# Contour root — in-cluster backend + providers. # # This branch (`contour`) serves ALL closed contours. Backend state lives in the # contour MinIO; the concrete contour is selected by INFRA_ENV. Providers target # in-cluster services (no managed YC). Infra-service admin creds are read from # Vault by a workflow step and injected as env vars (see .gitea/workflows) — # providers pick them up via get_env, so there is no cross-provider data-source # ordering dependency on the vault-secrets stack. remote_state { backend = "s3" generate = { path = "backend.tf" if_exists = "overwrite_terragrunt" } config = { endpoint = get_env("TF_STATE_S3_ENDPOINT", "") bucket = get_env("TF_STATE_S3_BUCKET", "") key = "${path_relative_to_include()}/terraform.tfstate" region = get_env("TF_STATE_S3_REGION", "ru-central1") access_key = get_env("S3_ACCESS_KEY", get_env("AWS_ACCESS_KEY_ID", "")) secret_key = get_env("S3_SECRET_KEY", get_env("AWS_SECRET_ACCESS_KEY", "")) skip_region_validation = true skip_credentials_validation = true skip_metadata_api_check = true skip_bucket_root_access = true force_path_style = true } } generate "provider" { path = "provider.tf" if_exists = "overwrite_terragrunt" contents = <= v1.0.0 (terraform-modules/rabbitmq, brusnika-stage pilot) # declares its own required_providers and provider "rabbitmq" block, and this # unit uses no other provider - the whole shared block below is intentionally # skipped here to avoid "Duplicate required providers configuration". %{else~} terraform { required_version = ">= 1.5.0" required_providers { kubernetes = { source = "hashicorp/kubernetes", version = "~> 2.23" } vault = { source = "hashicorp/vault", version = "~> 4.2" } kafka = { source = "Mongey/kafka", version = "0.10.4" } postgresql = { source = "cyrilgdn/postgresql", version = "~> 1.21" } rabbitmq = { source = "cyrilgdn/rabbitmq", version = "~> 1.8" } minio = { source = "aminueza/minio", version = "~> 2.0" } random = { source = "hashicorp/random", version = "~> 3.1" } tls = { source = "hashicorp/tls", version = "~> 4.0" } } } variable "kubeconfig_path" { type = string default = "" } variable "kube_context" { type = string default = "" } provider "kubernetes" { # KUBECONFIG is set unconditionally at job level for the external-runner case # (see .gitea/workflows/terraform.yml "Prepare kubeconfig"); on an in-cluster # runner that file is never written (no KUBECONFIG_B64), so fileexists() must # gate this - a non-empty path alone isn't enough, else the provider tries to # read a file that was never created and falls over instead of using the pod # ServiceAccount / in-cluster config. config_path = var.kubeconfig_path != "" && fileexists(var.kubeconfig_path) ? var.kubeconfig_path : null config_context = var.kubeconfig_path != "" && fileexists(var.kubeconfig_path) ? var.kube_context : null } # Vault: static VAULT_TOKEN if provided, else in-cluster k8s auth by the runner SA. provider "vault" { %{if get_env("VAULT_TOKEN", "") == ""~} auth_login_kubernetes { role = "${get_env("VAULT_K8S_ROLE", "terraform")}" mount_path = "auth/${get_env("VAULT_K8S_AUTH_BACKEND", "kubernetes")}" } %{endif~} } # In-cluster PostgreSQL (admin). Password injected from Vault secrets/postgresql/admin. provider "postgresql" { host = "${get_env("PG_ADMIN_HOST", "postgresql.postgresql.svc.cluster.local")}" port = ${get_env("PG_ADMIN_PORT", "5432")} username = "${get_env("PG_ADMIN_USER", "postgres")}" password = "${get_env("PG_ADMIN_PASSWORD", "")}" sslmode = "disable" superuser = false } # In-cluster Kafka (Bitnami). Admin = inter_broker super-user from Vault secrets/kafka/bootstrap. provider "kafka" { bootstrap_servers = ["${get_env("KAFKA_BOOTSTRAP", "kafka-kafka-contour-controller-0.kafka-kafka-contour-controller-headless.kafka.svc.cluster.local:9094")}"] tls_enabled = ${get_env("KAFKA_TLS_ENABLED", "false")} sasl_mechanism = "${get_env("KAFKA_SASL_MECHANISM", "plain")}" sasl_username = "${get_env("KAFKA_ADMIN_USER", "inter_broker_user")}" sasl_password = "${get_env("KAFKA_ADMIN_PASSWORD", "")}" } # RabbitMQ provider is configured INSIDE modules/rabbitmq (from its management_* # inputs), so it is intentionally NOT generated here to avoid a duplicate config. # MinIO provider is configured INSIDE modules/minio-buckets (endpoint from # infrastructure.yaml, admin creds from Vault via the s3 unit), so it is not # generated here. %{endif~} EOF_PROVIDER }