Skip to content

ci: upgrade pr deployments workflow #8924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 75 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
2d92a15
create-pr
matifali Aug 6, 2023
3ffb0c8
add permission to create serviceaccounts
matifali Aug 6, 2023
24f78d5
refactor
matifali Aug 6, 2023
52faafc
lint
matifali Aug 6, 2023
8b6ba6d
only build if needed
matifali Aug 6, 2023
f8121dd
Discard changes to helm/templates/rbac.yaml
matifali Aug 6, 2023
c633fec
Discard changes to helm/values.yaml
matifali Aug 6, 2023
51413cc
refactor
matifali Aug 6, 2023
4d370f7
wip
matifali Aug 6, 2023
65f1e08
update
matifali Aug 7, 2023
b8e6eab
add volume
matifali Aug 7, 2023
b0aaa69
set KUBECONFIG env variable
matifali Aug 7, 2023
098e5e6
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 8, 2023
cc65580
remove `--skip-build` and add `--force`
matifali Aug 8, 2023
003caf0
typo
matifali Aug 8, 2023
24dc6ca
test
matifali Aug 8, 2023
3e95af7
use a custom template
matifali Aug 8, 2023
4ff0966
finalize
matifali Aug 8, 2023
5923471
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 8, 2023
c64a7b4
use `set -euo pipefail`
matifali Aug 8, 2023
3f8599b
use `envsubst`
matifali Aug 8, 2023
9fa3d67
fmt
matifali Aug 8, 2023
3403530
fix typos
matifali Aug 9, 2023
fdbdf20
add template
matifali Aug 9, 2023
df4d829
use the included template
matifali Aug 9, 2023
27c175c
update
matifali Aug 9, 2023
0ec9c8a
separate build and deploy
matifali Aug 9, 2023
219a44b
do not force certificate creation
matifali Aug 9, 2023
b0afe7d
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 9, 2023
c5cbd16
update docs
matifali Aug 9, 2023
2ac3378
fix template
matifali Aug 9, 2023
1f3c2e2
use HOSTNAME
matifali Aug 9, 2023
d3f57b0
use better condition
matifali Aug 9, 2023
296d352
test `service_account_name`
matifali Aug 9, 2023
de998be
make fmt
matifali Aug 9, 2023
0a9eeeb
remove volumes
matifali Aug 9, 2023
f637501
fix renaming
matifali Aug 9, 2023
a1f2b8e
remove comments
matifali Aug 9, 2023
55524c6
add prefix
matifali Aug 9, 2023
4835b29
`terraform init`
matifali Aug 9, 2023
9576a3f
remove comments
matifali Aug 9, 2023
56d582c
change username to coder
matifali Aug 9, 2023
459b898
update docs
matifali Aug 9, 2023
188dfc9
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 9, 2023
7c71058
test parameter fro CLI
matifali Aug 9, 2023
4c8ab01
update condition
matifali Aug 9, 2023
96888a2
update comment
matifali Aug 9, 2023
b198d33
remove comments
matifali Aug 9, 2023
780f51c
use tailscale derpmap
matifali Aug 10, 2023
e3dac1c
use updated path of helm chart
matifali Aug 10, 2023
832e237
refactor to run on push
matifali Aug 10, 2023
76dbe1b
fix
matifali Aug 10, 2023
2062915
update permissions
matifali Aug 10, 2023
5be2f02
update
matifali Aug 10, 2023
4f5abfd
test
matifali Aug 10, 2023
62bcb8e
remove BRANCH NAME
matifali Aug 10, 2023
8a5f3f8
fix permission
matifali Aug 10, 2023
667acef
update checkout action
matifali Aug 10, 2023
40c3b74
update conditions
matifali Aug 10, 2023
fb29a3c
refactor
matifali Aug 10, 2023
232bed4
fix commenting
matifali Aug 10, 2023
e18a2c7
fix tag lookup
matifali Aug 10, 2023
57567e4
fixup!
matifali Aug 10, 2023
1767a70
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 10, 2023
1f5a5be
remove extra condition
matifali Aug 10, 2023
1a94dbb
debug
matifali Aug 10, 2023
f3b56a3
Update pr-deploy.yaml
matifali Aug 10, 2023
0bc368a
use PR_HOSTNAME
matifali Aug 11, 2023
b69af83
quoting
matifali Aug 11, 2023
ab7be03
Merge branch 'main' into matifali/pr-deployment-namespace-access
matifali Aug 11, 2023
ef13b94
run when build is true
matifali Aug 11, 2023
5906e8e
set BUILD to true if forced
matifali Aug 11, 2023
49f79f3
simplify condition
matifali Aug 11, 2023
bb6cd55
update deploy conditions
matifali Aug 11, 2023
d3a4c98
do a force deploy
matifali Aug 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/pr-deployments/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: pr${PR_NUMBER}-tls
namespace: pr-deployment-certs
spec:
secretName: pr${PR_NUMBER}-tls
issuerRef:
name: letsencrypt
kind: ClusterIssuer
dnsNames:
- "${HOSTNAME}"
- "*.${HOSTNAME}"
31 changes: 31 additions & 0 deletions .github/pr-deployments/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: coder-workspace-pr${PR_NUMBER}
namespace: pr${PR_NUMBER}

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: coder-workspace-pr${PR_NUMBER}
namespace: pr${PR_NUMBER}
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: coder-workspace-pr${PR_NUMBER}
namespace: pr${PR_NUMBER}
subjects:
- kind: ServiceAccount
name: coder-workspace-pr${PR_NUMBER}
namespace: pr${PR_NUMBER}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: coder-workspace-pr${PR_NUMBER}
334 changes: 334 additions & 0 deletions .github/pr-deployments/template/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.11.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.22"
}
}
}

provider "coder" {
}

variable "use_kubeconfig" {
type = bool
description = <<-EOF
Use host kubeconfig? (true/false)

Set this to false if the Coder host is itself running as a Pod on the same
Kubernetes cluster as you are deploying workspaces to.

Set this to true if the Coder host is running outside the Kubernetes cluster
for workspaces. A valid "~/.kube/config" must be present on the Coder host.
EOF
default = false
}

variable "namespace" {
type = string
description = "The Kubernetes namespace to create workspaces in (must exist prior to creating workspaces)"
}

data "coder_parameter" "cpu" {
name = "cpu"
display_name = "CPU"
description = "The number of CPU cores"
default = "2"
icon = "/icon/memory.svg"
mutable = true
option {
name = "2 Cores"
value = "2"
}
option {
name = "4 Cores"
value = "4"
}
option {
name = "6 Cores"
value = "6"
}
option {
name = "8 Cores"
value = "8"
}
}

data "coder_parameter" "memory" {
name = "memory"
display_name = "Memory"
description = "The amount of memory in GB"
default = "2"
icon = "/icon/memory.svg"
mutable = true
option {
name = "2 GB"
value = "2"
}
option {
name = "4 GB"
value = "4"
}
option {
name = "6 GB"
value = "6"
}
option {
name = "8 GB"
value = "8"
}
}

data "coder_parameter" "home_disk_size" {
name = "home_disk_size"
display_name = "Home disk size"
description = "The size of the home disk in GB"
default = "10"
type = "number"
icon = "/emojis/1f4be.png"
mutable = false
validation {
min = 1
max = 99999
}
}

provider "kubernetes" {
# Authenticate via ~/.kube/config or a Coder-specific ServiceAccount, depending on admin preferences
config_path = var.use_kubeconfig == true ? "~/.kube/config" : null
}

data "coder_workspace" "me" {}

resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
startup_script_timeout = 180
startup_script = <<-EOT
set -e

# install and start code-server
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &

# # Set KUBECONFIG env var to the path of the mounted secret
# mkdir -p /home/coder/.kube
# sudo cp /tmp/config /home/coder/.kube/config
# export KUBECONFIG=/home/coder/.kube/config

EOT

# The following metadata blocks are optional. They are used to display
# information about your workspace in the dashboard. You can remove them
# if you don't want to display any information.
# For basic resources, you can use the `coder stat` command.
# If you need more control, you can write your own script.
metadata {
display_name = "CPU Usage"
key = "0_cpu_usage"
script = "coder stat cpu"
interval = 10
timeout = 1
}

metadata {
display_name = "RAM Usage"
key = "1_ram_usage"
script = "coder stat mem"
interval = 10
timeout = 1
}

metadata {
display_name = "Home Disk"
key = "3_home_disk"
script = "coder stat disk --path $${HOME}"
interval = 60
timeout = 1
}

metadata {
display_name = "CPU Usage (Host)"
key = "4_cpu_usage_host"
script = "coder stat cpu --host"
interval = 10
timeout = 1
}

metadata {
display_name = "Memory Usage (Host)"
key = "5_mem_usage_host"
script = "coder stat mem --host"
interval = 10
timeout = 1
}

metadata {
display_name = "Load Average (Host)"
key = "6_load_host"
# get load avg scaled by number of cores
script = <<EOT
echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
EOT
interval = 60
timeout = 1
}
}

# code-server
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "code-server"
icon = "/icon/code.svg"
url = "http://localhost:13337?folder=/home/coder"
subdomain = false
share = "owner"

healthcheck {
url = "http://localhost:13337/healthz"
interval = 3
threshold = 10
}
}

resource "kubernetes_persistent_volume_claim" "home" {
metadata {
name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}-home"
namespace = var.namespace
labels = {
"app.kubernetes.io/name" = "coder-pvc"
"app.kubernetes.io/instance" = "coder-pvc-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
"app.kubernetes.io/part-of" = "coder"
//Coder-specific labels.
"com.coder.resource" = "true"
"com.coder.workspace.id" = data.coder_workspace.me.id
"com.coder.workspace.name" = data.coder_workspace.me.name
"com.coder.user.id" = data.coder_workspace.me.owner_id
"com.coder.user.username" = data.coder_workspace.me.owner
}
annotations = {
"com.coder.user.email" = data.coder_workspace.me.owner_email
}
}
wait_until_bound = false
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "${data.coder_parameter.home_disk_size.value}Gi"
}
}
}
}

resource "kubernetes_deployment" "main" {
count = data.coder_workspace.me.start_count
depends_on = [
kubernetes_persistent_volume_claim.home
]
wait_for_rollout = false
metadata {
name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
namespace = var.namespace
labels = {
"app.kubernetes.io/name" = "coder-workspace"
"app.kubernetes.io/instance" = "coder-workspace-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
"app.kubernetes.io/part-of" = "coder"
"com.coder.resource" = "true"
"com.coder.workspace.id" = data.coder_workspace.me.id
"com.coder.workspace.name" = data.coder_workspace.me.name
"com.coder.user.id" = data.coder_workspace.me.owner_id
"com.coder.user.username" = data.coder_workspace.me.owner
}
annotations = {
"com.coder.user.email" = data.coder_workspace.me.owner_email
}
}

spec {
# replicas = data.coder_workspace.me.start_count
replicas = 1
selector {
match_labels = {
"app.kubernetes.io/name" = "coder-workspace"
}
}

template {
metadata {
labels = {
"app.kubernetes.io/name" = "coder-workspace"
}
}
spec {
security_context {
run_as_user = 1000
fs_group = 1000
}

service_account_name = "coder-workspace-${var.namespace}"
container {
name = "dev"
image = "bencdr/devops-tools"
image_pull_policy = "Always"
command = ["sh", "-c", coder_agent.main.init_script]
security_context {
run_as_user = "1000"
}
env {
name = "CODER_AGENT_TOKEN"
value = coder_agent.main.token
}
resources {
requests = {
"cpu" = "250m"
"memory" = "512Mi"
}
limits = {
"cpu" = "${data.coder_parameter.cpu.value}"
"memory" = "${data.coder_parameter.memory.value}Gi"
}
}
volume_mount {
mount_path = "/home/coder"
name = "home"
read_only = false
}
}

volume {
name = "home"
persistent_volume_claim {
claim_name = kubernetes_persistent_volume_claim.home.metadata.0.name
read_only = false
}
}

affinity {
// This affinity attempts to spread out all workspace pods evenly across
// nodes.
pod_anti_affinity {
preferred_during_scheduling_ignored_during_execution {
weight = 1
pod_affinity_term {
topology_key = "kubernetes.io/hostname"
label_selector {
match_expressions {
key = "app.kubernetes.io/name"
operator = "In"
values = ["coder-workspace"]
}
}
}
}
}
}
}
}
}
}
Loading