TerraformXV · Environment Architecture and State BoundariesArchitecture
State Boundaries: Decomposing the Terraform Estate
What you'll learn
- Design state boundaries for production
- Decompose by lifecycle, ownership, environment, and failure domain
- Avoid the failure modes of fragmented and monolithic states
- Recognise when more or fewer states are appropriate
Prerequisites
Verified against Terraform CLI 1.9.x · OpenTofu 1.7.x · HCL 2.0 · bpg/proxmox provider 0.66+ · hashicorp/local provider 2.5+ · hashicorp/null provider 3.2+ · hashicorp/random provider 3.6+ · hashicorp/http provider 3.4+ · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · 2026-08-12
A state boundary is the unit of failure. A failure in one state cannot affect another state. The state boundary is the primary control for blast radius. This lesson teaches how to design state boundaries for production Terraform estates.
When to split a state
A state should be split when:
- Lifecycles differ. Network resources change rarely; compute resources change often. The two have different deployment cadences.
- Ownership differs. The network team owns the network; the application team owns the compute. The two teams will make changes independently.
- Failure domains differ. A failure in the network should not affect the compute. The two have different failure domains.
- Environments differ. Production and non-production are different. The two have different testing requirements.
- Security boundaries differ. IAM and security are higher-trust than compute. The two have different security requirements.
A state should not be split when:
- The resources are tightly coupled. A subnet and its route table are tightly coupled; they should be in the same state.
- The operational complexity is not worth it. Three resources with one operator do not need three states.
- The blast radius is already small. A state with three resources that are not critical has a small blast radius.
The decomposition framework
A production estate is decomposed by:
| Axis | Examples |
|---|---|
| Lifecycle | Network (changes rarely), Compute (changes often), Database (changes occasionally) |
| Ownership | Platform team, Application team, Security team |
| Failure domain | Network availability zone, Compute cluster, Database cluster |
| Environment | Production, staging, dev |
| Security | Internet-facing, internal, restricted |
The axes are not exclusive. A production state is decomposed along multiple axes:
prod-network-001 # production network (changes rarely)
prod-compute-001 # production compute (changes often)
prod-database-001 # production database (changes occasionally)
prod-shared-001 # production shared services (IAM, secrets)
staging-network-001
staging-compute-001
...
Each state has a clear ownership and a clear deployment cadence.
The state boundary trade-off
There is a trade-off between blast radius and operational complexity:
One state containing all infrastructure
- Blast radius: the entire estate
- Operational complexity: 1 state, 1 plan, 1 apply
Many states, one per resource
- Blast radius: 1 resource
- Operational complexity: 1000 states, 1000 plans, 1000 applies
The trade-off is real. The right answer is in the middle.
The right answer is:
- One state per lifecycle.
- One state per ownership.
- One state per environment.
These axes give a manageable number of states with manageable blast radii.
The pattern
A production estate can be decomposed like:
states/
├── network/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
├── compute/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
├── database/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
└── shared/
├── main.tf
├── variables.tf
├── outputs.tf
└── versions.tf
Each state has its own:
- Backend configuration.
- Lockfile.
- Output values.
The states communicate via terraform_remote_state data sources.
The cross-state coupling
The states are coupled. The compute state depends on the network state:
# compute/main.tf
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "mycompany-terraform-state"
key = "network/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_instance" "web" {
ami = "ami-0e1bed4f"
subnet_id = data.terraform_remote_state.network.outputs.public_subnet_id
}
The coupling is explicit. The compute state cannot be applied without the network state being applied first.
The deployment cadence
Each state has a deployment cadence:
| State | Cadence |
|---|---|
| Network | Quarterly |
| Compute | Daily |
| Database | Monthly |
| Shared | As needed |
The cadence is the rhythm of change. The state boundaries are the deployment boundaries.
The state boundary failures
The failure modes of state boundaries:
Too monolithic. A single state containing all infrastructure has the blast radius of the entire estate.
Too fragmented. A state per resource creates operational complexity that is not worth the marginal blast radius reduction.
Wrong coupling. A state boundary that puts tightly coupled resources in different states creates a deployment ordering problem.
No outputs. A state that does not expose its outputs cannot be consumed by other states.
Wrong environment. A state containing both production and non-production resources has the wrong blast radius.
The composition test
For a state boundary proposal, answer:
- What is the lifecycle of the resources?
- What is the ownership of the resources?
- What is the failure domain of the resources?
- What is the environment of the resources?
- What is the security boundary of the resources?
If the answers are consistent, the state boundary is correct. If the answers are mixed, the state boundary is wrong.
What comes next
The next lesson is workspaces — the Terraform feature for multiple states in a single backend configuration.
Verification
Knowledge check · 7 questions
Q1. Why are multiple environments important?
Q2. What is a state boundary?
Q3. Workspaces are appropriate for production isolation.
Q4. What is the role of directories in multi-environment estates?
Q5. Which of the following are good production patterns for environments? (Select all that apply.)
Q6. What is the role of accounts/projects/subscriptions in environments?
Q7. A team uses workspaces for staging and production. The state is corrupted in staging. Production is unaffected. What is the fix?
Passing score: 75%. Answers are checked in this browser.