From 08f0eaaf3b106b0594fbdddd9f5f7ee03fa51048 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Thu, 12 Dec 2024 09:28:49 -0500 Subject: [PATCH] feat: add new scaletest infrastructure (#15573) Closes https://github.com/coder/internal/issues/148 This has been validated to have working proxies with the `small` scenario. - [x] multi-region gcp infrastructure - [x] use cloudflare provider to automate dns entries - [x] automate proxy registration - [x] multi-regional proxies - [x] move scenarios into locals This excludes the infrastructure for `cert-manager` and `otel-collector` and those will be included in followup PRs. --- scaletest/terraform/action/cf_dns.tf | 8 + .../terraform/action/coder_helm_values.tftpl | 105 ++++++++++++ scaletest/terraform/action/coder_proxies.tf | 102 +++++++++++ scaletest/terraform/action/coder_templates.tf | 160 ++++++++++++++++++ scaletest/terraform/action/gcp_clusters.tf | 146 ++++++++++++++++ scaletest/terraform/action/gcp_db.tf | 89 ++++++++++ scaletest/terraform/action/gcp_project.tf | 27 +++ scaletest/terraform/action/gcp_vpc.tf | 42 +++++ scaletest/terraform/action/k8s_coder_asia.tf | 104 ++++++++++++ .../terraform/action/k8s_coder_europe.tf | 104 ++++++++++++ .../terraform/action/k8s_coder_primary.tf | 124 ++++++++++++++ scaletest/terraform/action/main.tf | 123 ++++++++++++++ scaletest/terraform/action/scenarios.tf | 106 ++++++++++++ scaletest/terraform/action/vars.tf | 87 ++++++++++ 14 files changed, 1327 insertions(+) create mode 100644 scaletest/terraform/action/cf_dns.tf create mode 100644 scaletest/terraform/action/coder_helm_values.tftpl create mode 100644 scaletest/terraform/action/coder_proxies.tf create mode 100644 scaletest/terraform/action/coder_templates.tf create mode 100644 scaletest/terraform/action/gcp_clusters.tf create mode 100644 scaletest/terraform/action/gcp_db.tf create mode 100644 scaletest/terraform/action/gcp_project.tf create mode 100644 scaletest/terraform/action/gcp_vpc.tf create mode 100644 scaletest/terraform/action/k8s_coder_asia.tf create mode 100644 scaletest/terraform/action/k8s_coder_europe.tf create mode 100644 scaletest/terraform/action/k8s_coder_primary.tf create mode 100644 scaletest/terraform/action/main.tf create mode 100644 scaletest/terraform/action/scenarios.tf create mode 100644 scaletest/terraform/action/vars.tf diff --git a/scaletest/terraform/action/cf_dns.tf b/scaletest/terraform/action/cf_dns.tf new file mode 100644 index 0000000000..eaaff28ce0 --- /dev/null +++ b/scaletest/terraform/action/cf_dns.tf @@ -0,0 +1,8 @@ +resource "cloudflare_record" "coder" { + for_each = local.deployments + zone_id = var.cloudflare_zone_id + name = each.value.subdomain + content = google_compute_address.coder[each.key].address + type = "A" + ttl = 3600 +} diff --git a/scaletest/terraform/action/coder_helm_values.tftpl b/scaletest/terraform/action/coder_helm_values.tftpl new file mode 100644 index 0000000000..7de0c598a1 --- /dev/null +++ b/scaletest/terraform/action/coder_helm_values.tftpl @@ -0,0 +1,105 @@ +coder: + workspaceProxy: ${workspace_proxy} + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "cloud.google.com/gke-nodepool" + operator: "In" + values: ["${node_pool}"] + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: "kubernetes.io/hostname" + labelSelector: + matchExpressions: + - key: "app.kubernetes.io/instance" + operator: "In" + values: ["${release_name}"] + env: + %{~ if workspace_proxy ~} + - name: "CODER_ACCESS_URL" + value: "${access_url}" + - name: CODER_PRIMARY_ACCESS_URL + value: "${primary_url}" + - name: CODER_PROXY_SESSION_TOKEN + valueFrom: + secretKeyRef: + key: token + name: "${proxy_token}" + %{~ endif ~} + %{~ if provisionerd ~} + - name: "CODER_URL" + value: "${access_url}" + - name: "CODER_PROVISIONERD_TAGS" + value: "scope=organization" + - name: "CODER_CONFIG_DIR" + value: "/tmp/config" + %{~ endif ~} + %{~ if !workspace_proxy && !provisionerd ~} + - name: "CODER_ACCESS_URL" + value: "${access_url}" + - name: "CODER_PG_CONNECTION_URL" + valueFrom: + secretKeyRef: + name: "${db_secret}" + key: url + - name: "CODER_PROVISIONER_DAEMONS" + value: "0" + - name: CODER_PROVISIONER_DAEMON_PSK + valueFrom: + secretKeyRef: + key: psk + name: "${provisionerd_psk}" + - name: "CODER_PROMETHEUS_COLLECT_AGENT_STATS" + value: "true" + - name: "CODER_PROMETHEUS_COLLECT_DB_METRICS" + value: "true" + - name: "CODER_PPROF_ENABLE" + value: "true" + %{~ endif ~} + - name: "CODER_CACHE_DIRECTORY" + value: "/tmp/coder" + - name: "CODER_TELEMETRY_ENABLE" + value: "false" + - name: "CODER_LOGGING_HUMAN" + value: "/dev/null" + - name: "CODER_LOGGING_STACKDRIVER" + value: "/dev/stderr" + - name: "CODER_PROMETHEUS_ENABLE" + value: "true" + - name: "CODER_VERBOSE" + value: "true" + - name: "CODER_EXPERIMENTS" + value: "${experiments}" + - name: "CODER_DANGEROUS_DISABLE_RATE_LIMITS" + value: "true" + image: + repo: ${image_repo} + tag: ${image_tag} + replicaCount: "${replicas}" + resources: + requests: + cpu: "${cpu_request}" + memory: "${mem_request}" + limits: + cpu: "${cpu_limit}" + memory: "${mem_limit}" + securityContext: + readOnlyRootFilesystem: true + %{~ if !provisionerd ~} + service: + enable: true + sessionAffinity: None + loadBalancerIP: "${ip_address}" + %{~ endif ~} + volumeMounts: + - mountPath: "/tmp" + name: cache + readOnly: false + volumes: + - emptyDir: + sizeLimit: 1024Mi + name: cache diff --git a/scaletest/terraform/action/coder_proxies.tf b/scaletest/terraform/action/coder_proxies.tf new file mode 100644 index 0000000000..6af3ef82bb --- /dev/null +++ b/scaletest/terraform/action/coder_proxies.tf @@ -0,0 +1,102 @@ +data "http" "coder_healthy" { + url = local.deployments.primary.url + // Wait up to 5 minutes for DNS to propagate + retry { + attempts = 30 + min_delay_ms = 10000 + } + + lifecycle { + postcondition { + condition = self.status_code == 200 + error_message = "${self.url} returned an unhealthy status code" + } + } + + depends_on = [helm_release.coder_primary, cloudflare_record.coder["primary"]] +} + +resource "null_resource" "api_key" { + provisioner "local-exec" { + interpreter = ["/bin/bash", "-c"] + command = < ${path.module}/.coderv2/session_token + +api_key=$(curl '${local.deployments.primary.url}/api/v2/users/me/keys/tokens' \ + -H "Coder-Session-Token: $${session_token}" \ + --data-raw '{"token_name":"terraform","scope":"all"}' \ + --insecure --silent | jq -r .key) + +echo -n $${api_key} > ${path.module}/.coderv2/api_key +EOF + } + + depends_on = [data.http.coder_healthy] +} + +data "local_file" "api_key" { + filename = "${path.module}/.coderv2/api_key" + depends_on = [null_resource.api_key] +} + +resource "null_resource" "license" { + provisioner "local-exec" { + interpreter = ["/bin/bash", "-c"] + command = < ${path.module}/.coderv2/europe_proxy_token +EOF + } + + depends_on = [null_resource.license] +} + +data "local_file" "europe_proxy_token" { + filename = "${path.module}/.coderv2/europe_proxy_token" + depends_on = [null_resource.europe_proxy_token] +} + +resource "null_resource" "asia_proxy_token" { + provisioner "local-exec" { + interpreter = ["/bin/bash", "-c"] + command = < ${path.module}/.coderv2/asia_proxy_token +EOF + } + + depends_on = [null_resource.license] +} + +data "local_file" "asia_proxy_token" { + filename = "${path.module}/.coderv2/asia_proxy_token" + depends_on = [null_resource.asia_proxy_token] +} diff --git a/scaletest/terraform/action/coder_templates.tf b/scaletest/terraform/action/coder_templates.tf new file mode 100644 index 0000000000..c2334a488a --- /dev/null +++ b/scaletest/terraform/action/coder_templates.tf @@ -0,0 +1,160 @@ +resource "local_file" "kubernetes_template" { + filename = "${path.module}/.coderv2/templates/kubernetes/main.tf" + content = <