Skip to content

fix(dns): ignore vpc changes on private_zone for cross-account assoc#398

Merged
fedemaleh merged 1 commit into
mainfrom
fix/r53-private-zone-ignore-vpc-changes
Jun 19, 2026
Merged

fix(dns): ignore vpc changes on private_zone for cross-account assoc#398
fedemaleh merged 1 commit into
mainfrom
fix/r53-private-zone-ignore-vpc-changes

Conversation

@fedemaleh

Copy link
Copy Markdown
Contributor

Problem

The aws_route53_zone.private_zone resource in infrastructure/aws/dns/main.tf declares a single inline vpc {} block but no lifecycle.ignore_changes. Any VPC association created on the zone outside of this block — for example via a standalone aws_route53_zone_association resource in another AWS account (the hub side of a hub-and-spoke setup) — is detected as drift on every refresh, and the next tofu apply calls DisassociateVPCFromHostedZone against it.

For consumers that authorize a hub VPC via aws_route53_vpc_association_authorization and let the hub account create the actual association via aws_route53_zone_association, this produces a perpetual diff in the zone-owning account and a yo-yo of disassociate/reassociate calls between layers — with a brief window of broken cross-account DNS resolution on every cycle.

Fix

Add lifecycle { ignore_changes = [vpc] } to the private_zone resource. The inline vpc {} block is still required at creation time (AWS rejects a private zone with zero VPC associations), but Tofu no longer tries to reconcile the set of associations on subsequent refreshes. Additional associations are then managed externally via aws_route53_zone_association resources (in the same or other accounts).

Why this is safe

This is the pattern explicitly documented by the AWS Terraform provider on the aws_route53_zone_association reference page:

Terraform provides both this standalone Zone VPC Association resource and exclusive VPC associations defined in-line in the aws_route53_zone resource via vpc configuration blocks. At this time, you cannot use those in-line VPC associations in conjunction with this resource and the same zone ID otherwise it will cause a perpetual difference in plan output. You can optionally use the generic Terraform resource lifecycle configuration block with ignore_changes in the aws_route53_zone resource to manage additional associations via this resource.

Source: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association

The provider's own example code on that page uses the exact pattern this PR applies.

Impact on existing consumers

  • Single-account consumers that never add associations outside of the module: no behavior change — the inline vpc {} still controls the initial association, and there are no external associations to ignore.
  • Multi-account / hub-and-spoke consumers: drift goes away, no more spurious destroys of cross-account associations.
  • Drift detection for unauthorized VPC associations added out-of-band: lost. This is the documented trade-off; the recommended way to surface unauthorized associations is through CloudTrail / Config rules, not Tofu plan output.

Context

Hit on accounts/galicia-3/infrastructure/aws/ in the Banco Galicia POC, where the canonical account is associated to a central Hub VPC (galicia-hub) via aws_route53_vpc_association_authorization + aws_route53_zone_association. Without this fix, every tofu plan in galicia-3 proposes disassociating the hub VPC from galicia-3-poc.nullapps.io, which would break Route53 Resolver lookups from the hub.

Test plan

  • tofu fmt -check -recursive on the dns module — passes (already verified locally).
  • Existing module tests under infrastructure/aws/dns/tests/ still pass.
  • Downstream apply on galicia-3/infrastructure/aws/ no longer proposes the ~ vpc {} destroy on aws_route53_zone.private_zone after the source ref is bumped to a release containing this change.

@fedemaleh fedemaleh merged commit 772c201 into main Jun 19, 2026
44 checks passed
@fedemaleh fedemaleh deleted the fix/r53-private-zone-ignore-vpc-changes branch June 19, 2026 17:47
This was referenced Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants