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
12data "coder_provisioner" "me" {
13}
14
15provider "docker" {
16}
17
18data "coder_workspace" "me" {
19}
20
21resource "coder_agent" "main" {
22 arch = data.coder_provisioner.me.arch
23 os = "linux"
24 startup_script = <<-EOT
25 set -e
26
27 # install and start code-server
28 curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
29 /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
30 EOT
31 dir = "/workspaces"
32
33 # These environment variables allow you to make Git commits right away after creating a
34 # workspace. Note that they take precedence over configuration defined in ~/.gitconfig!
35 # You can remove this block if you'd prefer to configure Git manually or using
36 # dotfiles. (see docs/dotfiles.md)
37 env = {
38 GIT_AUTHOR_NAME = coalesce(data.coder_workspace.me.owner_name, data.coder_workspace.me.owner)
39 GIT_AUTHOR_EMAIL = "${data.coder_workspace.me.owner_email}"
40 GIT_COMMITTER_NAME = coalesce(data.coder_workspace.me.owner_name, data.coder_workspace.me.owner)
41 GIT_COMMITTER_EMAIL = "${data.coder_workspace.me.owner_email}"
42 }
43
44 # The following metadata blocks are optional. They are used to display
45 # information about your workspace in the dashboard. You can remove them
46 # if you don't want to display any information.
47 # For basic resources, you can use the `coder stat` command.
48 # If you need more control, you can write your own script.
49 metadata {
50 display_name = "CPU Usage"
51 key = "0_cpu_usage"
52 script = "coder stat cpu"
53 interval = 10
54 timeout = 1
55 }
56
57 metadata {
58 display_name = "RAM Usage"
59 key = "1_ram_usage"
60 script = "coder stat mem"
61 interval = 10
62 timeout = 1
63 }
64
65 metadata {
66 display_name = "Home Disk"
67 key = "3_home_disk"
68 script = "coder stat disk --path $HOME"
69 interval = 60
70 timeout = 1
71 }
72
73 metadata {
74 display_name = "CPU Usage (Host)"
75 key = "4_cpu_usage_host"
76 script = "coder stat cpu --host"
77 interval = 10
78 timeout = 1
79 }
80
81 metadata {
82 display_name = "Memory Usage (Host)"
83 key = "5_mem_usage_host"
84 script = "coder stat mem --host"
85 interval = 10
86 timeout = 1
87 }
88
89 metadata {
90 display_name = "Load Average (Host)"
91 key = "6_load_host"
92 # get load avg scaled by number of cores
93 script = <<EOT
94 echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
95 EOT
96 interval = 60
97 timeout = 1
98 }
99
100 metadata {
101 display_name = "Swap Usage (Host)"
102 key = "7_swap_host"
103 script = <<EOT
104 free -b | awk '/^Swap/ { printf("%.1f/%.1f", $3/1024.0/1024.0/1024.0, $2/1024.0/1024.0/1024.0) }'
105 EOT
106 interval = 10
107 timeout = 1
108 }
109}
110
111resource "coder_app" "code-server" {
112 agent_id = coder_agent.main.id
113 slug = "code-server"
114 display_name = "code-server"
115 url = "http://localhost:13337/?folder=/workspaces"
116 icon = "/icon/code.svg"
117 subdomain = false
118 share = "owner"
119
120 healthcheck {
121 url = "http://localhost:13337/healthz"
122 interval = 5
123 threshold = 6
124 }
125}
126
127
128resource "docker_volume" "workspaces" {
129 name = "coder-${data.coder_workspace.me.id}"
130 # Protect the volume from being deleted due to changes in attributes.
131 lifecycle {
132 ignore_changes = all
133 }
134 # Add labels in Docker to keep track of orphan resources.
135 labels {
136 label = "coder.owner"
137 value = data.coder_workspace.me.owner
138 }
139 labels {
140 label = "coder.owner_id"
141 value = data.coder_workspace.me.owner_id
142 }
143 labels {
144 label = "coder.workspace_id"
145 value = data.coder_workspace.me.id
146 }
147 # This field becomes outdated if the workspace is renamed but can
148 # be useful for debugging or cleaning out dangling volumes.
149 labels {
150 label = "coder.workspace_name_at_creation"
151 value = data.coder_workspace.me.name
152 }
153}
154
155data "coder_parameter" "repo" {
156 name = "repo"
157 display_name = "Repository (auto)"
158 order = 1
159 description = "Select a repository to automatically clone and start working with a devcontainer."
160 mutable = true
161 option {
162 name = "vercel/next.js"
163 description = "The React Framework"
164 value = "https://github.com/vercel/next.js"
165 }
166 option {
167 name = "home-assistant/core"
168 description = "🏡 Open source home automation that puts local control and privacy first."
169 value = "https://github.com/home-assistant/core"
170 }
171 option {
172 name = "discourse/discourse"
173 description = "A platform for community discussion. Free, open, simple."
174 value = "https://github.com/discourse/discourse"
175 }
176 option {
177 name = "denoland/deno"
178 description = "A modern runtime for JavaScript and TypeScript."
179 value = "https://github.com/denoland/deno"
180 }
181 option {
182 name = "microsoft/vscode"
183 icon = "/icon/code.svg"
184 description = "Code editing. Redefined."
185 value = "https://github.com/microsoft/vscode"
186 }
187 option {
188 name = "Custom"
189 icon = "/emojis/1f5c3.png"
190 description = "Specify a custom repo URL below"
191 value = "custom"
192 }
193}
194
195data "coder_parameter" "custom_repo_url" {
196 name = "custom_repo"
197 display_name = "Repository URL (custom)"
198 order = 2
199 default = ""
200 description = "Optionally enter a custom repository URL, see [awesome-devcontainers](https://github.com/manekinekko/awesome-devcontainers)."
201 mutable = true
202}
203
204resource "docker_container" "workspace" {
205 count = data.coder_workspace.me.start_count
206 # Find the latest version here:
207 # https://github.com/coder/envbuilder/tags
208 image = "ghcr.io/coder/envbuilder:0.2.1"
209 # Uses lower() to avoid Docker restriction on container names.
210 name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
211 # Hostname makes the shell more user friendly: coder@my-workspace:~$
212 hostname = data.coder_workspace.me.name
213 # Use the docker gateway if the access URL is 127.0.0.1
214 env = [
215 "CODER_AGENT_TOKEN=${coder_agent.main.token}",
216 "CODER_AGENT_URL=${replace(data.coder_workspace.me.access_url, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")}",
217 "GIT_URL=${data.coder_parameter.repo.value == "custom" ? data.coder_parameter.custom_repo_url.value : data.coder_parameter.repo.value}",
218 "INIT_SCRIPT=${replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")}",
219 "FALLBACK_IMAGE=codercom/enterprise-base:ubuntu" # This image runs if builds fail
220 ]
221 host {
222 host = "host.docker.internal"
223 ip = "host-gateway"
224 }
225 volumes {
226 container_path = "/workspaces"
227 volume_name = docker_volume.workspaces.name
228 read_only = false
229 }
230 # Add labels in Docker to keep track of orphan resources.
231 labels {
232 label = "coder.owner"
233 value = data.coder_workspace.me.owner
234 }
235 labels {
236 label = "coder.owner_id"
237 value = data.coder_workspace.me.owner_id
238 }
239 labels {
240 label = "coder.workspace_id"
241 value = data.coder_workspace.me.id
242 }
243 labels {
244 label = "coder.workspace_name"
245 value = data.coder_workspace.me.name
246 }
247}
248