Techdecline's Blog

How to make sense of Terraform's for_each index

TL;DR

Using a map's key for indexing is not always preferred from a maintainability standpoint. Therefore, considering using the map's value is often a viable option.

Problem Statement

When iterating over a list of objects in Terraform using for_each there is a pattern of using the index as an identifier as shown in this snippet:

resource "null_resource" "compile_dsc_configuration" {
  for_each = {for k, v in local.dsc_configuration_data_path[*].data_file_path : k => v}
  provisioner "local-exec" {
    command = ". ./Invoke-AzDscCompilationJob.ps1 -AutomationAccountName ${var.aa_name} -ResourceGroupName ${var.aa_resource_group_name} -ConfigurationName SqlServerNode -ConfigurationDataPath ${each.value}"
    interpreter = [
      "pwsh", "-command"
    ]
  }
}

This pattern will result in state references where the object in question is not easy to identify hen running state operations like taint or import:

terraform taint null_resource.compile_dsc_configuration["0"] # I have no clue which configuration will be tainted

Using the Value as Identifier

Alternatively, you can use a value (or a transposed version of it):

resource "null_resource" "compile_dsc_configuration" {
  for_each = {for k, v in local.dsc_configuration_data_path[*].data_file_path : "${replace(basename(v), ".psd1", "")}" => v}
  provisioner "local-exec" {
    command = ". ./Invoke-AzDscCompilationJob.ps1 -AutomationAccountName ${var.aa_name} -ResourceGroupName ${var.aa_resource_group_name} -ConfigurationName SqlServerNode -ConfigurationDataPath ${each.value}"
    interpreter = [
      "pwsh", "-command"
    ]
  }
}

Here, the loop will use a configuration data file name as index which makes it a lot easier to work with the resulting state:

terraform taint null_resource.compile_dsc_configuration["prod-vm"] # I will recompile the configuration for my prod-vm

Conclusion

I will try to update my internal wiring to use the updated pattern more often, as I struggled a lot in the past making sense of a loop's index.

For more content on Azure DSC with Terraform, hit me up on LinkedIn or Mastodon.

#Azure #DSC #Terraform