Terraform - if within for_each. Can I filter for_each?

Viewed 5415

With the following I can loop through a resource block to add route table associations to "all" of my subnets easily. However I need to create associations only for my public subnets.

How can I make this "if" statement work? Or any other way to filter on each.value.class == "pub" for that matter.

resource "aws_route_table_association" "rtb-pub" {
  for_each =  local.subnets_map 
  if each.value.class == "pub"    ## <---- how?

  route_table_id = aws_route_table.rtb-pub.id
  subnet_id      = aws_subnet.map["${each.value.subnet}"].id
}

Thanks in advance!

2 Answers

It depends on exactly what is the structure of your local.subnets_map. But the for_each should be something like the following one:

resource "aws_route_table_association" "rtb-pub" {

  for_each =  {for key, val in local.subnets_map: 
               key => val if val.class == "pub"}

  route_table_id = aws_route_table.rtb-pub.id
  subnet_id      = aws_subnet.map["${each.value.subnet}"].id
}

One weakness of the for loop filtering is that AFAIK you are stuck with a single match value.

If you need to filter for multiple values in the map or list, try the matchkeys() function: https://www.terraform.io/docs/language/functions/matchkeys.html

When using a map, you'll need to use the keys() and values() functions to supply the list parameters:

local {
users = { user1 = "value1", user2 = "value2", user3 = "value3", user4 = "value4" }
}

output user_subset {
  value = matchkeys(values(local.users), keys(local.users), ["user1", "user3"])
}

The resulting output can be used in a for_each loop in a resource block. In this example case I'd use it to add the subset of users to a group.

Related