Devops

Understanding Terraform depends_on: When and How to Use It

April 7, 2026
Published
#Automation#Cloud#DevOps#Infrastructure as Code#Terraform

Terraform is pretty good at figuring things out on its own. In most cases, it builds a dependency graph automatically and provisions resources in the correct order. But sometimes, that implicit logic just isn’t enough.

That’s where depends_on comes in.

If you’ve ever run into situations where resources are created too early—or worse, fail because something wasn’t ready yet—you’ve already felt the need for explicit dependencies.

What is Terraform depends_on?

depends_on is a meta-argument in Terraform that lets you explicitly define resource dependencies when Terraform can’t infer them automatically.

In simple terms: you’re telling Terraform, “Don’t even try to create this until that is fully done.”

Basic Syntax

TEXT
1resource "aws_instance" "app" {
2  ami           = "ami-123456"
3  instance_type = "t3.micro"
4
5  depends_on = [aws_security_group.app_sg]
6}

Here, Terraform ensures the security group is created before launching the instance—even if there’s no direct attribute reference between them.

Wait… Doesn’t Terraform Handle Dependencies Automatically?

Yes, most of the time.

Terraform builds a dependency graph based on references. For example:

TEXT
1resource "aws_instance" "app" {
2  ami           = "ami-123456"
3  instance_type = "t3.micro"
4  vpc_security_group_ids = [aws_security_group.app_sg.id]
5}

Here, Terraform knows the instance depends on the security group because you referenced its ID.

No depends_on needed.

So when does it fail?

When dependencies are indirect, hidden, or purely operational rather than data-driven.

Real-World Scenarios Where depends_on Matters

1. Provisioners and Side Effects

Provisioners don’t create explicit dependencies in Terraform’s graph.

TEXT
1resource "null_resource" "setup" {
2  provisioner "local-exec" {
3    command = "echo Setup complete"
4  }
5}
6
7resource "aws_instance" "app" {
8  ami           = "ami-123456"
9  instance_type = "t3.micro"
10}

Terraform might run these in parallel, which can break assumptions.

Fix it with:

TEXT
1resource "aws_instance" "app" {
2  ami           = "ami-123456"
3  instance_type = "t3.micro"
4
5  depends_on = [null_resource.setup]
6}

2. External Systems or APIs

Sometimes a resource relies on something outside Terraform—like a DNS propagation or external service readiness.

Example: waiting for an IAM role to fully propagate before attaching policies.

3. Modules with Hidden Dependencies

Modules can obscure relationships.

TEXT
1module "network" {
2  source = "./network"
3}
4
5module "app" {
6  source = "./app"
7}

If app relies on resources inside network but doesn’t explicitly reference them, Terraform won’t know the order.

Solution:

TEXT
1module "app" {
2  source = "./app"
3
4  depends_on = [module.network]
5}

How Terraform Uses depends_on Internally

Terraform builds a directed acyclic graph (DAG) of resources. Adding depends_on inserts additional edges into that graph.

This affects:

  • Creation order
  • Destruction order (reverse dependencies)
  • Parallelism during apply

It doesn’t change resource configuration—it only affects execution sequencing.

A Subtle Gotcha: Overusing depends_on

A common mistake developers make is adding depends_on everywhere “just to be safe.”

This can actually hurt your infrastructure:

  • Reduces parallelism → slower applies
  • Makes dependency graph harder to reason about
  • Hides proper design issues

If Terraform can infer a dependency through references, let it.

Bad Pattern

TEXT
1depends_on = [aws_vpc.main]

…when you're already referencing aws_vpc.main.id somewhere.

Redundant and unnecessary.

Cleaner Alternative: Use Data Flow First

Before reaching for depends_on, ask:

Can I express this dependency through an attribute reference?

Terraform is designed to work best when dependencies are derived from data flow rather than manual ordering.

Example

TEXT
1subnet_id = aws_subnet.app.id

This is better than forcing:

TEXT
1depends_on = [aws_subnet.app]

Multiple Dependencies

You can specify more than one dependency:

TEXT
1depends_on = [
2  aws_security_group.app_sg,
3  aws_iam_role.app_role
4]

Terraform will wait for all of them before proceeding.

Applies to More Than Just Resources

depends_on works with:

  • Resources
  • Modules
  • Data sources (in newer Terraform versions)

This makes it useful across complex infrastructure stacks.

When You Definitely Should Use depends_on

  • When dealing with provisioners
  • When dependencies are not expressed in attributes
  • When modules hide internal resource relationships
  • When timing/order matters beyond configuration

When You Should Avoid It

  • When Terraform already infers dependencies
  • To “fix” race conditions caused by poor design
  • As a default habit in every resource

Quick Mental Model

If Terraform can see the data flow, don’t use depends_on.

If Terraform can’t see the relationship, that’s your signal to use it.

Wrapping It Up

depends_on is a precision tool, not a safety net.

Used correctly, it solves edge cases where Terraform’s dependency graph falls short. Used excessively, it slows things down and hides better solutions.

When in doubt, prefer explicit references. Reach for depends_on only when the dependency is real—but invisible to Terraform.

Comments

Leave a comment on this article with your name, email, and message.

Loading comments...

Similar Articles

More posts from the same category you may want to read next.

Share: