Copy and paste the following into main.tf
and run coder template push
:
1terraform {
2 required_providers {
3 coder = {
4 source = "coder/coder"
5 }
6 docker = {
7 source = "kreuzwerker/docker"
8 }
9 }
10}
11
12locals {
13 username = data.coder_workspace_owner.me.name
14}
15
16data "coder_provisioner" "me" {
17}
18
19provider "docker" {
20}
21
22data "coder_workspace" "me" {
23}
24data "coder_workspace_owner" "me" {}
25
26resource "coder_agent" "main" {
27 arch = data.coder_provisioner.me.arch
28 os = "linux"
29 startup_script = <<-EOT
30 set -e
31
32 # Prepare user home with default files on first start.
33 if [ ! -f ~/.init_done ]; then
34 cp -rT /etc/skel ~
35 touch ~/.init_done
36 fi
37
38 # install and start code-server
39 curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.19.1
40 /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
41 EOT
42
43 # These environment variables allow you to make Git commits right away after creating a
44 # workspace. Note that they take precedence over configuration defined in ~/.gitconfig!
45 # You can remove this block if you'd prefer to configure Git manually or using
46 # dotfiles. (see docs/dotfiles.md)
47 env = {
48 GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
49 GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}"
50 GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
51 GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}"
52 }
53
54 # The following metadata blocks are optional. They are used to display
55 # information about your workspace in the dashboard. You can remove them
56 # if you don't want to display any information.
57 # For basic resources, you can use the `coder stat` command.
58 # If you need more control, you can write your own script.
59 metadata {
60 display_name = "CPU Usage"
61 key = "0_cpu_usage"
62 script = "coder stat cpu"
63 interval = 10
64 timeout = 1
65 }
66
67 metadata {
68 display_name = "RAM Usage"
69 key = "1_ram_usage"
70 script = "coder stat mem"
71 interval = 10
72 timeout = 1
73 }
74
75 metadata {
76 display_name = "Home Disk"
77 key = "3_home_disk"
78 script = "coder stat disk --path $${HOME}"
79 interval = 60
80 timeout = 1
81 }
82
83 metadata {
84 display_name = "CPU Usage (Host)"
85 key = "4_cpu_usage_host"
86 script = "coder stat cpu --host"
87 interval = 10
88 timeout = 1
89 }
90
91 metadata {
92 display_name = "Memory Usage (Host)"
93 key = "5_mem_usage_host"
94 script = "coder stat mem --host"
95 interval = 10
96 timeout = 1
97 }
98
99 metadata {
100 display_name = "Load Average (Host)"
101 key = "6_load_host"
102 # get load avg scaled by number of cores
103 script = <<EOT
104 echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
105 EOT
106 interval = 60
107 timeout = 1
108 }
109
110 metadata {
111 display_name = "Swap Usage (Host)"
112 key = "7_swap_host"
113 script = <<EOT
114 free -b | awk '/^Swap/ { printf("%.1f/%.1f", $3/1024.0/1024.0/1024.0, $2/1024.0/1024.0/1024.0) }'
115 EOT
116 interval = 10
117 timeout = 1
118 }
119}
120
121resource "coder_app" "code-server" {
122 agent_id = coder_agent.main.id
123 slug = "code-server"
124 display_name = "code-server"
125 url = "http://localhost:13337/?folder=/home/${local.username}"
126 icon = "/icon/code.svg"
127 subdomain = false
128 share = "owner"
129
130 healthcheck {
131 url = "http://localhost:13337/healthz"
132 interval = 5
133 threshold = 6
134 }
135}
136
137resource "docker_volume" "home_volume" {
138 name = "coder-${data.coder_workspace.me.id}-home"
139 # Protect the volume from being deleted due to changes in attributes.
140 lifecycle {
141 ignore_changes = all
142 }
143 # Add labels in Docker to keep track of orphan resources.
144 labels {
145 label = "coder.owner"
146 value = data.coder_workspace_owner.me.name
147 }
148 labels {
149 label = "coder.owner_id"
150 value = data.coder_workspace_owner.me.id
151 }
152 labels {
153 label = "coder.workspace_id"
154 value = data.coder_workspace.me.id
155 }
156 # This field becomes outdated if the workspace is renamed but can
157 # be useful for debugging or cleaning out dangling volumes.
158 labels {
159 label = "coder.workspace_name_at_creation"
160 value = data.coder_workspace.me.name
161 }
162}
163
164resource "docker_image" "main" {
165 name = "coder-${data.coder_workspace.me.id}"
166 build {
167 context = "./build"
168 build_args = {
169 USER = local.username
170 }
171 }
172 triggers = {
173 dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
174 }
175}
176
177resource "docker_container" "workspace" {
178 count = data.coder_workspace.me.start_count
179 image = docker_image.main.name
180 # Uses lower() to avoid Docker restriction on container names.
181 name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
182 # Hostname makes the shell more user friendly: coder@my-workspace:~$
183 hostname = data.coder_workspace.me.name
184 # Use the docker gateway if the access URL is 127.0.0.1
185 entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
186 env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
187 host {
188 host = "host.docker.internal"
189 ip = "host-gateway"
190 }
191 volumes {
192 container_path = "/home/${local.username}"
193 volume_name = docker_volume.home_volume.name
194 read_only = false
195 }
196
197 # Add labels in Docker to keep track of orphan resources.
198 labels {
199 label = "coder.owner"
200 value = data.coder_workspace_owner.me.name
201 }
202 labels {
203 label = "coder.owner_id"
204 value = data.coder_workspace_owner.me.id
205 }
206 labels {
207 label = "coder.workspace_id"
208 value = data.coder_workspace.me.id
209 }
210 labels {
211 label = "coder.workspace_name"
212 value = data.coder_workspace.me.name
213 }
214}
215