DEV Community

Paul Delcogliano
Paul Delcogliano

Posted on • Originally published at spacelift.io

How to Use Terraform `depends_on`

In this article you will learn why and how to use Terraform's depends_on meta-argument.

Resource Dependencies

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
}
Enter fullscreen mode Exit fullscreen mode

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", and 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.

What is Terraform depends_on

In the majority of 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 depends_on meta-argument. depends_on allows you to create an explicit dependency between two resources.

Dependencies are not limited to just resources. Dependencies 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 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 because Terraform must wait until the dependency object is created before continuing.

  • It is recommended to use expression references to create implicit dependencies whenever possible.

Use Cases for depends_on

Some scenarios that may require the use of an explicit dependency include running a SQL script after a DB is created, deploying containers only after the container registry is created, or you have an application running 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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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]
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)