Skip to content

Depends On & Life Cycles

Terraform allows you to define dependencies between resources using the depends_on attribute. This meta argument specifies that one resource depends on another, and Terraform will ensure that the dependent resource is created or updated before changes are made to the resources it depends on.

In addition to depends_on, Terraform also provides a set of lifecycle blocks that allow you to control the creation, updating, and deletion of resources.

It is worth noting that the use of depends_on should be done as a last resort as it can cause Terraform to create more conservative plans that replace more resources than necessary.


In most scenarios, Terraform automatically determines dependencies between resources based on expressions within a resource block.

This is where the depends_on meta-arugment comes in, as it allows you to create an explicit dependency between two resources. These dependencies are not limited to just resources - they can be created between modules.

Put simply depends_on affects the order in which Terraform processes all the resources and data sources associated with an state change.

If a dependency is not visible to Terraform, you can explicitly set it using the depends_on meta-argument. Examples of this could be deploying containers only after the container registry is created, or ensuring settings

Another common scenario is ensuring that a database is initialized (with custom scripts or configurations) before another resource, such as an application server, starts.

Here, the EC2 instance app_server waits until the database initialization script has completed, ensuring that the application server only starts once the database is ready.

resource "aws_db_instance" "db" {
engine = "mysql"
instance_class = "db.t2.micro"
allocated_storage = 20
name = "mydb"
username = "admin"
password = "password"
}
resource "null_resource" "db_initialization" {
provisioner "local-exec" {
command = "echo Initializing database..."
}
depends_on = [aws_db_instance.db]
}
resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
depends_on = [null_resource.db_initialization]
}

In addition to depends_on, Terraform provides a set of lifecycle blocks that allow you to control the creation, updating, and deletion of resources. Here are the available lifecycle blocks:

create_before_destroy: Specifies that the new resource should be created before the old resource is destroyed. This can be useful when changing resource configurations that require both the old and new resources to be present at the same time.
prevent_destroy: Specifies that a resource should not be destroyed, even if it is no longer managed by Terraform. This can be useful for resources that should never be deleted, such as a production database.
ignore_changes: Specifies that Terraform should ignore changes to certain resource attributes. This can be useful for attributes that are managed outside of Terraform, such as instance metadata.

Here’s an example of using create_before_destroy:

resource "aws_lb_target_group" "web" {
name = "web-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
lifecycle {
create_before_destroy = true
}
}

In this example, we create an AWS target group for an application load balancer. We use the lifecycle block to specify that the target group should be created before the old target group is destroyed. This ensures that there is no downtime during the update.

The depends_on attribute allows you to specify dependencies between resources, while lifecycle blocks allow you to control the creation, updating, and deletion of resources.

Dependencies between resources and resource lifecycles are complex topic, and understanding how resources are related and modified on AWS - will help you determine when and how to use the depends_on and life cycle meta-arguments.