Skip to content

Commit fdbdf20

Browse files
committed
add template
1 parent 3403530 commit fdbdf20

File tree

1 file changed

+346
-0
lines changed
  • .github/pr-deployments/kubernetes

1 file changed

+346
-0
lines changed
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "~> 0.11.0"
6+
}
7+
kubernetes = {
8+
source = "hashicorp/kubernetes"
9+
version = "~> 2.22"
10+
}
11+
}
12+
}
13+
14+
provider "coder" {
15+
}
16+
17+
variable "use_kubeconfig" {
18+
type = bool
19+
description = <<-EOF
20+
Use host kubeconfig? (true/false)
21+
22+
Set this to false if the Coder host is itself running as a Pod on the same
23+
Kubernetes cluster as you are deploying workspaces to.
24+
25+
Set this to true if the Coder host is running outside the Kubernetes cluster
26+
for workspaces. A valid "~/.kube/config" must be present on the Coder host.
27+
EOF
28+
default = false
29+
}
30+
31+
variable "namespace" {
32+
type = string
33+
description = "The Kubernetes namespace to create workspaces in (must exist prior to creating workspaces)"
34+
}
35+
36+
data "coder_parameter" "cpu" {
37+
name = "cpu"
38+
display_name = "CPU"
39+
description = "The number of CPU cores"
40+
default = "2"
41+
icon = "/icon/memory.svg"
42+
mutable = true
43+
option {
44+
name = "2 Cores"
45+
value = "2"
46+
}
47+
option {
48+
name = "4 Cores"
49+
value = "4"
50+
}
51+
option {
52+
name = "6 Cores"
53+
value = "6"
54+
}
55+
option {
56+
name = "8 Cores"
57+
value = "8"
58+
}
59+
}
60+
61+
data "coder_parameter" "memory" {
62+
name = "memory"
63+
display_name = "Memory"
64+
description = "The amount of memory in GB"
65+
default = "2"
66+
icon = "/icon/memory.svg"
67+
mutable = true
68+
option {
69+
name = "2 GB"
70+
value = "2"
71+
}
72+
option {
73+
name = "4 GB"
74+
value = "4"
75+
}
76+
option {
77+
name = "6 GB"
78+
value = "6"
79+
}
80+
option {
81+
name = "8 GB"
82+
value = "8"
83+
}
84+
}
85+
86+
data "coder_parameter" "home_disk_size" {
87+
name = "home_disk_size"
88+
display_name = "Home disk size"
89+
description = "The size of the home disk in GB"
90+
default = "10"
91+
type = "number"
92+
icon = "/emojis/1f4be.png"
93+
mutable = false
94+
validation {
95+
min = 1
96+
max = 99999
97+
}
98+
}
99+
100+
provider "kubernetes" {
101+
# Authenticate via ~/.kube/config or a Coder-specific ServiceAccount, depending on admin preferences
102+
config_path = var.use_kubeconfig == true ? "~/.kube/config" : null
103+
}
104+
105+
data "coder_workspace" "me" {}
106+
107+
resource "coder_agent" "main" {
108+
os = "linux"
109+
arch = "amd64"
110+
startup_script_timeout = 180
111+
startup_script = <<-EOT
112+
set -e
113+
114+
# install and start code-server
115+
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
116+
117+
# Set KUBECONFIG env var to the path of the mounted secret
118+
mkdir -p /home/coder/.kube
119+
sudo cp /tmp/config /home/coder/.kube/config
120+
export KUBECONFIG=/home/coder/.kube/config
121+
122+
EOT
123+
124+
# The following metadata blocks are optional. They are used to display
125+
# information about your workspace in the dashboard. You can remove them
126+
# if you don't want to display any information.
127+
# For basic resources, you can use the `coder stat` command.
128+
# If you need more control, you can write your own script.
129+
metadata {
130+
display_name = "CPU Usage"
131+
key = "0_cpu_usage"
132+
script = "coder stat cpu"
133+
interval = 10
134+
timeout = 1
135+
}
136+
137+
metadata {
138+
display_name = "RAM Usage"
139+
key = "1_ram_usage"
140+
script = "coder stat mem"
141+
interval = 10
142+
timeout = 1
143+
}
144+
145+
metadata {
146+
display_name = "Home Disk"
147+
key = "3_home_disk"
148+
script = "coder stat disk --path $${HOME}"
149+
interval = 60
150+
timeout = 1
151+
}
152+
153+
metadata {
154+
display_name = "CPU Usage (Host)"
155+
key = "4_cpu_usage_host"
156+
script = "coder stat cpu --host"
157+
interval = 10
158+
timeout = 1
159+
}
160+
161+
metadata {
162+
display_name = "Memory Usage (Host)"
163+
key = "5_mem_usage_host"
164+
script = "coder stat mem --host"
165+
interval = 10
166+
timeout = 1
167+
}
168+
169+
metadata {
170+
display_name = "Load Average (Host)"
171+
key = "6_load_host"
172+
# get load avg scaled by number of cores
173+
script = <<EOT
174+
echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
175+
EOT
176+
interval = 60
177+
timeout = 1
178+
}
179+
}
180+
181+
# code-server
182+
resource "coder_app" "code-server" {
183+
agent_id = coder_agent.main.id
184+
slug = "code-server"
185+
display_name = "code-server"
186+
icon = "/icon/code.svg"
187+
url = "http://localhost:13337?folder=/home/coder"
188+
subdomain = false
189+
share = "owner"
190+
191+
healthcheck {
192+
url = "http://localhost:13337/healthz"
193+
interval = 3
194+
threshold = 10
195+
}
196+
}
197+
198+
resource "kubernetes_persistent_volume_claim" "home" {
199+
metadata {
200+
name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}-home"
201+
namespace = var.namespace
202+
labels = {
203+
"app.kubernetes.io/name" = "coder-pvc"
204+
"app.kubernetes.io/instance" = "coder-pvc-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
205+
"app.kubernetes.io/part-of" = "coder"
206+
//Coder-specific labels.
207+
"com.coder.resource" = "true"
208+
"com.coder.workspace.id" = data.coder_workspace.me.id
209+
"com.coder.workspace.name" = data.coder_workspace.me.name
210+
"com.coder.user.id" = data.coder_workspace.me.owner_id
211+
"com.coder.user.username" = data.coder_workspace.me.owner
212+
}
213+
annotations = {
214+
"com.coder.user.email" = data.coder_workspace.me.owner_email
215+
}
216+
}
217+
wait_until_bound = false
218+
spec {
219+
access_modes = ["ReadWriteOnce"]
220+
resources {
221+
requests = {
222+
storage = "${data.coder_parameter.home_disk_size.value}Gi"
223+
}
224+
}
225+
}
226+
}
227+
228+
resource "kubernetes_deployment" "main" {
229+
count = data.coder_workspace.me.start_count
230+
depends_on = [
231+
kubernetes_persistent_volume_claim.home
232+
]
233+
wait_for_rollout = false
234+
metadata {
235+
name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
236+
namespace = var.namespace
237+
labels = {
238+
"app.kubernetes.io/name" = "coder-workspace"
239+
"app.kubernetes.io/instance" = "coder-workspace-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
240+
"app.kubernetes.io/part-of" = "coder"
241+
"com.coder.resource" = "true"
242+
"com.coder.workspace.id" = data.coder_workspace.me.id
243+
"com.coder.workspace.name" = data.coder_workspace.me.name
244+
"com.coder.user.id" = data.coder_workspace.me.owner_id
245+
"com.coder.user.username" = data.coder_workspace.me.owner
246+
}
247+
annotations = {
248+
"com.coder.user.email" = data.coder_workspace.me.owner_email
249+
}
250+
}
251+
252+
spec {
253+
# replicas = data.coder_workspace.me.start_count
254+
replicas = 1
255+
selector {
256+
match_labels = {
257+
"app.kubernetes.io/name" = "coder-workspace"
258+
}
259+
}
260+
261+
template {
262+
metadata {
263+
labels = {
264+
"app.kubernetes.io/name" = "coder-workspace"
265+
}
266+
}
267+
spec {
268+
security_context {
269+
run_as_user = 1000
270+
fs_group = 1000
271+
}
272+
273+
container {
274+
name = "dev"
275+
image = "bencdr/devops-tools"
276+
image_pull_policy = "Always"
277+
command = ["sh", "-c", coder_agent.main.init_script]
278+
security_context {
279+
run_as_user = "1000"
280+
}
281+
env {
282+
name = "CODER_AGENT_TOKEN"
283+
value = coder_agent.main.token
284+
}
285+
resources {
286+
requests = {
287+
"cpu" = "250m"
288+
"memory" = "512Mi"
289+
}
290+
limits = {
291+
"cpu" = "${data.coder_parameter.cpu.value}"
292+
"memory" = "${data.coder_parameter.memory.value}Gi"
293+
}
294+
}
295+
volume_mount {
296+
mount_path = "/home/coder"
297+
name = "home"
298+
read_only = false
299+
}
300+
volume_mount {
301+
mount_path = "/tmp/config"
302+
sub_path = "kubeconfig"
303+
name = "kubeconfig"
304+
read_only = true
305+
}
306+
}
307+
308+
volume {
309+
name = "home"
310+
persistent_volume_claim {
311+
claim_name = kubernetes_persistent_volume_claim.home.metadata.0.name
312+
read_only = false
313+
}
314+
}
315+
316+
# mount kubeconfig secret as a volume to /home/coder/.kube/config
317+
volume {
318+
name = "kubeconfig"
319+
secret {
320+
secret_name = "coder-namespace-kubeconfig"
321+
}
322+
}
323+
324+
affinity {
325+
// This affinity attempts to spread out all workspace pods evenly across
326+
// nodes.
327+
pod_anti_affinity {
328+
preferred_during_scheduling_ignored_during_execution {
329+
weight = 1
330+
pod_affinity_term {
331+
topology_key = "kubernetes.io/hostname"
332+
label_selector {
333+
match_expressions {
334+
key = "app.kubernetes.io/name"
335+
operator = "In"
336+
values = ["coder-workspace"]
337+
}
338+
}
339+
}
340+
}
341+
}
342+
}
343+
}
344+
}
345+
}
346+
}

0 commit comments

Comments
 (0)