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 |
| NGINX Ingress | Ingress controller, fronted by MetalLB |
| 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 |
| Kubecost | Cluster cost attribution |
| 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 |
| 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.