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.
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:
| Property | Value |
|---|---|
| Resource group | aucert-tfstate-rg |
| Storage account | Created manually (before Terraform) |
| Container | tfstate |
| State files | foundation.tfstate, internal-platform.tfstate, environments/dev.tfstate |
| Locking | Azure 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
| Tier | Blast radius | prevent_destroy | Change frequency |
|---|---|---|---|
| Foundation | All environments | Yes (AKS, VNet, Key Vault) | Rarely |
| Internal Platform | Team tools only | Yes (PostgreSQL) | Monthly |
| Environments | Single environment | No | Weekly |
What's next
- Azure topology — Full resource inventory
- How to update Terraform — Step-by-step runbook