How To Use Terraform depends_on Meta-Argument

Terraform is widely known for its ability to efficiently create, manage and update infrastructure resources across cloud providers and on-premises environments. It provides the ability to create resources that depend on each other, and the depends_on meta-argument is a helpful feature for implementing such relationships in a systematic way.

This blog covers what Terraform depends_on is, its syntax, the best use cases, and the best practices to follow.

Looking to gain or polish your Terraform skills? Check out our Terraform for Beginners Course.

What is Terraform depends_on

Terraform's depends_on is a meta-argument that allows you to specify an explicit relationship between resources. With it, you can enforce an orderly creation or update of resources; this is particularly useful when some resources depend on others to be correctly created or configured.

When configuring, Terraform analyzes its dependency graph to determine how resources should be created or updated. By default, Terraform relies on implicit dependencies based on references found within configuration files. However, this might not always suffice when dealing with non-obvious or complex relationships among resources.

With Terraform's depends_on meta-argument, you can add explicit dependencies that do not directly infer from configuration files. This helps ensure that resources are created sequentially during deployment to avoid race conditions or potential issues with deployment processes.

How to Use depends_on in Terraform?

Using the depends_on meta-argument in Terraform is straightforward. Here is the syntax for using it:

resource "aws_resource_type" "resource_name" {
  # Resource configuration here
 
  depends_on = [aws_resource_type.dependent_resource_name]
}

In the above example, aws_resource_type.resource_name is the resource you want to create, and aws_resource_type.dependent_resource_name is the resource it depends on.

Let's walk through an example to illustrate its usage:

Suppose we have a simple Terraform configuration that provisions an AWS EC2 instance and S3 bucket, but one needs to come before the other as log storage requires it. To enforce this order of creation, we can use depends_on as shown below:

resource "aws_s3_bucket" "my_bucket" {
  # S3 bucket configuration here
}
 
resource "aws_instance" "my_ec2_instance" {
  # EC2 instance configuration here
 
  # Explicit dependency on the S3 bucket resource
  depends_on = [aws_s3_bucket.my_bucket]
}

In this example, we have added the depends_on meta-argument to the aws_instance resource and specified that it depends on the aws_s3_bucket resource. This ensures Terraform creates an S3 bucket before creating an EC2 instance.

Remember that the depends_on meta-argument accepts a list of resources, enabling you to specify multiple dependencies if necessary.

When to Use depends_on

The depends_on meta-argument should only be used in cases where implicit dependencies do not suffice. Terraform's dependency analysis system has been designed to handle most cases automatically.

Here are a few situations in which depends_on may become necessary:

  • Resource Creation Order: When resources must be created in an ordered fashion due to dependencies among them, depends_on is a great way to enforce that order.
  • Resource Timing: Sometimes resources take an extended time to become fully available before being provisioned - the depends_on function allows you to manage this transition with precise timing control.
  • External Resources: When your Terraform configuration depends on resources created outside of Terraform, such as databases or networking components, depends_on can ensure Terraform waits until those resources become accessible before proceeding further.
  • Terraform Provisioners: When working with Terraform provisioners (scripts that run upon resource creation), which depend upon other fully functional resources, depends_on can be extremely helpful.
  • Workarounds: In certain instances, depends_on may be employed as a workaround to address limitations or issues in Terraform providers or modules; however, this should only be considered a last resort, and any underlying problems should ideally be dealt with directly.

Terraform depends_on Use Cases and Examples

Here are some additional use cases and examples where depends_on in Terraform can be helpful:

Interdependent Resources: When your resources depend on each other for existence or state. For example, AWS Lambda functions that need to be activated by Amazon CloudWatch event rules can use depends_on to make sure their creation occurs before your Lambda function:

resource "aws_lambda_function" "example" {
  # Function configuration here
}
 
resource "aws_cloudwatch_event_rule" "example" {
  # Event rule configuration here
 
  depends_on = [aws_lambda_function.example]
}

Creation Order: When creating multiple resources within a single configuration, Terraform may need to automatically recognize their correct creation order. You can use depends_on to enforce it instead:

resource "aws_security_group" "web" {
  # Web security group configuration here
}
 
resource "aws_instance" "web_server" {
  # Web server instance configuration here
 
  # Make sure the security group is created first
  depends_on = [aws_security_group.web]
}

Resource Cleanup: If you have resources that depend on other resources and you want to ensure that dependent resources are destroyed before their dependencies, you can use depends_on to manage the deletion order:

resource "aws_security_group_rule" "example" {
  # Security group rule configuration here
 
  # Ensure the associated security group exists before creating the rule
  depends_on = [aws_security_group.example]
}

Provisioners: When using provisioners like local-exec or remote-exec, it may be necessary to ensure specific resources have been provisioned before running these steps. depends_on is an excellent way of managing sequencing for provisioners.

resource "aws_instance" "example" {
  # Instance configuration here
 
  # Make sure the EBS volume is created before running the provisioners
  depends_on = [aws_ebs_volume.example]
 
  provisioner "local-exec" {
	command = "echo Instance provisioned!"
  }
}

Take on real Infrastructure Provisioning Tasks on a live system with KodeKloud Engineer.

Best Practices for Using depends_on

While depends_on can be a powerful tool, improper usage can lead to complications in your Terraform configurations. Here are some best practices to follow when working with depends_on:

  • Limit Usage: As mentioned earlier, rely on implicit dependencies wherever possible. Only resort to depends_on when there is no other viable option.
  • Document Dependencies: When using depends_on, it's crucial to document the reasons for adding explicit dependencies. This helps other team members understand the configuration and avoid unintentional changes.
  • Test Thoroughly: If you use depends_on for timing-related dependencies, thoroughly test your configuration. Resource availability timings can vary, leading to issues if not carefully considered.
  • Avoid Circular Dependencies: Be cautious not to create circular dependencies between resources. Terraform will be unable to resolve such dependencies, resulting in an error during deployment.
  • Check for Updates: During version upgrades of providers or modules, verifying if any changes affect the implicit or explicit dependencies is essential. Sometimes, updates can lead to unexpected behavior, and adjustments might be necessary.

Conclusion

Terraform's depends_on meta-argument is a valuable feature that can help you manage resource dependencies and control the order of resource creation in your infrastructure deployments. While it should be used less frequently, it can be a lifesaver in some situations.

By understanding when and how to use depends_on, you can ensure smoother, more reliable infrastructure provisioning with Terraform. Remember to leverage implicit dependencies when possible and document your explicit dependencies for improved collaboration and maintainability.

Are you looking to polish your Terraform skills in a real-world environment? Enroll in our Terraform for Beginners Course, which covers all of Terraform fundamentals. It includes video lectures, interactive exercises, and hands-on labs to help you internalize concepts and commands.

Terraform Basics Training Course | KodeKloud
Learn Terraform with hands-on labs

To gain other Infrastructure as Code (IaC) skills, check out our IaC Learning Path.