TemplatesModules
Back to Templates
Envbox (Kubernetes) Icon

Envbox (Kubernetes)

By:
Provision envbox pods as Coder workspaces
Source
README
Resources (2)
Variables (8)

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    kubernetes = {
7      source = "hashicorp/kubernetes"
8    }
9  }
10}
11
12data "coder_parameter" "home_disk" {
13  name        = "Disk Size"
14  description = "How large should the disk storing the home directory be?"
15  icon        = "https://cdn-icons-png.flaticon.com/512/2344/2344147.png"
16  type        = "number"
17  default     = 10
18  mutable     = true
19  validation {
20    min = 10
21    max = 100
22  }
23}
24
25variable "use_kubeconfig" {
26  type        = bool
27  sensitive   = true
28  default     = true
29  description = <<-EOF
30  Use host kubeconfig? (true/false)
31  Set this to false if the Coder host is itself running as a Pod on the same
32  Kubernetes cluster as you are deploying workspaces to.
33  Set this to true if the Coder host is running outside the Kubernetes cluster
34  for workspaces.  A valid "~/.kube/config" must be present on the Coder host.
35  EOF
36}
37
38provider "coder" {
39}
40
41variable "namespace" {
42  type        = string
43  sensitive   = true
44  description = "The namespace to create workspaces in (must exist prior to creating workspaces)"
45}
46
47variable "create_tun" {
48  type        = bool
49  sensitive   = true
50  description = "Add a TUN device to the workspace."
51  default     = false
52}
53
54variable "create_fuse" {
55  type        = bool
56  description = "Add a FUSE device to the workspace."
57  sensitive   = true
58  default     = false
59}
60
61variable "max_cpus" {
62  type        = string
63  sensitive   = true
64  description = "Max number of CPUs the workspace may use (e.g. 2)."
65}
66
67variable "min_cpus" {
68  type        = string
69  sensitive   = true
70  description = "Minimum number of CPUs the workspace may use (e.g. .1)."
71}
72
73variable "max_memory" {
74  type        = string
75  description = "Maximum amount of memory to allocate the workspace (in GB)."
76  sensitive   = true
77}
78
79variable "min_memory" {
80  type        = string
81  description = "Minimum amount of memory to allocate the workspace (in GB)."
82  sensitive   = true
83}
84
85provider "kubernetes" {
86  # Authenticate via ~/.kube/config or a Coder-specific ServiceAccount, depending on admin preferences
87  config_path = var.use_kubeconfig == true ? "~/.kube/config" : null
88}
89
90data "coder_workspace" "me" {}
91
92resource "coder_agent" "main" {
93  os             = "linux"
94  arch           = "amd64"
95  startup_script = <<EOT
96    #!/bin/bash
97    # home folder can be empty, so copying default bash settings
98    if [ ! -f ~/.profile ]; then
99      cp /etc/skel/.profile $HOME
100    fi
101    if [ ! -f ~/.bashrc ]; then
102      cp /etc/skel/.bashrc $HOME
103    fi
104    # install and start code-server
105    curl -fsSL https://code-server.dev/install.sh | sh -s -- --version 4.8.3 | tee code-server-install.log
106    code-server --auth none --port 13337 | tee code-server-install.log &
107  EOT
108}
109
110# code-server
111resource "coder_app" "code-server" {
112  agent_id     = coder_agent.main.id
113  slug         = "code-server"
114  display_name = "code-server"
115  icon         = "/icon/code.svg"
116  url          = "http://localhost:13337?folder=/home/coder"
117  subdomain    = false
118  share        = "owner"
119
120  healthcheck {
121    url       = "http://localhost:13337/healthz"
122    interval  = 3
123    threshold = 10
124  }
125}
126
127resource "kubernetes_persistent_volume_claim" "home" {
128  metadata {
129    name      = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}-home"
130    namespace = var.namespace
131  }
132  wait_until_bound = false
133  spec {
134    access_modes = ["ReadWriteOnce"]
135    resources {
136      requests = {
137        storage = "${data.coder_parameter.home_disk.value}Gi"
138      }
139    }
140  }
141}
142
143resource "kubernetes_pod" "main" {
144  count = data.coder_workspace.me.start_count
145
146  metadata {
147    name      = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
148    namespace = var.namespace
149  }
150
151  spec {
152    restart_policy = "Never"
153
154    container {
155      name              = "dev"
156      image             = "ghcr.io/coder/envbox:latest"
157      image_pull_policy = "Always"
158      command           = ["/envbox", "docker"]
159
160      security_context {
161        privileged = true
162      }
163
164      resources {
165        requests = {
166          "cpu" : "${var.min_cpus}"
167          "memory" : "${var.min_memory}G"
168        }
169
170        limits = {
171          "cpu" : "${var.max_cpus}"
172          "memory" : "${var.max_memory}G"
173        }
174      }
175
176      env {
177        name  = "CODER_AGENT_TOKEN"
178        value = coder_agent.main.token
179      }
180
181      env {
182        name  = "CODER_AGENT_URL"
183        value = data.coder_workspace.me.access_url
184      }
185
186      env {
187        name  = "CODER_INNER_IMAGE"
188        value = "index.docker.io/codercom/enterprise-base@sha256:069e84783d134841cbb5007a16d9025b6aed67bc5b95eecc118eb96dccd6de68"
189      }
190
191      env {
192        name  = "CODER_INNER_USERNAME"
193        value = "coder"
194      }
195
196      env {
197        name  = "CODER_BOOTSTRAP_SCRIPT"
198        value = coder_agent.main.init_script
199      }
200
201      env {
202        name  = "CODER_MOUNTS"
203        value = "/home/coder:/home/coder"
204      }
205
206      env {
207        name  = "CODER_ADD_FUSE"
208        value = var.create_fuse
209      }
210
211      env {
212        name  = "CODER_INNER_HOSTNAME"
213        value = data.coder_workspace.me.name
214      }
215
216      env {
217        name  = "CODER_ADD_TUN"
218        value = var.create_tun
219      }
220
221      env {
222        name = "CODER_CPUS"
223        value_from {
224          resource_field_ref {
225            resource = "limits.cpu"
226          }
227        }
228      }
229
230      env {
231        name = "CODER_MEMORY"
232        value_from {
233          resource_field_ref {
234            resource = "limits.memory"
235          }
236        }
237      }
238
239      volume_mount {
240        mount_path = "/home/coder"
241        name       = "home"
242        read_only  = false
243        sub_path   = "home"
244      }
245
246      volume_mount {
247        mount_path = "/var/lib/coder/docker"
248        name       = "home"
249        sub_path   = "cache/docker"
250      }
251
252      volume_mount {
253        mount_path = "/var/lib/coder/containers"
254        name       = "home"
255        sub_path   = "cache/containers"
256      }
257
258      volume_mount {
259        mount_path = "/var/lib/sysbox"
260        name       = "sysbox"
261      }
262
263      volume_mount {
264        mount_path = "/var/lib/containers"
265        name       = "home"
266        sub_path   = "envbox/containers"
267      }
268
269      volume_mount {
270        mount_path = "/var/lib/docker"
271        name       = "home"
272        sub_path   = "envbox/docker"
273      }
274
275      volume_mount {
276        mount_path = "/usr/src"
277        name       = "usr-src"
278      }
279
280      volume_mount {
281        mount_path = "/lib/modules"
282        name       = "lib-modules"
283      }
284    }
285
286    volume {
287      name = "home"
288      persistent_volume_claim {
289        claim_name = kubernetes_persistent_volume_claim.home.metadata.0.name
290        read_only  = false
291      }
292    }
293
294    volume {
295      name = "sysbox"
296      empty_dir {}
297    }
298
299    volume {
300      name = "usr-src"
301      host_path {
302        path = "/usr/src"
303        type = ""
304      }
305    }
306
307    volume {
308      name = "lib-modules"
309      host_path {
310        path = "/lib/modules"
311        type = ""
312      }
313    }
314  }
315}
316