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" {}
89
90resource "coder_agent" "main" {
91  os             = "linux"
92  arch           = "amd64"
93  startup_script = <<-EOT
94    set -e
95    # install and start code-server
96    curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server
97    /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
98  EOT
99
100  metadata {
101    display_name = "Load Average (Host)"
102    key          = "load_host"
103    # get load avg scaled by number of cores
104    script   = <<EOT
105      echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
106    EOT
107    interval = 60
108    timeout  = 1
109  }
110}
111
112# code-server
113resource "coder_app" "code-server" {
114  agent_id     = coder_agent.main.id
115  slug         = "code-server"
116  display_name = "code-server"
117  icon         = "/icon/code.svg"
118  url          = "http://localhost:13337?folder=/home/coder"
119  subdomain    = false
120  share        = "owner"
121
122  healthcheck {
123    url       = "http://localhost:13337/healthz"
124    interval  = 3
125    threshold = 10
126  }
127}
128
129locals {
130  workspace_tag    = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
131  home_volume_name = "coder_${data.coder_workspace.me.id}_home"
132}
133
134resource "nomad_namespace" "coder_workspace" {
135  name        = local.workspace_tag
136  description = "Coder workspace"
137  meta = {
138    owner = data.coder_workspace.me.owner
139  }
140}
141
142data "nomad_plugin" "hostpath" {
143  plugin_id        = "hostpath"
144  wait_for_healthy = true
145}
146
147resource "nomad_csi_volume" "home_volume" {
148  depends_on = [data.nomad_plugin.hostpath]
149
150  lifecycle {
151    ignore_changes = all
152  }
153  plugin_id = "hostpath"
154  volume_id = local.home_volume_name
155  name      = local.home_volume_name
156  namespace = nomad_namespace.coder_workspace.name
157
158  capability {
159    access_mode     = "single-node-writer"
160    attachment_mode = "file-system"
161  }
162
163  mount_options {
164    fs_type = "ext4"
165  }
166}
167
168resource "nomad_job" "workspace" {
169  count      = data.coder_workspace.me.start_count
170  depends_on = [nomad_csi_volume.home_volume]
171  jobspec = templatefile("${path.module}/workspace.nomad.tpl", {
172    coder_workspace_owner = data.coder_workspace.me.owner
173    coder_workspace_name  = data.coder_workspace.me.name
174    workspace_tag         = local.workspace_tag
175    cores                 = tonumber(data.coder_parameter.cpu.value)
176    memory_mb             = tonumber(data.coder_parameter.memory.value * 1024)
177    coder_init_script     = coder_agent.main.init_script
178    coder_agent_token     = coder_agent.main.token
179    workspace_name        = data.coder_workspace.me.name
180    home_volume_name      = local.home_volume_name
181  })
182  deregister_on_destroy = true
183  purge_on_destroy      = true
184}
185
186resource "coder_metadata" "workspace_info" {
187  count       = data.coder_workspace.me.start_count
188  resource_id = nomad_job.workspace[0].id
189  item {
190    key   = "CPU (Cores)"
191    value = data.coder_parameter.cpu.value
192  }
193  item {
194    key   = "Memory (GiB)"
195    value = data.coder_parameter.memory.value
196  }
197}
198