# ── GKE Autopilot Cluster — neuron-platform ─────────────────────────────────── # # Regional Autopilot cluster in us-central1. Autopilot manages the node pool # automatically — no node pools to configure, no VM sizes to choose. # Pods spread across a/b/c zones automatically by GKE. # # Workload Identity is required so Vault pods can access KMS (auto-unseal) # and Gitea pods can use Cloud SQL Auth Proxy without key files. # # After `terraform apply`, register the cluster with Legion Argo CD: # 1. Get the endpoint: terraform output gke_cluster_endpoint # 2. Get credentials: gcloud container clusters get-credentials neuron-platform \ # --region us-central1 --project neuron-785695 # 3. Register with Argo CD: # argocd cluster add --name gke-neuron-platform # 4. Update servers/gcp/k8s/argocd-apps/*.yaml with the actual cluster endpoint. resource "google_container_cluster" "neuron_platform" { provider = google-beta name = "neuron-platform" location = "us-central1" project = var.project_id # Autopilot — GKE manages node pools, scaling, and node security enable_autopilot = true release_channel { channel = "REGULAR" } # Workload Identity — required for Vault KMS and Gitea Cloud SQL proxy workload_identity_config { workload_pool = "${var.project_id}.svc.id.goog" } # Deletion protection — prevent accidental cluster destruction deletion_protection = true # Cluster networking — uses default VPC (same as Vault GCE nodes) ip_allocation_policy {} # Disable basic auth and client cert (Workload Identity handles auth) master_auth { client_certificate_config { issue_client_certificate = false } } } # ── Workload Identity bindings ──────────────────────────────────────────────── # # Each GCP SA gets a binding that allows its corresponding k8s ServiceAccount # (in the GKE cluster) to impersonate it via Workload Identity. # The k8s SA must also have the annotation: # iam.gke.io/gcp-service-account: # Vault pods (namespace: vault, k8s SA: vault) → vault-unseal GCP SA # This lets the Vault StatefulSet access KMS for auto-unseal without key files. resource "google_service_account_iam_member" "vault_workload_identity" { service_account_id = google_service_account.vault_unseal.name role = "roles/iam.workloadIdentityUser" member = "serviceAccount:${var.project_id}.svc.id.goog[vault/vault]" depends_on = [google_container_cluster.neuron_platform] } # Gitea pod (namespace: gitea, k8s SA: gitea) → gitea GCP SA # This lets the Cloud SQL Auth Proxy sidecar connect to neuron-prod-pg15. resource "google_service_account_iam_member" "gitea_workload_identity" { service_account_id = google_service_account.gitea.name role = "roles/iam.workloadIdentityUser" member = "serviceAccount:${var.project_id}.svc.id.goog[gitea/gitea]" depends_on = [google_container_cluster.neuron_platform] } # ── Outputs ─────────────────────────────────────────────────────────────────── output "gke_cluster_endpoint" { description = "GKE cluster API endpoint — use as destination.server in Argo CD Applications" value = "https://${google_container_cluster.neuron_platform.endpoint}" sensitive = true } output "gke_cluster_name" { description = "GKE cluster name" value = google_container_cluster.neuron_platform.name } output "gke_workload_pool" { description = "Workload Identity pool — used in Workload Identity bindings" value = "${var.project_id}.svc.id.goog" }