Terraform - Understanding Implicit and Explicit Dependencies

pwd9000

Marcel.L

Posted on February 14, 2024

Terraform - Understanding Implicit and Explicit Dependencies

Overview

When working with Terraform, it is important to understand the difference between implicit and explicit dependencies. This is important as it can help you to understand how Terraform creates the dependency graph and how it determines the order in which resources are created.

What Are Dependencies in Terraform?

Dependencies in Terraform dictate the order in which resources are created, updated, or destroyed. Terraform automatically determines dependencies between your resources, ensuring that they are managed in the correct sequence.

Implicit Dependencies

Implicit dependencies are automatically discovered by Terraform by analysing resource attributes. When one resource refers to another using interpolation syntax, Terraform recognises this as a dependency.

In other words, implicit dependencies in Terraform are created when one resource property references another resource's property or output. Terraform uses these references to automatically determine the order of resource creation.

Consider this example involving an Azure virtual network and a subnet:



resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"
}

resource "azurerm_virtual_network" "example_vnet" {
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "example_subnet" {
  name                 = "example-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example_vnet.name
  address_prefixes     = ["10.0.1.0/24"]
}


Enter fullscreen mode Exit fullscreen mode

In this example, the azurerm_subnet resource has an implicit dependency on the azurerm_virtual_network resource. This is because the virtual_network_name property of the azurerm_subnet resource references the name property of the azurerm_virtual_network resource. Terraform automatically recognises this and creates the dependency.

Explicit Dependencies

Sometimes, however, the relationship between resources is not captured by direct references. In these instances, you can use the depends_on attribute to create an explicit dependency.

Explicit dependencies should only be defined when Terraform can't automatically infer the required order for resource creation, or when specific provisioning steps are necessary before or after a resource is deployed.

Let's illustrate an explicit dependency in a scenario where an Azure App Service depends on certain configuration settings that are applied via an Azure CLI script after the creation of an Azure Key Vault.

Here's a simple Terraform configuration demonstrating this relationship:



resource "azurerm_resource_group" "example_rg" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_key_vault" "example_kv" {
  name                        = "exampleKeyVault"
  location                    = azurerm_resource_group.example_rg.location
  resource_group_name         = azurerm_resource_group.example_rg.name
  tenant_id                   = "00000000-0000-0000-0000-000000000000"
  sku_name                    = "standard"

  soft_delete_enabled         = true
  purge_protection_enabled    = false
}

resource "null_resource" "example_kv_settings" {
  # Dummy example of an Azure CLI script command that sets configuration in the Key Vault
  provisioner "local-exec" {
    command = "echo Configuring Key Vault Settings"
  }

  # Explicitly state that the Key Vault settings should be applied after the Key Vault is created
  depends_on = [ azurerm_key_vault.example_kv ]
}

resource "azurerm_app_service" "example_app_service" {
  name                = "example-appservice"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  app_service_plan_id = azurerm_app_service_plan.example_asp.id

  # Explicitly state the dependency on the Key Vault settings to ensure these are set before creating the App Service
  depends_on = [ null_resource.example_kv_settings ]
}

resource "azurerm_app_service_plan" "example_asp" {
  name                = "example-asp"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name

  sku {
    tier = "Standard"
    size = "S1"
  }
}


Enter fullscreen mode Exit fullscreen mode

In the above example:

  1. azurerm_resource_group.example_rg creates a resource group.
  2. azurerm_key_vault.example_kv creates the Azure Key Vault.
  3. null_resource.example_kv_settings represents a hypothetical Azure CLI script that configures settings in the Key Vault (replaced with an echo command for simplicity). The depends_on ensures the Key Vault is in place before the configuration script runs.
  4. azurerm_app_service_plan.example_asp sets up the required App Service Plan.
  5. azurerm_app_service.example_app_service creates the App Service with a depends_on pointing to null_resource.example_kv_settings. This explicit dependency ensures that the App Service is only provisioned after the Key Vault settings have been applied by the script.

By using depends_on, we establish an explicit dependency chain: Resource Group -> Key Vault -> Key Vault Settings -> App Service. This ensures the resources are provisioned in the correct order, even though the dependencies aren't apparent from the resource attributes alone.

When to Use Implicit vs. Explicit Dependencies

Implicit dependencies should be your first go-to in Terraform since they are automatically detected, and Terraform handles the ordering for you. However, there are cases when Terraform cannot discern the right order, or you have custom steps in your provisioning process which can warrant the use of explicit dependencies with the depends_on attribute.

To minimise potential issues:

  • Rely mostly on implicit dependencies through resource attribute references.
  • Only use explicit dependencies when necessary, and keep them to a minimum to avoid tightly coupled architecture.
  • Always document why an explicit dependency is required to help other developers understand the rationale behind it.

Conclusion

Grasping the concept of implicit and explicit dependencies and applying that knowledge to Azure resources with Terraform will lead to smoother deployments and a more robust infrastructure.

Author

Like, share, follow me on: 🐙 GitHub | 🐧 X/Twitter | 👾 LinkedIn

💖 💪 🙅 🚩
pwd9000
Marcel.L

Posted on February 14, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related