Hey!
Versions
Terraform: 0.12.19
provider.aws: version = “3.2.0”
Background
Could I ask for a bit of guidance on the below?
We’ve started using route53 resolver to handle outbound dns from some of our VPCs.
I turned our configuration into a module which is responsible for the following resources:
- aws_route53_resolver_endpoint
- aws_route53_resolver_rule
- aws_route53_resolver_rule_association
In our AWS account, we want all of the resolver rules to get attached to all VPCs.
Some of my aws_route53_resolver_rule_association resources get recreated, this happens when either a new VPC or a new Resolver Rule are added. I think it’s down to the design of my module but wanted to clarify.
What I’m doing
The resource I’m trying to create is this one:
resource “aws_route53_resolver_rule_association” “rule_to_forwarder” {
depends_on = [aws_route53_resolver_rule.forwarder]
vpc_id = a_vpc_id
resolver_rule_id = a_resolver_rule_id
}
As we want “all_rule_ids x all_vpc_ids”, I added two data sources to get these and return a list:
data “aws_route53_resolver_rules” “all” {rule_type = “FORWARD”} ← get all forwarding rules, return a list
data “aws_vpcs” “all” {} ← get all VPC IDs, return a list
Then I created this local variable to get the cartesian product of “all_rule_ids x all_vpc_ids”, loop through and store each combination
in a map.
locals {
all_vpcs_x_all_rules = [
for pair in setproduct(data.aws_vpcs.all.ids, data.aws_route53_resolver_rules.all.resolver_rule_ids) : {
vpc_id = pair[0]
resolver_rule_id = pair[1]
}
]
}
This returns a list of maps which I can loop through in the aws_route53_resolver_rule_association resource like so:
resource “aws_route53_resolver_rule_association” “rule_to_forwarder” {
depends_on = [aws_route53_resolver_rule.forwarder]
for_each = {
for index, pair in local.all_vpcs_x_all_rules : “${index}” => pair
}vpc_id = each.value.vpc_id
resolver_rule_id = each.value.resolver_rule_id
}
Result
This configuration worked fine, when I first ran it. I recently added a new forwarder rule and the plan showed:
Plan: 46 to add, 0 to change, 38 to destroy.
The delta between 46 / 38 is 8. As I added a new forwarder rule and there are 8 VPC’s I expected the plan to show 8 to add.
So why the 38 to recreate?
Speculation
I have a couple of theories about why this might be, but not sure how to progress:
the data sources
aws_route53_resolver_rules&aws_vpcsreturn unordered lists:
this would mean the all_vpcs_x_all_rules local var would always be a bit of a mess, changing every time the configuration was run. I don’t think this is true because running the job without adding a new resolver_rule_id has always been stable (no changes).
the data sources
aws_route53_resolver_rules&aws_vpcsreturn ordered lists, but the new resolver rule ID could be anywhere in that list
for example say I have: rule_id_1, rule_id_3 and vpc_x
- the module creates two attachments and stores in terraform state like this:
rule_id_1:vpc_x[0]
rule_id_3:vpc_x[1]
- then I add a new rule, called rule_id_2
- the module creates:
rule_id_1:vpc_x[0]
rule_id_3:vpc_x[1] → rule_id_2:vpc_x[1] #forces replacement
rule_id_3:vpc_x[2]
Judging by it’s behaviour I think the latter is closer but I’m clutching a bit!
Any help is appreciated!