Skip to content

Domain Topology

Infrastructure is modeled in three layers:

  • Core infra. One shared core-infra cluster per enterprise or major region. Hosts Forgejo, Harbor, chart publishing, and shared bootstrap services. Cloudflare R2 backs OpenTofu state and any near-term shared storage.
  • Shared observability. Today a vbt-observability stack runs locally inside each cell (Prometheus, Grafana, Loki, Fluent Bit). A central-agent mode is on the chart's roadmap but not yet implemented.
  • Domain cells. Each production domain gets its own cluster/cell per environment. A domain is a product platform, sub-company, internal-ops area, regulated workload boundary, or customer-facing deployment.

Live-tree shape

tofu/live/domains/<domain>/<env>/
  env.hcl
  global/
    dns/terragrunt.hcl
    storage/terragrunt.hcl
  cells/<cell>/
    network/terragrunt.hcl
    secrets/terragrunt.hcl
    cluster/terragrunt.hcl
    database/server/terragrunt.hcl
    database/<instance>/terragrunt.hcl

Cell naming: use primary for the first cell. Use region-qualified names like primary-use2, dr-usw3, iot-use2, or analytics-use2 when a domain needs multiple cells. The remote-state key includes the leaf's working-directory path, so never copy an existing leaf into a new path without a state move - Terragrunt will treat the resources as new and unmanaged. The shape above is the full Azure-backed platform shape. Minimal Linode/K3s domains can omit leaves they do not use, such as secrets, database, global/dns, and global/storage. A specialized cell may also keep env.hcl beside its cell leaves when that cell is the whole stack.

Generic Make targets

All of these take DOMAIN=<slug> ENV=<env> CELL=<cell> (defaults: vibrant-platform, dev, primary): - infra/plan, infra/apply - base stack (network → cluster, plus secrets/database leaves when present). - infra/dns/plan, infra/dns/apply - DNS records; auto-skips until the env-specific ingress IP env var is set. - kubeconfig/domain - fetch AKS credentials for Azure-backed domain cells; K3s domains should use their stack-specific kubeconfig helper. - deploy/core, deploy/observability - Helm install into the cell.

Domain onboarding

  • Pick a stable domain slug (e.g. internal-ops, customer-portal).
  • Project prefix defaults to vbt-<domain> (override with DOMAIN_PROJECT=).
  • Start with one primary cell per environment. Do not co-host multiple production domains on a single app cluster.
  • Allocate non-overlapping VNet/pod/service/PE/IPv6 ranges in tofu/live/domains/cidr-registry.yaml.
  • Choose database placement: dedicated managed server, shared managed server with logical databases, per-cell server, or Crunchy in-cluster. Document RPO/RTO, backup retention, maintenance, and failover before adding regional cells.
  • DNS lives in Tofu. Charts only get their own hosts; they should never need to know other domains or cells.
  • Add a domain values file when defaults aren't enough: charts/vbt-core/envs/<domain>-<env>-<cell>.yaml. Same pattern for scripts/.env.secrets.<domain>-<env>[-<cell>].

Scaling order

  1. Scale inside the primary cell: HPA/KEDA, requests/limits, PDBs, larger VMs, cluster autoscaling.
  2. Add specialized node pools (system, app, CI/build, observability, GPU, IO-heavy).
  3. Add another same-domain cell in the same region for blast-radius isolation.
  4. Add regional cells for latency, data residency, or DR.
  5. Default to active/passive. Active/active requires an explicit data strategy (regional partitioning, globally replicated with conflict rules, read replicas + write primary, or app-level sharding).

Security and compliance posture

Treat every domain/cell as a future compliance boundary. Baseline: default-deny NetworkPolicies, Pod Security Standards, Key Vault purge protection, TLS at the edge, explicit admin lists, documented backup/restore. Regulated/HIPAA domains opt into stricter controls via config: private API, workload identity, per-workload Key Vault access, AKS/Key Vault/Postgres diagnostic logs, immutable audit export, Velero, image signing, admission policy, WAF/rate limiting, tested DR.