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!
Terraform doesn't support if-statements, so this code won't work. However, you can accomplish the same thing by using the count parameter and taking advantage of two properties: If you set count to 1 on a resource, you get one copy of that resource; if you set count to 0, that resource is not created at all.
What is count in Terraform? When you define a resource block in Terraform, by default, this specifies one resource that will be created. To manage several of the same resources, you can use either count or for_each , which removes the need to write a separate block of code for each one.
The fields which have known only after apply is not an error, but just informs the user that these fields only get populated in terraform state after its applied. The dependency order is handled by Terraform and hence referring values (even those which have known only after apply ) will be resolved at run time. Thanks.
Using the count meta-argument The count meta-argument is the simplest of the looping constructs within Terraform. By either directly assigning a whole number or using the length function on a list or map variable, Terraform creates this number of resources based on the resource block it is assigned to.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With