I am trying to create a nested loop to create Firewall rules in GCP. I have a locals variable that looks something like this:
local.firewall_definitions
{
"10.0.0.0/8" = [
{
"port" = "80"
"protocol" = "tcp"
},
{
"port" = "443"
"protocol" = "tcp"
},
{
"port" = "9000"
"protocol" = "udp"
},
]
"99.99.99.99/32" = [
{
"port" = "30000"
"protocol" = "tcp"
},
{
"port" = "1822"
"protocol" = "tcp"
},
{
"port" = "1823"
"protocol" = "udp"
},
]
}
What I am essentially trying to do, is to loop through this variable in 2 ways:
- Create a new
google_compute_firewallrule once for every different CIDR in this list (sometimes it may be 1, sometimes there could be 10) - Within each CIDR, loop through the variable for every port & protocol to create each
allowrule
My main.tf looks like this:
resource "google_compute_firewall" "firewalls" {
for_each = local.firewall_definitions
name = var.name
network = var.network
project = var.project
target_tags = var.targets
source_ranges = var.ranges
dynamic "allow" {
for_each = local.firewall_definitions[*]
content {
protocol = each.value[*].protocol
ports = each.value[*].port
}
}
}
The issue is (I think) that I am trying to loop through using splat, but I get errors like
each.value is tuple with 3 elements. Inappropriate value for attribute "protocol": string required.
I think this is because each.value[*].protocol currently equates to
"tcp",
"tcp",
"udp",
Whereas Terraform expects only a single protocol in string form, not a tuple of 3 elements.
Does anyone have any ideas about the correct way to achieve a nested loop?