Why Order Matters
When you split state into shards, those shards are not independent — they have dependencies. Your application needs to know the database endpoint. Your database needs to know which subnet to deploy into. Your subnet needs to know which VPC it belongs to. These dependencies form a directed graph, and if you don't manage that graph deliberately, you end up with circular references and deployment deadlocks.
The solution is a strict layered hierarchy: a set of rules about which stacks can read from which other stacks. Dependencies only flow in one direction — from higher-level stacks down to lower-level ones.
The Three-Layer Model
Layer 0 — Foundation (Network)
- Resources: VPCs, subnets, route tables, internet gateways, VPN connections, Transit Gateway attachments.
- Change frequency: Yearly. These are the bedrock of your infrastructure. Changing them is a major event.
- Dependencies: None. Layer 0 reads from nothing. It is the source of truth for everything else.
- Outputs it provides: VPC IDs, subnet IDs, availability zone lists, CIDR blocks.
Layer 1 — Data and Identity
- Resources: RDS instances, ElastiCache clusters, S3 buckets, IAM roles and policies, KMS keys, ACM certificates.
- Change frequency: Monthly. These resources are stable but need occasional updates (new IAM role, new certificate).
- Dependencies: Reads Layer 0 outputs (subnet IDs for RDS placement, VPC ID for security group scope).
- Outputs it provides: Database endpoints, S3 bucket ARNs, IAM role ARNs, KMS key IDs.
Layer 2 — Compute and Application
- Resources: EC2 Auto Scaling Groups, EKS node groups, Lambda functions, ECS services, Kubernetes Deployments.
- Change frequency: Hourly or daily. This is where application code ships.
- Dependencies: Reads Layer 1 (database endpoints, IAM roles) and Layer 0 (subnets, VPC).
- Outputs it provides: Load balancer DNS names, service endpoints (consumed by DNS or monitoring, not by lower layers).
The Golden Rule
Dependencies only flow upward through the hierarchy. Layer 2 can read Layer 1. Layer 1 can read Layer 0. Layer 0 reads nothing. No layer may ever read from a layer above it.
Layer 2 (Compute) → reads → Layer 1 (Data) → reads → Layer 0 (Network)
↑ ↑ ↑
Changes daily Changes monthly Changes yearly
This rule has a practical consequence: you can always determine the correct apply order. When deploying a new environment from scratch, apply Layer 0 first, then Layer 1, then Layer 2. Teardown runs in reverse. There is never ambiguity.
Key Point: A strict dependency hierarchy does more than prevent circular references — it encodes your infrastructure's change velocity. The things that change most often (application code) sit at the top and can be redeployed without touching the stable foundation below. This is the infrastructure equivalent of the Open/Closed Principle.