I’m using a module to create a list of maps for me to iterate over:
module "regions" {
source = "hashicorp/subnets/cidr"
base_cidr_block = "1.2.0.0/23"
networks = [
{
name = "in-use-us-east1"
new_bits = 5
},
{
name = "in-use-us-west1"
new_bits = 5
},
{
name = "in-use-us-west4"
new_bits = 5
},
{
name = "in-use-us-central1"
new_bits = 5
},
{
name = "not-in-use"
new_bits = 1
},
]
}
module.regions creates an object that looks like this:
+ regions = {
+ base_cidr_block = "1.2.0.0/23"
+ network_cidr_blocks = {
+ "not-in-use" = "1.2.1.0/24"
+ "in-use-us-central1" = "1.2.0.32/28"
+ "in-use-us-east1" = "1.2.0.48/28"
+ "in-use-us-west1" = "1.2.0.0/28"
+ "in-use-us-west4" = "1.2.0.16/28"
}
+ networks = [
+ {
+ cidr_block = "1.2.0.0/28"
+ name = "in-use-us-west1"
+ new_bits = 5
},
+ {
+ cidr_block = "1.2.0.16/28"
+ name = "in-use-us-west4"
+ new_bits = 5
},
... etc
I’m looping over the object like this:
resource "google_compute_global_address" "regions" {
for_each = {for subnet in module.regions.networks: subnet.name => subnet}
provider = google-beta
name = each.value.name
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = split("/", each.value.cidr_block)[1]
address = split("/", each.value.cidr_block)[0]
project = local.project_id
network = google_compute_subnetwork.my_vpc.network
}
All of this works great and does everything I want with one exception.
How do I exclude a key from the set?
I only want to loop over objects where subnet.name does not start with not-in-use.
Is this possible? I’m so close, I really don’t want to have to reshape the whole thing in a new var in globals when I’m 90% of the way there. This is also very readable too.
I tried the following:
for_each = {for subnet in module.regions.networks: subnet.name => subnet if regexall("^in-use", subnet.name)}
But that throws an error:
Error: Invalid 'for' condition
The 'if' clause value is invalid: bool required.
I also tried wrapping regexall() in length() and that returned the same error.
>Solution :
I am somewhat hesitant to answer this because you almost completely did it yourself, but I will supply the final piece. While it is possible to do this with the regex function (it returns a bool whereas regexall returns a list which led to your error message since a bool is required for a conditional logical return), it would be even easier in your situation to use the startswith function:
for_each = {for subnet in module.regions.networks: subnet.name => subnet if startswith(subnet.name, "in-use")}