Terraform
depends_on reference
Use the depends_on meta-argument to handle hidden resource or module dependencies that Terraform cannot automatically infer. You only need to explicitly specify a dependency when a resource or module relies on another resource's behavior but does not access any of that resource's data in its arguments.
Usage
You can use the depends_on meta-argument in module blocks and in all resource blocks, regardless of resource type.
It requires a list of references to other resources or child modules in the same calling module. This list cannot include arbitrary expressions because the depends_on value must be known before Terraform knows resource relationships and thus before it can safely evaluate expressions.
In the following example, the depends_on argument instructs Terraform to handle a hidden dependency on the aws_iam_instance_profile.example resource.
resource "aws_iam_role" "example" {
name = "example"
# assume_role_policy is omitted for brevity in this example. Refer to the
# documentation for aws_iam_role for a complete example.
assume_role_policy = "..."
}
resource "aws_iam_instance_profile" "example" {
# Because this expression refers to the role, Terraform automatically
# infers that the role must be created first.
role = aws_iam_role.example.name
}
resource "aws_iam_role_policy" "example" {
name = "example"
role = aws_iam_role.example.name
policy = jsonencode({
"Statement" = [{
# This policy allows software running on the EC2 instance to
# access the S3 API.
"Action" = "s3:*",
"Effect" = "Allow",
}],
})
}
resource "aws_instance" "example" {
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
# Terraform can infer from this that the instance profile must
# be created before the EC2 instance.
iam_instance_profile = aws_iam_instance_profile.example
# However, if software running in this EC2 instance needs access
# to the S3 API in order to boot properly, there is also a
# dependency on the aws_iam_role_policy that Terraform cannot
# automatically infer, so you must declare it explicitly:
depends_on = [
aws_iam_role_policy.example
]
}
Processing and planning consequences
The depends_on meta-argument instructs Terraform to complete all actions on the dependency object, including read operations, before performing operations on the object declaring the dependency. When the dependency object is an entire module, depends_on affects the order in which Terraform processes all of the resources and data sources associated with that module. Refer to the documentation on specifying resource dependencies and data resource dependencies for more details.
You should only use depends_on as a last resort because it can cause Terraform to create more conservative plans that replace more resources than necessary. For example, Terraform may treat more values as unknown "(known after apply)" because it is uncertain what changes will occur on the upstream object. This is especially likely when you use depends_on for modules.
Instead of depends_on, we recommend using expression references to imply dependencies when possible. Expression references let Terraform understand which value the reference derives from and avoid planning changes if that particular value hasn’t changed, even if other parts of the upstream object have planned changes.
Supported constructs
You can use depends_on in the following Terraform configuration blocks:
You can use depends_on in the following Stack configuration blocks:
Example use cases
The following use cases describe common patterns for the depends_on argument.
Specify a dependency during validation
Add a depends_on argument to a data block nested in a check block validation when the data source depends on another resource but doesn't reference the resource directly.
check blocks validate infrastructure outside of the typical resource lifecycle. You can nest a data block inside a check block to fetch information that you can reference in an assert block. By adding a depends_on argument to the data block nested in a check block requires, Terraform retrieves the necessary data before running the validation.
For example, if you define a check that verifies that a website API returns 200, that check fails the first time Terraform runs your configuration because your website's infrastructure does not exist yet. You can set the depends_on argument to a resource, such as the load balancer, to ensure Terraform only runs the check once the website is up. When running an operation, Terraform evaluates the check, warns known after apply until that crucial piece of your website is ready, and continues the operation.
However, this strategy only works when the data block does not directly reference the resource specified in the depends_on argument. Otherwise, anytime that resource changes, the check block warns known after apply until Terraform updates that resource, making your check potentially noisy and ineffective.
In the following example, Terraform waits to run the check until it creates the aws_db_instance.main database. Terraform prints known after apply, instead of printing false warnings, until it finishes creating the database:
check "database_connection" {
data "postgresql_database" "app_db" {
name = "application"
depends_on = [aws_db_instance.main]
}
assert {
condition = data.postgresql_database.app_db.allow_connections
error_message = "Database is not accepting connections"
}
}
Create a database service that other services depend on
In the following example, Terraform must launch the aws_db_instance service first so that aws_instance can connect to it:
provider "aws" {
region = "us-east-2"
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_db_instance" "api" {
allocated_storage = 10
db_name = "api_db"
engine = "postgres"
engine_version = "17.4"
instance_class = "db.t3.micro"
username = "foo"
password = "foobarbaz"
skip_final_snapshot = true
}
resource "aws_instance" "api" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
depends_on = [aws_db_instance.api]
}
Specify a dependency on the parent module
In the following example, Terraform only creates the EC2 instance module after creating the S3 bucket resource:
resource "aws_s3_bucket" "example" {
bucket = "my-example-bucket-12345"
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "6.0.2"
name = "example-instance"
ami = data.aws_ami.latest_amazon_linux.id
instance_type = "t2.micro"
depends_on = [aws_s3_bucket.example]
}
Specify a dependency when outputting values
In the following example, instance_ip_addr adds an explicit dependency on the security group rule to ensure that Terraform creates the security group before exposing the IP address:
output "instance_ip_addr" {
value = aws_instance.server.private_ip
description = "The private IP address of the main server instance."
depends_on = [
# Services are unreachable unless the security group rule is created
# before exposing this IP address.
aws_security_group_rule.local_access,
]
}
The output block typically does not require explicit dependencies so we recommend that when you add an explicit dependency, include a comment to explain why it's necessary.