Explicit depends_on
Use depends_on for the rare hidden dependency that Terraform cannot infer from references.
depends_on = [aws_iam_role_policy.example]Occasionally two resources depend on each other in a way that is not visible through an attribute reference — for example, an application that needs an IAM policy to exist before it starts, even though it never references the policy directly.
The depends_on meta-argument
For those cases, add an explicit depends_on listing the resources that must be created first.
Use sparingly
Explicit dependencies are a last resort. Overusing them reduces parallelism and makes the graph harder to reason about.
Example
resource "aws_iam_role_policy" "app" {
name = "app-policy"
role = aws_iam_role.app.id
policy = data.aws_iam_policy_document.app.json
}
resource "aws_instance" "app" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
# Ensure the policy exists before the app boots
depends_on = [aws_iam_role_policy.app]
}When to use it
- An application EC2 instance explicitly depends_on an IAM role policy attachment because the attachment has no attribute the instance can reference but must complete first.
- A Lambda function uses depends_on to wait for an SQS queue policy to be applied, since the policy is a separate resource with no return value the function needs.
- A database migration job resource explicitly depends_on the RDS instance being ready and its parameter group applied, dependencies Terraform cannot infer from references alone.
More examples
depends_on IAM policy attachment
Forces the instance to wait for the IAM policy attachment even though there is no direct attribute reference between them.
resource "aws_iam_role_policy_attachment" "s3_access" {
role = aws_iam_role.app.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.app.name
depends_on = [aws_iam_role_policy_attachment.s3_access]
}S3 bucket policy before object
Ensures the bucket policy is in place before uploading the public HTML object, avoiding a race where the object becomes public before the policy lands.
resource "aws_s3_bucket_policy" "public_read" {
bucket = aws_s3_bucket.site.id
policy = data.aws_iam_policy_document.public_read.json
}
resource "aws_s3_object" "index" {
bucket = aws_s3_bucket.site.id
key = "index.html"
content = "<h1>Hello</h1>"
depends_on = [aws_s3_bucket_policy.public_read]
}Multiple explicit dependencies
Uses a list in depends_on to declare multiple hidden dependencies that Terraform cannot detect from attribute references.
resource "aws_db_instance" "app" {
identifier = "app-db"
engine = "mysql"
instance_class = "db.t3.micro"
allocated_storage = 20
username = "admin"
password = var.db_password
depends_on = [
aws_db_subnet_group.app,
aws_security_group.rds
]
}
Discussion