TemplatesModules
Back to Templates
Nomad Icon

Nomad

By:
Provision Nomad Jobs as Coder workspaces
Source
README
Resources (3)
Variables (2)

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    nomad = {
7      source = "hashicorp/nomad"
8    }
9  }
10}
11
12variable "nomad_provider_address" {
13  type        = string
14  description = "Nomad provider address. e.g., http://IP:PORT"
15  default     = "http://localhost:4646"
16}
17
18variable "nomad_provider_http_auth" {
19  type        = string
20  description = "Nomad provider http_auth in the form of `user:password`"
21  sensitive   = true
22  default     = ""
23}
24
25provider "coder" {}
26
27provider "nomad" {
28  address   = var.nomad_provider_address
29  http_auth = var.nomad_provider_http_auth == "" ? null : var.nomad_provider_http_auth
30
31  # Fix reading the NOMAD_NAMESPACE and the NOMAD_REGION env var from the coder's allocation.
32  ignore_env_vars = {
33    "NOMAD_NAMESPACE" = true
34    "NOMAD_REGION"    = true
35  }
36}
37
38data "coder_parameter" "cpu" {
39  name         = "cpu"
40  display_name = "CPU"
41  description  = "The number of CPU cores"
42  default      = "1"
43  icon         = "/icon/memory.svg"
44  mutable      = true
45  option {
46    name  = "1 Cores"
47    value = "1"
48  }
49  option {
50    name  = "2 Cores"
51    value = "2"
52  }
53  option {
54    name  = "3 Cores"
55    value = "3"
56  }
57  option {
58    name  = "4 Cores"
59    value = "4"
60  }
61}
62
63data "coder_parameter" "memory" {
64  name         = "memory"
65  display_name = "Memory"
66  description  = "The amount of memory in GB"
67  default      = "2"
68  icon         = "/icon/memory.svg"
69  mutable      = true
70  option {
71    name  = "2 GB"
72    value = "2"
73  }
74  option {
75    name  = "4 GB"
76    value = "4"
77  }
78  option {
79    name  = "6 GB"
80    value = "6"
81  }
82  option {
83    name  = "8 GB"
84    value = "8"
85  }
86}
87
88data "coder_workspace" "me" {}
89data "coder_workspace_owner" "me" {}
90
91resource "coder_agent" "main" {
92  os             = "linux"
93  arch           = "amd64"
94  startup_script = <<-EOT
95    set -e
96    # install and start code-server
97    curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server
98    /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
99  EOT
100
101  metadata {
102    display_name = "Load Average (Host)"
103    key          = "load_host"
104    # get load avg scaled by number of cores
105    script   = <<EOT
106      echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
107    EOT
108    interval = 60
109    timeout  = 1
110  }
111}
112
113# code-server
114resource "coder_app" "code-server" {
115  agent_id     = coder_agent.main.id
116  slug         = "code-server"
117  display_name = "code-server"
118  icon         = "/icon/code.svg"
119  url          = "http://localhost:13337?folder=/home/coder"
120  subdomain    = false
121  share        = "owner"
122
123  healthcheck {
124    url       = "http://localhost:13337/healthz"
125    interval  = 3
126    threshold = 10
127  }
128}
129
130locals {
131  workspace_tag    = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
132  home_volume_name = "coder_${data.coder_workspace.me.id}_home"
133}
134
135resource "nomad_namespace" "coder_workspace" {
136  name        = local.workspace_tag
137  description = "Coder workspace"
138  meta = {
139    owner = data.coder_workspace_owner.me.name
140  }
141}
142
143data "nomad_plugin" "hostpath" {
144  plugin_id        = "hostpath"
145  wait_for_healthy = true
146}
147
148resource "nomad_csi_volume" "home_volume" {
149  depends_on = [data.nomad_plugin.hostpath]
150
151  lifecycle {
152    ignore_changes = all
153  }
154  plugin_id = "hostpath"
155  volume_id = local.home_volume_name
156  name      = local.home_volume_name
157  namespace = nomad_namespace.coder_workspace.name
158
159  capability {
160    access_mode     = "single-node-writer"
161    attachment_mode = "file-system"
162  }
163
164  mount_options {
165    fs_type = "ext4"
166  }
167}
168
169resource "nomad_job" "workspace" {
170  count      = data.coder_workspace.me.start_count
171  depends_on = [nomad_csi_volume.home_volume]
172  jobspec = templatefile("${path.module}/workspace.nomad.tpl", {
173    coder_workspace_owner = data.coder_workspace_owner.me.name
174    coder_workspace_name  = data.coder_workspace.me.name
175    workspace_tag         = local.workspace_tag
176    cores                 = tonumber(data.coder_parameter.cpu.value)
177    memory_mb             = tonumber(data.coder_parameter.memory.value * 1024)
178    coder_init_script     = coder_agent.main.init_script
179    coder_agent_token     = coder_agent.main.token
180    workspace_name        = data.coder_workspace.me.name
181    home_volume_name      = local.home_volume_name
182  })
183  deregister_on_destroy = true
184  purge_on_destroy      = true
185}
186
187resource "coder_metadata" "workspace_info" {
188  count       = data.coder_workspace.me.start_count
189  resource_id = nomad_job.workspace[0].id
190  item {
191    key   = "CPU (Cores)"
192    value = data.coder_parameter.cpu.value
193  }
194  item {
195    key   = "Memory (GiB)"
196    value = data.coder_parameter.memory.value
197  }
198}
199