Subscribe to the Spacelift Blog newsletter, Mission Infrastructure |

Sign Up ➡️

Terraform

How to Use Terraform depends_on Meta-Argument

terraform depends_on

Terraform’s depends_on meta-argument creates an explicit dependency between resources or modules when Terraform can’t infer the relationship automatically, though overusing it can lead to slower plans and harder-to-maintain code.

In this article, you’ll learn:

  • How implicit and explicit dependencies work in Terraform
  • When depends_on is actually necessary (and when it isn’t)
  • Practical examples: resources, modules, and multiple dependencies
  • Best practices to keep your configuration clean and performant

Resource dependencies in Terraform

Terraform uses resource dependencies to create and destroy resources in the correct order. Expression references create implicit dependencies between one resource and another resource.

The following shows an implicit dependency created between two Azure resources using an expression reference.

resource "azurerm_resource_group" "rg" {
  name     = "rg-example-centralus"
  location  = "centralus"
}

resource "azurerm_virtual_network" "vnet" {
  name                            = "vnet-example-centralus"
  resource_group_name = azurerm_resource_group.rg.name
}

In this example, an implicit dependency is created because the VNet’s resource_group_name attribute references the name of the resource group. The object with the dependency, the VNet, is referred to as the “object declaring the dependency.” The resource group is referred to as the “dependency object.”

Terraform completes all actions on the dependency object first, then performs actions on the object declaring the dependency.

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

There are rare scenarios, however, where Terraform cannot infer dependencies between resources. In these cases, you will need to create an explicit dependency. This is the purpose of the Terraform depends_on meta-argument.

Read more: How to Manage Dependencies Between Terraform Resources

What is Terraform depends_on?

Terraform depends_on is a meta-argument that creates an explicit dependency between two resources or modules, telling Terraform to fully provision one before starting the other

Dependencies are not limited to just resources. They can be created between modules. When the dependency is a module, depends_on affects the order in which Terraform processes all the resources and data sources associated with that module.

Both implicit and explicit dependencies affect the order in which resources are destroyed as well as created. Explicit dependencies are only necessary when a resource or module relies on another resource’s behavior but does not access any of that resource’s data in its arguments.

There are some things you should consider when using Terraform depends_on:

  • Always include a comment to explain why using depends_on is necessary.
  • depends_on causes Terraform to create a more conservative plan. The plan may modify more resources than necessary. For example, there may be more values as unknown “(known after apply).” This is more likely to occur when creating explicit dependencies between modules.
  • Adding explicit dependencies can increase the length of time it takes to build your infrastructure. Terraform must wait until the dependency object is created before continuing.
  • It is recommended to use expression references to create implicit dependencies whenever possible.

When to use Terraform depends_on?

Terraform’s implicit dependencies mechanism is more than enough for most use cases. Usually, when you use depends_on, there is a problem with your code, rather than a need for a particular dependency. However, dependencies are required in some cases:

  • Ensuring resource configuration – You may need a resource to be fully configured before starting the creation of another one that depends on it
  • Terraform provisioners – If you are using Terraform null resources and Terraform data in conjunction with a provisioner, you will need to ensure that an instance is created before you can run a script on it
  • Enforcing creation order – If there are resources in your configuration that must be created in a particular order, you can use depends_on to enforce it
  • Workarounds – Terraform may have limitations that can only be addressed by using the depends_on block.

Terraform depends_on example use cases

Some scenarios that may require an explicit dependency include running a SQL script after a DB is created, deploying containers only after the container registry is created, or running an application on a VM instance that expects to use a specific Azure Storage Container.

This dependency is not visible to Terraform since the application’s architecture controls it. The following snippet demonstrates an explicit dependency between a VM and a storage container.

resource "azurerm_windows_virtual_machine" "vm" {
  resource_group_name      = "rg-demo"
  name                     	         = "vm-demo"
  location                              = "centralus"

  size                                = "Standard_F2"
  admin_username          = "adminuser"
  admin_password           = "P@$$w0rd1234!"
  network_interface_ids   = [
    azurerm_network_interface.nic.id,
  ]

  os_disk {
    caching                        = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  # all other relevant attributes
 
 depends_on = [
    azurerm_storage_account.st
 ]
}

resource "azurerm_storage_account" "st" {
  resource_group_name      = "rg-demo"
  name                                 = "stdemo"
  location                              = "centralus"
  account_tier                       = "Standard"
  account_replication_type   = "LRS"
  # all other relevant attributes
}

Adding multiple dependency objects

Multiple dependencies can be passed to the depends_on argument using a comma-separated list of resources.

Note: Adding explicit dependencies can increase the length of time it takes to create your infrastructure because Terraform will wait to create the dependent resource until after the specified resource is created.

The following snippet expands on the example from above and adds a second dependency, an Azure SQL Server, to the VM. This example is for illustration purposes and does not represent the best use case for creating an explicit dependency to multiple resources.

 

resource "azurerm_windows_virtual_machine" "vm" {
  # all other relevant attributes
 
 depends_on = [
    azurerm_storage_account.st,
    azurerm_mssql_server.sql
 ]
}

resource "azurerm_mssql_server" "sql" {
  resource_group_name             = "rg-demo"
  name                                        = "stdemo"
  location                                     = "centralus"
  administrator_login                   = "adminuser"
  administrator_login_password  = "P@$$w0rd1234!"
  version                                      = "12.0"
  # all other relevant attributes
}

How to use depends_on for modules in Terraform

As mentioned above, resources can have explicit dependencies on modules and vice-versa. This next example uses a module from the Terraform registry to create a VM. The module will be dependent upon the successful creation of the storage account.

module "virtual-machine" {
  source = "Azure/network/azurerm"
  resource_group_name           = "rg-demo"
  # all other relevant attributes

  depends_on = [
      azurerm_storage_account.st
  ]  
}

resource "azurerm_storage_account" "st" {
  # all other relevant attributes
}

Here’s an example of the same two resources with the dependency reversed. In this example, the storage account resource is dependent upon the VM module. Note the use of the module keyword in the dependency resource.

module "virtual-machine" {
  source = "Azure/network/azurerm"
  resource_group_name           = "rg-demo"
  # all other relevant attributes
}

resource "azurerm_storage_account" "st" {
  # all other relevant attributes
  depends_on = [module.virtual-machine]
}

Using depends_on with data sources

depends_on behaves differently with data sources than with resources. By default, Terraform reads data sources during the planning phase, before any resources are created or modified. This becomes a problem when a data source depends on a resource that doesn’t exist yet, because there’s nothing to read at plan time.

Adding depends_on to a data source forces Terraform to defer reading it until the apply phase, after the dependency has been provisioned.

resource "azurerm_storage_account" "st" {
  name                     = "stdemo"
  resource_group_name      = "rg-demo"
  location                 = "centralus"
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

data "azurerm_storage_account" "st_data" {
  name                = "stdemo"
  resource_group_name = "rg-demo"

  # Force Terraform to read this data source at apply time,
  # after the storage account has been created
  depends_on = [azurerm_storage_account.st]
}

The trade-off is that deferring a data source to apply time means its values will show as (known after apply) in your plan, reducing plan visibility. Prefer structuring your config so data sources read from already-existing infrastructure wherever possible, and treat depends_on on data sources as a last resort, consistent with how you’d use it on resources.

Terraform depends_on best practices

Terraform depends_on can be helpful in some situations, but you need to follow best practices when leveraging it:

  • Limit usage – Overuse of depends_on can lead to complex code that is difficult to troubleshoot.
  • Test your dependencies – Catch any potential issues early, to reduce the risk of problems during actual infrastructure provisioning.
  • Be specific – Avoid broad dependencies if you can use a specific one.
  • Try to use it only for workarounds – Use it for temporary workarounds for limitations or bugs in Terraform providers.
  • Document the reasoning behind using it – Specify if it is a workaround, you are ensuring resource configuration, or any other use case you may have. This will help the team understand the reason for using it.

Key points

Understanding how Terraform uses implicit and explicit dependencies helps you to determine when and how to use the depends_on meta-argument. When necessary, depends_on instructs Terraform to create and destroy resources in the correct order. Misusing the argument can lead to potentially confusing, poor-performing code.

If you need help orchestrating your infrastructure as code workflows, building complex pipelines, and managing AWS credentials per run instead of using static key pairs on local machines, Spacelift is a great fit. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more features right out of the box. You can check it for free by creating a trial account.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Terraform management made easy

Spacelift effectively manages Terraform state and more complex workflows. It supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and many more features.

Start free trial

Frequently asked questions

  • How to use dependencies in Terraform?

    Terraform manages dependencies automatically when you reference one resource’s attributes in another. This creates an implicit dependency and ensures correct ordering. To enforce execution order without direct references, use the depends_on argument to explicitly declare relationships between resources or modules.

  • What are the different types of dependencies in Terraform?

    Terraform supports two types of dependencies: implicit and explicit. Implicit dependencies are created automatically when one resource references another’s attributes, guiding Terraform’s execution order. Explicit dependencies use the depends_on argument to manually define relationships, useful when there’s no direct reference but execution order still matters.

  • Can a Terraform module depend on another module?

    A Terraform module can depend on another by referencing its outputs as inputs, creating an implicit dependency that Terraform resolves automatically. If no such reference exists but execution order is important, you can use the depends_on argument in the module block to enforce that dependency explicitly.

  • Why is depends_on not recommended in Terraform?

    Terraform automatically infers dependencies from resource references, so explicit depends_on is rarely needed. When overused, it creates hidden ordering constraints that make configurations harder to maintain and can force unnecessary resource replacements during apply. It also prevents Terraform from parallelizing operations efficiently.

  • What happens if you overuse depends_on in Terraform?

    Overusing depends_on forces Terraform to serialize operations that could otherwise run in parallel, slowing down plan and apply cycles. It also makes configurations harder to maintain, since explicit dependencies mask the implicit ones Terraform already infers from resource references.

  • Does depends_on work with data sources in Terraform?

    Yes, depends_on works with data sources in Terraform. Adding it to a data block forces Terraform to read that data source only after the listed resources or modules have been created or updated.

Terraform Project Structure
Cheat Sheet

Get the Terraform file & project structure

PDF cheat sheet.

terraform files cheat sheet bottom overlay
Share your data and download the cheat sheet