Skip to main content

Terraform three-tier architecture

Aucert's Terraform code is organized into three independent tiers, each with its own state file and lifecycle.

Tier 1: Foundation (infra/terraform/foundation/)

Shared infrastructure that all environments depend on. Rarely changes.

Resources: VNet, AKS cluster, ACR, Key Vault, Storage Account, DNS zones, Internal PostgreSQL.

State: foundation.tfstate in aucert-tfstate-rg.

Tier 2: Internal Platform (infra/terraform/internal-platform/)

Internal tools (Plane, Grafana, Sentry). Always-on, lifecycle independent of product environments.

Resources: Helm releases for internal tools, Cloudflare Tunnel config, Ingress rules.

State: internal-platform.tfstate.

danger

The internal platform tier has prevent_destroy = true on its PostgreSQL instance. Destroying a dev environment CANNOT affect Plane or Astra data.

Tier 3: Environments (infra/terraform/environments/{env}/)

Per-environment resources. Can be created and destroyed independently.

Dev resources: Product PostgreSQL, Redis, Redis Private Endpoint.

State: environments/dev.tfstate.

Dependency rules

  • Tier 2 and Tier 3 both depend on Tier 1 outputs (VNet ID, subnet IDs, AKS credentials)
  • Tier 2 and Tier 3 are independent of each other
  • Destroying a Tier 3 environment never affects Tier 2

Remote state configuration

All tiers use Azure Storage Account for remote state:

PropertyValue
Resource groupaucert-tfstate-rg
Storage accountCreated manually (before Terraform)
Containertfstate
State filesfoundation.tfstate, internal-platform.tfstate, environments/dev.tfstate
LockingAzure Blob lease-based locking (automatic)

Cross-tier data access

Tier 2 and Tier 3 read Tier 1 outputs via terraform_remote_state:

data "terraform_remote_state" "foundation" {
backend = "azurerm"
config = {
resource_group_name = "aucert-tfstate-rg"
storage_account_name = "<storage-account>"
container_name = "tfstate"
key = "foundation.tfstate"
}
}

# Use outputs
locals {
vnet_id = data.terraform_remote_state.foundation.outputs.vnet_id
aks_subnet = data.terraform_remote_state.foundation.outputs.aks_subnet_id
}

Safety summary

TierBlast radiusprevent_destroyChange frequency
FoundationAll environmentsYes (AKS, VNet, Key Vault)Rarely
Internal PlatformTeam tools onlyYes (PostgreSQL)Monthly
EnvironmentsSingle environmentNoWeekly

What's next