
Terraform lets you declare dependencies between resources, and even between data sources. There are two kinds:
Either way, a dependency stops Terraform from creating a resource before the thing it needs already exists. The rest of this post walks through an example of each.
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 this reference and creates a dependency for us in the resource graph between those particular resources.
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
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
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" {
│We've seen implicit dependencies in action. Here's how explicit ones work. We'll reuse the example from above, which is currently broken because it has no dependencies in place, and fix it with explicit dependencies.
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)

We've looked at the two ways to declare dependencies in Terraform code. Implicit dependencies come from referencing one resource or data source inside another. Explicit ones use the depends_on block to tell Terraform about a dependency directly. Both make sure resources are created in the right order, whether the reason is technical or a business constraint. It's one more thing that makes Terraform a capable infrastructure-as-code tool.
