terraformterraform-loop

Terraform for_each with condition and key removal


I need to find a way to specify a for_each resource creation where dynamically I use a specific map AND at the same time, remove an item/key or skip an item in that map.

I currently us the following for_each to specify which map to use for iteration:

for_each = (var.subnet_size == "large" ? var.subnet_map_large : var.subnet_map_small)

at the same time, I need to skip a key when the key is "AppGatewaySubnet" since there I can't apply a network security group.

I found a snippet for that purpose but have no clue how to integrate it with what I have. Here is the snippet:

for_each = { for k in compact([for k, v in var.mymap: v.condition ? k : ""]): k => var.mymap[k] }

It is assumed that the var.mymap has a boolean for the condition like:

variable "mymap" {
    type = map(object({
        attribute = string
        condition = bool
    }))

Perhaps I can state my problem in a different way. I do not know how to create a for_each expression where I accomplish the following pseudo code: for_each {if the var.subnet_size variable is equal to "large", then use the subnet_map_large, otherwise use the subnet_map_small, AND if the value "Add_NSG" is FALSE for any key in the chosen map, then skip that key}

An alternative would be: for_each {if the var.subnet_size variable is equal to "large", then use the subnet_map_large, otherwise use the subnet_map_small, AND if the key is "AppGatewaySubnet" in the chosen map, then skip that key}


Solution

  • While I was used to SQL as a declarative language, I found Terraform somewhat unfamiliar. I then just cobbled it together as I would in SQL and voila, it worked. Here is my solution to loop through all keys that are deemed "enabled":

      for_each = {
        for k, v in(var.subnet_size == "large" ? var.subnet_map_large : var.subnet_map_small) : k => v
        if contains(var.nsg_enabled, k)
      }
    

    This is based on the var.nsg_enabled being a list having keys that are the names of subnets where I want a network security group like:

    variable "nsg_enabled" {
      type    = list(string)
      default = ["LB-NAT", "Front-Free1", "Front-Free2", "Data", "Free", "Backend", "API"]
    }