TrademarkTrademark
Features
Documentation
  1. Learning Center
  2. The Developer's Guide to HCL

Article · part of a guide

Terraform Resource Dependencies Explained

Terraform can declare dependencies between resources, and even data sources. Here's how implicit and explicit dependencies work.

Terraform Resource Dependencies Explained

Key takeaways

  1. Terraform dependencies come in two forms: implicit, where a resource references another resource or data source, and explicit, declared with depends_on.
  2. Implicit dependencies form automatically when one resource references another's attributes, and Terraform builds them into the resource graph to control creation order.
  3. Replacing references with hard-coded values removes implicit dependencies, causing Terraform to create resources at the same time and fail when one depends on another not yet created.
  4. The depends_on block lets engineers explicitly declare dependencies between resources or data sources for technical or business reasons.
  5. Dependencies ensure resources are created in the correct order, which is a core part of Terraform's power as an infrastructure-as-code tool.

Terraform lets you declare dependencies between resources, and even between data sources. There are two kinds:

  • Implicit - where a resource references another resource/data source
  • Explicit - where an engineer explicitly calls out a dependency between two resources/data sources

Either way, a dependency stops Terraform from creating a resource before the thing it needs already exists. Below is an example of each.

How Do Implicit Dependencies Work in Terraform?

The example below creates three resources that depend on each other: a Resource Group, a Virtual Network, and a Subnet. In the code, each one references the others in some way. The Virtual Network references the Resource Group twice, once for its location and once for its name.

Terraform sees that reference and adds a dependency between those resources in the resource graph.

resource "azurerm_resource_group" "this" {
  name     = "rg-implicit-dependency"
  location = "Australia East"
}
 
resource "azurerm_virtual_network" "this" {
  name                = "vn-implicit-dependency"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
 
  address_space = ["10.0.0.0/24"]
}
 
resource "azurerm_subnet" "this" {
  name                 = "sn-implicit-dependency"
  resource_group_name  = azurerm_resource_group.this.name
  virtual_network_name = azurerm_virtual_network.this.name
 
  address_prefixes = ["10.0.0.0/28"]
}

The diagram below is the output of the terraform graph command piped into https://github.com/pcasteran/terraform-graph-beautifier. Now you can see those references between each resource.

Output of the terraform graph

Output of the terraform graph

To prove the point, let's change the code so it uses hard-coded values instead of references. The code now looks like this:

resource "azurerm_resource_group" "this" {
  name     = "rg-implicit-dependency"
  location = "Australia East"
}
 
resource "azurerm_virtual_network" "this" {
  name                = "vn-implicit-dependency"
  location            = "Australia East"
  resource_group_name = "rg-implicit-dependency"
 
  address_space = ["10.0.0.0/24"]
}
 
resource "azurerm_subnet" "this" {
  name                 = "sn-implicit-dependency"
  resource_group_name  = "rg-implicit-dependency"
  virtual_network_name = "vn-implicit-dependency"
 
  address_prefixes = ["10.0.0.0/28"]
}

If we run the terraform graph command again we get a completely different result! As you can see below, we no longer have those dependencies marked by arrows in the resource graph.

Resources without dependencies

Resources without dependencies

With this configuration Terraform will try to create all three resources at the same time. You can limit that with the parallelism command line option for apply, but it'll still error out. The example below shows that the Virtual Network can't find the Resource Group we're referencing.

╷
│ Error: creating/updating Virtual Network: (Name "vn-implicit-dependency" / Resource Group "rg-implicit-dependency"): network.VirtualNetworksClient#CreateOrUpdate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceGroupNotFound" Message="Resource group 'rg-implicit-dependency' could not be found."
│ 
│   with azurerm_virtual_network.this,
│   on main.tf line 10, in resource "azurerm_virtual_network" "this":
│   10: resource "azurerm_virtual_network" "this" {
│

How Do You Declare Explicit Dependencies with depends_on?

Now for explicit dependencies. We'll reuse the example from above, which is broken because it has no dependencies in place, and fix it with explicit ones.

resource "azurerm_resource_group" "this" {
  name     = "rg-explicit-dependency"
  location = "Australia East"
}
 
resource "azurerm_virtual_network" "this" {
  name                = "vn-explicit-dependency"
  location            = "Australia East"
  resource_group_name = "rg-explicit-dependency"
 
  address_space = ["10.0.0.0/24"]
 
  depends_on = [
    azurerm_resource_group.this
  ]
}
 
resource "azurerm_subnet" "this" {
  name                 = "sn-explicit-dependency"
  resource_group_name  = "rg-explicit-dependency"
  virtual_network_name = "vn-explicit-dependency"
 
  address_prefixes = ["10.0.0.0/28"]
 
  depends_on = [
    azurerm_resource_group.this,
    azurerm_virtual_network.this
  ]
}

Each resource now has a new block called depends_on. It lets us, as engineers, call out explicit dependencies between resources or data sources. Instead of references, the example uses the literal names of the Resource Group and Virtual Network. In a real setup these would more likely be input variables passed in. This also helps when two services depend on each other for a business reason rather than a technical one.

The below screenshot shows what our graph will look like when we use the depends_on. (I promise it's not copy paste from above)

Terraform graph showing explicit dependencies using depends_on block

Why Do Resource Dependencies Matter in Terraform?

Implicit dependencies come from referencing one resource or data source inside another, and explicit ones come from the depends_on block. Either way, Terraform creates resources in the right order, whether the reason is technical or a business constraint. Without either, as the hard-coded example showed, Terraform tries to create everything at once and the apply fails.

About the author

Brendan Thompson

solutions engineer at Scalr

Brendan Thompson is a solutions engineer at Scalr, specializing in Terraform and cloud infrastructure.

Part of this guide

9 sheets

The Developer's Guide to HCL

8 articles