Skip to content

Platform (Stage 2)

Stage 2 is Terraform. It assumes a working Kubernetes cluster from Stage 1 and deploys 20 modules onto it.

Every module is a directory under stage2/, wired together in stage2/main.tf. All input variables live in the root stage2/variables.tf and are passed down, so a module never reads a variable directly.

Always-on modules

These have no count, so they deploy on every apply.

Module Deploys
Preflight Cross-module compatibility checks that must pass before cluster changes
Kubernetes CoreDNS configuration, Prometheus CRDs
Istio Gateway Gateway API CRDs, the Istio control plane, and the one Gateway every public hostname is served through
Cert-Manager TLS certificates from Let's Encrypt
Longhorn Distributed block storage, the default StorageClass
MinIO S3-compatible object storage
Monitoring Prometheus, Grafana, AlertManager, ElastAlert2
OAuth2 Proxy Auth0-backed authentication in front of the web UIs
ArgoCD GitOps continuous deployment
Stakater Reloader Restarts workloads when a Secret or ConfigMap changes

Gated modules

Controlled by an enable flag. The Terraform idiom is count = var.<name>_enable ? 1 : 0, so a disabled module is simply not in the plan.

Module Gate Default
GitLab Platform host_machine_architecture == "amd64" auto, AMD64 only
Logging logging_module_enable true
ArgoCD Image Updater argocd_image_updater_enable false
Datadog datadog_enable false
Kubecost kubecost_enable false
Cloudflare Tunnel cloudflare_tunnel_enable false
Sealed Secrets sealed_secrets_enable true
LiteLLM litellm_enable false
OmniRoute omniroute_enable false
Tailscale tailscale_enable false
WireGuard wireguard_enable false

The stage2/vpn/ module has no module-level gate, so it is always in the plan and its vpn namespace is always created. Its two backends, Tailscale and WireGuard, are gated per resource by tailscale_enable and wireguard_enable, both false by default and independent of each other.

GitLab is AMD64 only

registry.gitlab.com/gitlab-org/build/cng/kubectl publishes no ARM64 image. On an ARM64 control plane the GitLab module is skipped entirely, which also removes ArgoCD's depends_on source.

Ordering

Modules do not deploy in file order. See the dependency graph for the actual depends_on DAG and why the ordering matters.