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
}
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
}
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]
}
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)