Terraform Dependencies Explained: How Resource Ordering Really Works
One of the most common questions beginners ask is:
“In what order does Terraform create resources?”
The short answer?
You don’t control the order.
Terraform does.
And it does it intelligently.
Understanding how Terraform handles dependencies and resource ordering is what separates confident IaC engineers from people who add unnecessary depends_on everywhere.
Let’s unpack how it really works.
Terraform Doesn’t Execute Top-to-Bottom
Unlike traditional scripts, Terraform does not execute files line by line.
This will not control order:
resource "aws_vpc" "main" { ... }resource "aws_subnet" "app" { ... }resource "aws_instance" "web" { ... }
Terraform ignores file order entirely.
Instead, it builds something called a:
Dependency Graph
The Dependency Graph (Terraform’s Brain)
Before running apply, Terraform:
- Reads all configuration files
- Identifies references between resources
- Builds a graph of relationships
- Executes resources in dependency order
Terraform ensures:
- A VPC is created before subnets
- Subnets before EC2 instances
- IAM roles before attachments
All automatically.
Implicit Dependencies (The Default Behavior)
Most dependencies in Terraform are implicit.
They happen when one resource references another.
Example: VPC → Subnet → EC2
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}resource "aws_subnet" "app" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}resource "aws_instance" "web" {
subnet_id = aws_subnet.app.id
}
Here’s what Terraform sees:
- Subnet depends on VPC (
vpc_idreference) - Instance depends on Subnet (
subnet_idreference)
You didn’t specify ordering manually.
Terraform figured it out.
That’s the power of references.
Explicit Dependencies (depends_on)
Sometimes dependencies aren’t obvious from references.
Example:
You create:
- An IAM role
- A policy attachment
- A resource that requires the role to be fully ready
In rare cases, Terraform may not detect the dependency automatically.
You can enforce it:
resource "aws_instance" "web" {
depends_on = [aws_iam_role_policy_attachment.example]
}This tells Terraform:
“Wait for this resource before creating this one.”
When Should You Use depends_on?
Use it when:
- There is no direct attribute reference
- You’re dealing with provisioners
- You’re managing external dependencies
- AWS eventual consistency causes timing issues
But here’s the important part:
If you find yourself using depends_on everywhere, something is wrong with your design.
Terraform’s implicit graph should handle most ordering automatically.
depends_on is the override.Parallel Execution (Yes, Terraform Is Fast)
Terraform doesn’t just handle order.
It also runs independent resources in parallel.
Example:
Get TheVega.AI’s stories in your inbox
Join Medium for free to get updates from this writer.
If you create:
- Two separate S3 buckets
- An IAM role unrelated to them
Terraform creates them simultaneously.
That’s why applies can feel surprisingly fast.
Ordering happens only when dependencies exist.
Real-World Example: Networking Stack
Let’s say you build:
- VPC
- Internet Gateway
- Route Table
- Subnet
- EC2 Instance
Dependencies naturally form:
VPC
├── Internet Gateway
├── Subnet
│ └── EC2
└── Route TableTerraform analyzes references and ensures proper creation order.
You don’t write sequencing logic.
Terraform does orchestration.
What Happens During Destruction?
Dependency ordering works in reverse during destroy.
If EC2 depends on Subnet:
- EC2 is destroyed first
- Then Subnet
- Then VPC
Terraform prevents dependency violations automatically.
Hidden Dependency Pitfalls
1️ String Interpolation Without References
Bad:
vpc_id = "vpc-123456"Terraform sees no dependency.
Good:
vpc_id = aws_vpc.main.idNow Terraform understands the relationship.
Hardcoding IDs breaks the dependency graph.
2️ Overusing depends_on
Some engineers add:
depends_on = [aws_vpc.main]Even when the resource already references it.
This is redundant and unnecessary.
Trust the graph.
How to Visualize the Dependency Graph
Terraform includes a built-in command:
terraform graphThis outputs a DOT format graph that can be visualized with Graphviz.
It’s extremely helpful in large infrastructure projects.
The Mental Model You Should Remember
Terraform ordering is based on:
Data references, not file position.
If Resource A references Resource B →
Terraform ensures B runs first.
If no reference exists →
Terraform runs them in parallel.
Why This Matters in Production
Understanding dependencies helps you:
- Avoid race conditions
- Reduce unnecessary
depends_on - Improve performance
- Prevent accidental destroys
- Debug plan behavior faster
Infrastructure ordering errors in production can cause:
- Downtime
- Partial deployments
- Broken networking
Knowing how Terraform thinks makes you more predictable and confident.
Final Thoughts
Terraform is declarative.
You declare what you want.
Terraform decides how and when to build it.
Once you understand:
- Implicit dependencies
- Explicit
depends_on - Graph-based execution
You stop fighting Terraform — and start leveraging it.
Have you ever had a deployment fail because of dependency timing?
Did depends_on fix it — or was it a design issue? Let’s discuss.








