How to trace through who is creating hosted zones?

Hi @deantray,

terraform graph is primarily a learning/teaching tool and it doesn’t really scale very well for non-trivial configurations, since the graphviz automatic layout has a very hard time with graphs that contain lots of nodes or lots of edges.

With that said, the snippets from its output you’ve shared are describing three separate resources:

  • module.ecs_backend.data.aws_route53_zone.public_zone
  • module.route53_private_tray_domain.module.route53_hosted_zone.aws_route53_zone.public_zone
  • module.route53_public_tray_domain.module.route53_hosted_zone.aws_route53_zone.public_zone

The first one is a data.aws_route53_zone and so is a data resource rather than a managed resource, so I think you can ignore that one for the sake of what you’re asking here – it’s just fetching the data about some existing Route53 Zone, rather than declaring a new one.

If you intend there to be only one Route53 Zone managed by this configuration then I think those second two are the main point of concern: you seem to have you route53_private_tray_domain and route53_public_tray_domain both making separate calls to a “route53_hosted_zone” module; I’m guessing they are both calling the same module source since they both seem to have resource "aws_route53_zone" "public_zone" blocks inside.

I assume this is the same configuration we were just discussing over here:

If so, and if you intend to share the same Route53 Zone across all three of these modules ecs_backend, route53_private_tray_domain, and route53_public_tray_domain, then I would suggest moving the module "route53_hosted_zone" block up into the root module, as a sibling of the other three, and then pass its resulting zone into the other three modules.

In the other topic I discussed the idea of using an object type that’s a subset of a resource type as an input variable. You can also do a similar thing in an output value when data is flowing in the opposite direction, though of course in this case you must be the one to define how to construct the needed subset:

output "zone" {
  value = {
    name    = aws_route53_zone.public_zone.name
    zone_id = aws_route53_zone.public_zone.zone_id
    arn     = aws_route53_zone.public_zone.arn
  }
}

Terraform will also let you just return the entire resource instance object as the value if you want – value = aws_route53_zone.public_zone – but I find I typically want to be more selective in what I’m exposing because otherwise the result the caller sees can be affected by what version of the AWS provider you’re using, and that can be a surprising extra dependency.

As long as the object you return in the output value has attributes that are a superset of what the input variable expects, you can assign the output value directly to the input variable, instead of assigning the resource object itself:

module "example" {
  # ...

  route53_zone = module.route53_hosted_zone.zone
}