Multiple for_each

Im trying to see if its possible to run multiple for_each loops in one resource.

using the azurerm_private_dns_zone_virtual_network_link I have to pass in the name of the network id I want to create the link for.

Im already calling the module with a foreach, from the azurerm_private_dns_zone.

So what im trying to do, is create a dns zone virtual link, for each DNS Zone I’ve created (in the azurerm_private_dns_zone) and for each virtual network I want to link it to.

I tried passing a list, converting it to string, but it just combines the list elements together.

Not sure if what im trying is possible

`resource "azurerm_private_dns_zone_virtual_network_link" "dns_vnet_link" {
  for_each = azurerm_private_dns_zone.prv_dns_zone

  name = "${each.value.name}-vnet-link"
  resource_group_name = var.resource_group_name
  #virtual_network_id = [for vnet_id in var.vnet_id : format("%s", vnet_id)]
  virtual_network_id = "${join(", ", [for vnet_id in var.vnet_id : format("%s", vnet_id)])}"
  private_dns_zone_name = each.value.name

  lifecycle {
        ignore_changes = [tags]
    }
}`

If I just pass one element in the list the above works, but just for one virtual network id.

Im thinking im going to need to use a local to create an object that contains the values I need and then pass them onto the resource…

Hi @deniscooper,

The general rule for for_each is that you must provide a mapping that has one element per instance you want to declare, because Terraform will use the map keys as part of the unique identifiers for each of the instances.

Therefore a different way to ask this question is to ask how one might combine two or more collections together to produce a single collection with one element per instance.

There are two common patterns which many of these different requirements fall into:

  • flatten can help turn nested structures into flattened structures.
  • setproduct finds all of the possible selections of elements from two or more sets.

I think the situation you’re describing is a “setproduct-shaped” problem, because you are trying to declare an instance of this resource for every unique combination of one DNS zone and one virtual network. The subsection of that documentation Finding combinations for for_each has a worked example of declaring subnets of multiple networks, and I think the solution you need will have a similar shape to that one.

2 Likes

Thank you for the prompt and detailed response. I’ve had a quick read over and setproduct looks like exactly what I need.

Thank you