Terraform usually figures out resource creation order on its own. depends_on is used only when it can't — it forces Terraform to create one resource before another.
When one resource directly references another, Terraform detects the order automatically.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # Terraform sees this reference
}
Terraform knows: create VPC first, then subnet. No depends_on needed.
Sometimes a resource depends on another but doesn't directly reference its attribute — the connection is invisible to Terraform.
Example: EC2 runs a startup script that reads from an S3 bucket. But EC2 doesn't reference aws_s3_bucket anywhere in its code — Terraform just sees a plain text script. So it thinks both are independent and may create EC2 first.
EC2 boots → runs script → tries to read from S3 → S3 not created yet → script fails.
resource "aws_s3_bucket" "data" {
bucket = "my-app-data"
}
resource "aws_instance" "app" {
ami = "ami-123456"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
aws s3 cp s3://my-app-data/config.txt /home/ec2-user/
EOF
depends_on = [aws_s3_bucket.data] # create S3 first, then EC2
}
With depends_on → S3 created first → EC2 boots → script runs successfully.
Simple rule: if the connection is inside a script or string — Terraform can't see it, so you need depends_on.
Use it only when automatic detection fails — which happens in these cases: