From fd7d99810d653d4dab27648101be1ddff5ea9b92 Mon Sep 17 00:00:00 2001 From: Eric Paulsen Date: Sun, 21 Aug 2022 19:12:50 -0500 Subject: [PATCH 1/4] add: persistence & coder images --- .../kubernetes-multi-service/README.md | 4 + .../kubernetes-multi-service/main.tf | 88 ++++++++++++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/examples/templates/kubernetes-multi-service/README.md b/examples/templates/kubernetes-multi-service/README.md index 7c70d661f7258..0162498739269 100644 --- a/examples/templates/kubernetes-multi-service/README.md +++ b/examples/templates/kubernetes-multi-service/README.md @@ -72,3 +72,7 @@ roleRef: Then start the Coder host with `serviceAccountName: coder` in the pod spec. +## Persistence + +Each container in this Kubernetes pod example will have their `/home/coder` directory +persisted via the attached PersistentVolumeClaim. diff --git a/examples/templates/kubernetes-multi-service/main.tf b/examples/templates/kubernetes-multi-service/main.tf index 118c258bc21fa..adf67209b9cae 100644 --- a/examples/templates/kubernetes-multi-service/main.tf +++ b/examples/templates/kubernetes-multi-service/main.tf @@ -32,6 +32,12 @@ variable "workspaces_namespace" { default = "coder-workspaces" } +variable "disk_size" { + type = number + description = "Disk size (__ GB)" + default = 10 +} + provider "kubernetes" { # Authenticate via ~/.kube/config or a Coder-specific ServiceAccount, depending on admin preferences config_path = var.use_kubeconfig == true ? "~/.kube/config" : null @@ -63,7 +69,7 @@ resource "kubernetes_pod" "main" { spec { container { name = "go" - image = "mcr.microsoft.com/vscode/devcontainers/go:1" + image = "codercom/enterprise-golang:ubuntu" command = ["sh", "-c", coder_agent.go.init_script] security_context { run_as_user = "1000" @@ -72,10 +78,20 @@ resource "kubernetes_pod" "main" { name = "CODER_AGENT_TOKEN" value = coder_agent.go.token } + volume_mount { + mount_path = "/home/coder" + name = "go-home-directory" + } + } + volume { + name = "go-home-directory" + persistent_volume_claim { + claim_name = kubernetes_persistent_volume_claim.go-home-directory.metadata.0.name + } } container { name = "java" - image = "mcr.microsoft.com/vscode/devcontainers/java" + image = "codercom/enterprise-java:ubuntu" command = ["sh", "-c", coder_agent.java.init_script] security_context { run_as_user = "1000" @@ -84,10 +100,20 @@ resource "kubernetes_pod" "main" { name = "CODER_AGENT_TOKEN" value = coder_agent.java.token } + volume_mount { + mount_path = "/home/coder" + name = "java-home-directory" + } + } + volume { + name = "java-home-directory" + persistent_volume_claim { + claim_name = kubernetes_persistent_volume_claim.java-home-directory.metadata.0.name + } } container { name = "ubuntu" - image = "mcr.microsoft.com/vscode/devcontainers/base:ubuntu" + image = "codercom/enterprise-base:ubuntu" command = ["sh", "-c", coder_agent.ubuntu.init_script] security_context { run_as_user = "1000" @@ -96,6 +122,62 @@ resource "kubernetes_pod" "main" { name = "CODER_AGENT_TOKEN" value = coder_agent.ubuntu.token } + volume_mount { + mount_path = "/home/coder" + name = "ubuntu-home-directory" + } + } + volume { + name = "ubuntu-home-directory" + persistent_volume_claim { + claim_name = kubernetes_persistent_volume_claim.ubuntu-home-directory.metadata.0.name + } + } + + } +} + +resource "kubernetes_persistent_volume_claim" "go-home-directory" { + metadata { + name = "home-coder-go-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}" + namespace = var.workspaces_namespace + } + spec { + access_modes = ["ReadWriteOnce"] + resources { + requests = { + storage = "${var.disk_size}Gi" + } + } + } +} + +resource "kubernetes_persistent_volume_claim" "java-home-directory" { + metadata { + name = "home-coder-java-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}" + namespace = var.workspaces_namespace + } + spec { + access_modes = ["ReadWriteOnce"] + resources { + requests = { + storage = "${var.disk_size}Gi" + } + } + } +} + +resource "kubernetes_persistent_volume_claim" "ubuntu-home-directory" { + metadata { + name = "home-coder-ubuntu-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}" + namespace = var.workspaces_namespace + } + spec { + access_modes = ["ReadWriteOnce"] + resources { + requests = { + storage = "${var.disk_size}Gi" + } } } } From e7c0d547cb29fe725c710b0d745f2275a1c0d37e Mon Sep 17 00:00:00 2001 From: Eric Paulsen Date: Mon, 22 Aug 2022 17:08:56 -0500 Subject: [PATCH 2/4] add: code-server --- .../kubernetes-multi-service/README.md | 4 +- .../kubernetes-multi-service/main.tf | 117 ++++-------------- 2 files changed, 28 insertions(+), 93 deletions(-) diff --git a/examples/templates/kubernetes-multi-service/README.md b/examples/templates/kubernetes-multi-service/README.md index 0162498739269..c09e229a79007 100644 --- a/examples/templates/kubernetes-multi-service/README.md +++ b/examples/templates/kubernetes-multi-service/README.md @@ -74,5 +74,5 @@ Then start the Coder host with `serviceAccountName: coder` in the pod spec. ## Persistence -Each container in this Kubernetes pod example will have their `/home/coder` directory -persisted via the attached PersistentVolumeClaim. +The `/home/coder` directory in this example is persisted via the attached PersistentVolumeClaim. +Any data saved outside of this directory will be wiped when the workspace stops. diff --git a/examples/templates/kubernetes-multi-service/main.tf b/examples/templates/kubernetes-multi-service/main.tf index adf67209b9cae..d23d978b7d958 100644 --- a/examples/templates/kubernetes-multi-service/main.tf +++ b/examples/templates/kubernetes-multi-service/main.tf @@ -6,7 +6,7 @@ terraform { } kubernetes = { source = "hashicorp/kubernetes" - version = "~> 2.10" + version = "~> 2.12.1" } } } @@ -29,7 +29,7 @@ variable "workspaces_namespace" { type = string sensitive = true description = "The namespace to create workspaces in (must exist prior to creating workspaces)" - default = "coder-workspaces" + default = "coder-workspace" } variable "disk_size" { @@ -45,19 +45,25 @@ provider "kubernetes" { data "coder_workspace" "me" {} -resource "coder_agent" "go" { +resource "coder_agent" "main" { os = "linux" arch = "amd64" -} + startup_script = < Date: Mon, 22 Aug 2022 17:53:14 -0500 Subject: [PATCH 3/4] chore: README updates --- .../README.md | 11 +++++++++++ .../main.tf | 8 ++++---- 2 files changed, 15 insertions(+), 4 deletions(-) rename examples/templates/{kubernetes-multi-service => kubernetes-pod}/README.md (85%) rename examples/templates/{kubernetes-multi-service => kubernetes-pod}/main.tf (95%) diff --git a/examples/templates/kubernetes-multi-service/README.md b/examples/templates/kubernetes-pod/README.md similarity index 85% rename from examples/templates/kubernetes-multi-service/README.md rename to examples/templates/kubernetes-pod/README.md index c09e229a79007..3d8e96cbaa974 100644 --- a/examples/templates/kubernetes-multi-service/README.md +++ b/examples/templates/kubernetes-pod/README.md @@ -72,7 +72,18 @@ roleRef: Then start the Coder host with `serviceAccountName: coder` in the pod spec. +## Namespace + +The target namespace in which the pod will be deployed is defined via the `coder_workspace` +variable. The namespace must exist prior to creating workspaces. + ## Persistence The `/home/coder` directory in this example is persisted via the attached PersistentVolumeClaim. Any data saved outside of this directory will be wiped when the workspace stops. + +## code-server + +`code-server` is installed via the `startup_script` argument in the `coder_agent` +resource block. The `coder_app` resource is defined to access `code-server` through +the dashboard UI over `localhost:13337`. diff --git a/examples/templates/kubernetes-multi-service/main.tf b/examples/templates/kubernetes-pod/main.tf similarity index 95% rename from examples/templates/kubernetes-multi-service/main.tf rename to examples/templates/kubernetes-pod/main.tf index d23d978b7d958..2a28e607750c0 100644 --- a/examples/templates/kubernetes-multi-service/main.tf +++ b/examples/templates/kubernetes-pod/main.tf @@ -25,11 +25,11 @@ variable "use_kubeconfig" { EOF } -variable "workspaces_namespace" { +variable "coder_namespace" { type = string sensitive = true description = "The namespace to create workspaces in (must exist prior to creating workspaces)" - default = "coder-workspace" + default = "coder-namespace" } variable "disk_size" { @@ -70,7 +70,7 @@ resource "kubernetes_pod" "main" { count = data.coder_workspace.me.start_count metadata { name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}" - namespace = var.workspaces_namespace + namespace = var.coder_namespace } spec { security_context { @@ -105,7 +105,7 @@ resource "kubernetes_pod" "main" { resource "kubernetes_persistent_volume_claim" "home-directory" { metadata { name = "home-coder-java-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}" - namespace = var.workspaces_namespace + namespace = var.coder_namespace } spec { access_modes = ["ReadWriteOnce"] From 3805327156efc6573a75bb407cac263b7b721d47 Mon Sep 17 00:00:00 2001 From: Eric Paulsen Date: Wed, 24 Aug 2022 11:02:35 -0500 Subject: [PATCH 4/4] chore: README example --- examples/templates/kubernetes-pod/README.md | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/examples/templates/kubernetes-pod/README.md b/examples/templates/kubernetes-pod/README.md index 3d8e96cbaa974..fa4569846b79f 100644 --- a/examples/templates/kubernetes-pod/README.md +++ b/examples/templates/kubernetes-pod/README.md @@ -82,6 +82,28 @@ variable. The namespace must exist prior to creating workspaces. The `/home/coder` directory in this example is persisted via the attached PersistentVolumeClaim. Any data saved outside of this directory will be wiped when the workspace stops. +Since most binary installations and environment configurations live outside of +the `/home` directory, we suggest including these in the `startup_script` argument +of the `coder_agent` resource block, which will run each time the workspace starts up. + +For example, when installing the `aws` CLI, the install script will place the +`aws` binary in `/usr/local/bin/aws`. To ensure the `aws` CLI is persisted across +workspace starts/stops, include the following code in the `coder_agent` resource +block of your workspace template: + +```terraform +resource "coder_agent" "main" { + startup_script = <