migrate Vault and Gitea to GKE Autopilot cluster
Implements Option A: move Vault (3x GCE e2-small) and Gitea (Legion k8s) onto a new GKE Autopilot cluster (neuron-platform, us-central1) managed through Legion Argo CD. Terraform (servers/gcp/): - gke.tf: GKE Autopilot cluster, Workload Identity bindings for Vault (KMS) and Gitea (Cloud SQL) - cloud-sql.tf: gitea database + user on neuron-prod-pg15, gitea GCP SA, gitea-database-url and gitea-db-password Secret Manager secrets - vault-nodes.tf: PENDING DECOMMISSION comment with migration checklist k8s manifests (servers/gcp/k8s/): - vault/: namespace.yaml - gitea/: namespace, serviceaccount (Workload Identity annotation), pvc (50Gi standard-rwo), deployment (Gitea + Cloud SQL Auth Proxy sidecar), service, configmap (custom CSS carried from Legion), external-secrets (GCP SM provider) - argocd-apps/: vault-gke.yaml, vault-helm-gke.yaml (Helm chart, HA Raft 3 replicas, GCP KMS auto-unseal, topologySpread across zones, 10Gi premium-rwo), gitea-gke.yaml — all target GKE_CLUSTER_ENDPOINT placeholder Legion (servers/legion/): - apps/gke-apps.yaml: App-of-Apps entry point on Legion Argo CD that syncs the GKE Application manifests - k8s/gitea-runner/Dockerfile: add system-level git insteadOf so GKE CI runners resolve Gitea in-cluster without Cloudflare Access headers
This commit is contained in:
@@ -148,3 +148,100 @@ resource "google_secret_manager_secret" "license_admin_token" {
|
||||
ignore_changes = [id]
|
||||
}
|
||||
}
|
||||
|
||||
# ── Gitea — database + user on neuron-prod-pg15 ───────────────────────────────
|
||||
# Gitea on GKE uses the existing Cloud SQL instance with a Cloud SQL Auth Proxy
|
||||
# sidecar. Connection via unix socket — no public IP exposure.
|
||||
|
||||
resource "google_sql_database" "gitea" {
|
||||
name = "gitea"
|
||||
instance = google_sql_database_instance.main.name
|
||||
project = var.project_id
|
||||
}
|
||||
|
||||
resource "random_password" "gitea_db" {
|
||||
length = 32
|
||||
special = false # Cloud SQL unix socket path DSN; keep alphanumeric for simplicity
|
||||
}
|
||||
|
||||
resource "google_sql_user" "gitea" {
|
||||
name = "gitea"
|
||||
instance = google_sql_database_instance.main.name
|
||||
project = var.project_id
|
||||
password = random_password.gitea_db.result
|
||||
}
|
||||
|
||||
# ── Gitea service account (for Workload Identity → Cloud SQL) ─────────────────
|
||||
|
||||
resource "google_service_account" "gitea" {
|
||||
account_id = "gitea"
|
||||
display_name = "Gitea GKE SA"
|
||||
description = "Service account for the Gitea pod on GKE. Used by the Cloud SQL Auth Proxy sidecar via Workload Identity."
|
||||
project = var.project_id
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "gitea_sql_client" {
|
||||
project = var.project_id
|
||||
role = "roles/cloudsql.client"
|
||||
member = "serviceAccount:${google_service_account.gitea.email}"
|
||||
}
|
||||
|
||||
# ── Secret Manager — Gitea database URL ───────────────────────────────────────
|
||||
# Full DSN using the Cloud SQL Auth Proxy unix socket path.
|
||||
# The proxy sidecar mounts the socket at /cloudsql/<connection_name>.
|
||||
|
||||
resource "google_secret_manager_secret" "gitea_database_url" {
|
||||
secret_id = "gitea-database-url"
|
||||
project = var.project_id
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "gitea_database_url" {
|
||||
secret = google_secret_manager_secret.gitea_database_url.id
|
||||
secret_data = "host=/cloudsql/${google_sql_database_instance.main.connection_name} user=gitea password=${random_password.gitea_db.result} dbname=gitea sslmode=disable"
|
||||
}
|
||||
|
||||
# gitea-db-password — the raw password only, for use in Gitea's GITEA__database__PASSWD.
|
||||
# The Cloud SQL Auth Proxy provides the unix socket; Gitea uses standard postgres
|
||||
# password auth through the proxy socket.
|
||||
resource "google_secret_manager_secret" "gitea_db_password" {
|
||||
secret_id = "gitea-db-password"
|
||||
project = var.project_id
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "gitea_db_password" {
|
||||
secret = google_secret_manager_secret.gitea_db_password.id
|
||||
secret_data = random_password.gitea_db.result
|
||||
}
|
||||
|
||||
# Allow the Gitea GCP SA to access its secrets
|
||||
resource "google_secret_manager_secret_iam_member" "gitea_database_url_accessor" {
|
||||
project = var.project_id
|
||||
secret_id = google_secret_manager_secret.gitea_database_url.secret_id
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${google_service_account.gitea.email}"
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_iam_member" "gitea_db_password_accessor" {
|
||||
project = var.project_id
|
||||
secret_id = google_secret_manager_secret.gitea_db_password.secret_id
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${google_service_account.gitea.email}"
|
||||
}
|
||||
|
||||
output "gitea_service_account_email" {
|
||||
description = "Gitea GKE SA email — used in the Workload Identity annotation"
|
||||
value = google_service_account.gitea.email
|
||||
}
|
||||
|
||||
output "gitea_database_secret_id" {
|
||||
description = "Secret Manager secret ID for the Gitea database URL"
|
||||
value = google_secret_manager_secret.gitea_database_url.secret_id
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user