Home > Net >  How to use depends_on in terraform if resources are created using count or for_each
How to use depends_on in terraform if resources are created using count or for_each

Time:12-23

Hello How to use depends_on in the cases of count or for_each.

The basic syntax of depends_on assumes

resource "azurerm_storage_container" "cont1"{
.....
.....
depends_on = [
    azurerm_storage_account.storageAccount
 ]
}
 
resource "azurerm_storage_account" "storageAccount" {
  count                   = 3
  name                    = "storageAccountName-${count.index}"
  resource_group_name     = "rg-demo"
  location                = "centralus"
  account_tier            = "Standard"
  account_replication_type= "LRS"
  # all other relevant attributes
}

So here its azurerm_storage_account.storageAccount if only one such resource were to be created but if we have many azurerm_storage_account created as for_each or count was used in them then what to write in place of storageAccount? Like suppose we have to have a dependency of storageAccountName-2 on the container then how will we write the depends on?

CodePudding user response:

As was mentioned in a comment above, you can add an index to the storageAccount resource reference:

resource "azurerm_storage_account" "test_storage_account" {
  count                    = 3
  name                     = "teststorageaccount${count.index}"
  ...
}

resource "azurerm_storage_container" "container" {
  depends_on = [
    azurerm_storage_account.test_storage_account[0]
  ]
  name                  = "testcontainer"
  ...
}

You can also omit the index and have the container(s) depend on the entire storage account resource. Both worked in my testing.

Additionally, while implicit dependency would normally allow you to not have a "depends_on" block in the container resource (if you had a single storage account), the implicit dependency does not appear to work when you have multiple storage accounts created with a "for_each" that are later referenced in a storage container resource.

CodePudding user response:

Dependencies in Terraform are only between static blocks, not between individual instances declared by those blocks. This is because the count and for_each expressions themselves can have dependencies, and so Terraform must build the dependency graph before calculating which instances will exist for each resource or module.

Therefore using count and for_each for a resource changes nothing about how you would create dependencies for the resource.

As usual, the most common way to create a dependency is to just refer to the resource in at least one of the arguments of another resource. That creates a dependency automatically, so you don't need depends_on at all:

resource "azurerm_storage_account" "example" {
  count = 3

  # ...
}

resource "azurerm_storage_container" "example" {
  # the azurerm_storage_account.example part of the following
  # expression creates a dependency, regardless of what
  # else this expression does.
  count = length(azurerm_storage_account.example)

  # ...
}

The depends_on argument is needed only for situations where a remote API design causes there to be "hidden dependencies" that Terraform can't discover automatically by noticing your references.

One way that could be true with the resource types you showed here is if you are writing a shared module that declares both of these resources and then exports the storage account IDs as an output value. In that case you may wish to tell Terraform that the output value also depends on the storage container, which would represent that the storage account isn't actually ready to use until the storage container has been created:

output "storage_account_ids" {
  value = toset(azurerm_storage_account.example[*].id)

  # The storage accounts are not ready to use
  # until their containers are also ready.
  depends_on = [azurerm_storage_container.example]
}

Notice that depends_on refers to just azurerm_storage_container.example, because Terraform only tracks dependencies on whole resources.

Although it is syntactically valid to write an instance ID here -- for example, you could declare a dependency on azurerm_storage_container.example[0] and Terraform would accept it -- Terraform will just ignore the [0] part and create a dependency on the whole resource anyway. The [0] suffix makes absolutely no difference to Terraform's behavior.

  • Related