From 1adc5912b4667161fd2e11072dc5ad9810a37b07 Mon Sep 17 00:00:00 2001 From: Mike Carey <32496966+mike-carey@users.noreply.github.com> Date: Mon, 28 Apr 2025 17:55:58 -0500 Subject: [PATCH 1/3] feat: Skip zone data source lookup in records module --- examples/complete/README.md | 1 + examples/complete/main.tf | 11 +++++++++++ modules/records/README.md | 1 + modules/records/main.tf | 13 +++++++++---- modules/records/variables.tf | 6 ++++++ 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/examples/complete/README.md b/examples/complete/README.md index 76f3e9e..1176670 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -44,6 +44,7 @@ Note that this example may create resources which cost money. Run `terraform des | [outbound\_resolver\_endpoints](#module\_outbound\_resolver\_endpoints) | ../../modules/resolver-endpoints | n/a | | [records](#module\_records) | ../../modules/records | n/a | | [records\_with\_full\_names](#module\_records\_with\_full\_names) | ../../modules/records | n/a | +| [records\_without\_zone\_lookup](#module\_records\_without\_zone\_lookup) | ../../modules/records | n/a | | [resolver\_rule\_associations](#module\_resolver\_rule\_associations) | ../../modules/resolver-rule-associations | n/a | | [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | n/a | | [terragrunt](#module\_terragrunt) | ../../modules/records | n/a | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 5d7fe55..a040b5a 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -249,6 +249,17 @@ module "records" { depends_on = [module.zones] } +module "records_without_zone_lookup" { + source = "../../modules/records" + + # When skip_zone_lookup is set to true, zone_id and zone_name must be provided + skip_zone_lookup = true + zone_id = module.zones.route53_zone_zone_id["private-vpc.terraform-aws-modules-example2.com"] + zone_name = module.zones.route53_zone_name["private-vpc.terraform-aws-modules-example2.com"] + + # Note that private_zone is not needed here because we are setting skip_zone_lookup to true +} + module "terragrunt" { source = "../../modules/records" diff --git a/modules/records/README.md b/modules/records/README.md index 47d3183..abc5872 100644 --- a/modules/records/README.md +++ b/modules/records/README.md @@ -59,6 +59,7 @@ No modules. | [private\_zone](#input\_private\_zone) | Whether Route53 zone is private or public | `bool` | `false` | no | | [records](#input\_records) | List of objects of DNS records | `any` | `[]` | no | | [records\_jsonencoded](#input\_records\_jsonencoded) | List of map of DNS records (stored as jsonencoded string, for terragrunt) | `string` | `null` | no | +| [skip\_zone\_lookup](#input\_skip\_zone\_lookup) | Whether to skip zone lookup. If set to true, zone\_id and zone\_name must be provided | `bool` | `false` | no | | [zone\_id](#input\_zone\_id) | ID of DNS zone | `string` | `null` | no | | [zone\_name](#input\_zone\_name) | Name of DNS zone | `string` | `null` | no | diff --git a/modules/records/main.tf b/modules/records/main.tf index 0de5992..902b73e 100644 --- a/modules/records/main.tf +++ b/modules/records/main.tf @@ -5,10 +5,15 @@ locals { # Convert `records` from list to map with unique keys recordsets = { for rs in local.records : try(rs.key, join(" ", compact(["${rs.name} ${rs.type}", try(rs.set_identifier, "")]))) => rs } + + zone_id = var.zone_id != null ? var.zone_id : data.aws_route53_zone.this[0].zone_id + zone_name = var.zone_name != null ? var.zone_name : data.aws_route53_zone.this[0].name } data "aws_route53_zone" "this" { - count = var.create && (var.zone_id != null || var.zone_name != null) ? 1 : 0 + # Since terraform does not short ciruit, we will use lazy evaluation to avoid + # > The "count" value depends on resource attributes that cannot be determined until apply + count = var.skip_zone_lookup ? 0 : var.create && (var.zone_id != null || var.zone_name != null) ? 1 : 0 zone_id = var.zone_id name = var.zone_name @@ -18,9 +23,9 @@ data "aws_route53_zone" "this" { resource "aws_route53_record" "this" { for_each = { for k, v in local.recordsets : k => v if var.create && (var.zone_id != null || var.zone_name != null) } - zone_id = data.aws_route53_zone.this[0].zone_id + zone_id = local.zone_id - name = each.value.name != "" ? (lookup(each.value, "full_name_override", false) ? each.value.name : "${each.value.name}.${data.aws_route53_zone.this[0].name}") : data.aws_route53_zone.this[0].name + name = each.value.name != "" ? (lookup(each.value, "full_name_override", false) ? each.value.name : "${each.value.name}.${local.zone_name}") : local.zone_name type = each.value.type ttl = lookup(each.value, "ttl", null) records = try(each.value.records, null) @@ -34,7 +39,7 @@ resource "aws_route53_record" "this" { content { name = each.value.alias.name - zone_id = try(each.value.alias.zone_id, data.aws_route53_zone.this[0].zone_id) + zone_id = try(each.value.alias.zone_id, local.zone_id) evaluate_target_health = lookup(each.value.alias, "evaluate_target_health", false) } } diff --git a/modules/records/variables.tf b/modules/records/variables.tf index d3581be..5535869 100644 --- a/modules/records/variables.tf +++ b/modules/records/variables.tf @@ -4,6 +4,12 @@ variable "create" { default = true } +variable "skip_zone_lookup" { + description = "Whether to skip zone lookup. If set to true, zone_id and zone_name must be provided" + type = bool + default = false +} + variable "zone_id" { description = "ID of DNS zone" type = string From f18b4ea8c5a97cae1f0a29cbd190cd341a6ea417 Mon Sep 17 00:00:00 2001 From: Mike Carey <32496966+mike-carey@users.noreply.github.com> Date: Tue, 29 Apr 2025 09:45:32 -0500 Subject: [PATCH 2/3] Only reference the data source if we did a lookup --- modules/records/main.tf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/records/main.tf b/modules/records/main.tf index 902b73e..28c3bad 100644 --- a/modules/records/main.tf +++ b/modules/records/main.tf @@ -6,12 +6,13 @@ locals { # Convert `records` from list to map with unique keys recordsets = { for rs in local.records : try(rs.key, join(" ", compact(["${rs.name} ${rs.type}", try(rs.set_identifier, "")]))) => rs } - zone_id = var.zone_id != null ? var.zone_id : data.aws_route53_zone.this[0].zone_id - zone_name = var.zone_name != null ? var.zone_name : data.aws_route53_zone.this[0].name + do_lookup = !var.skip_zone_lookup && var.create && (var.zone_id != null || var.zone_name != null) + zone_id = local.do_lookup ? data.aws_route53_zone.this[0].zone_id : var.zone_id + zone_name = local.do_lookup ? data.aws_route53_zone.this[0].name : var.zone_name } data "aws_route53_zone" "this" { - # Since terraform does not short ciruit, we will use lazy evaluation to avoid + # Since terraform does not short circuit, we will use lazy evaluation to avoid: # > The "count" value depends on resource attributes that cannot be determined until apply count = var.skip_zone_lookup ? 0 : var.create && (var.zone_id != null || var.zone_name != null) ? 1 : 0 From f177facd1099c0e87cdacccff053646e4796db9c Mon Sep 17 00:00:00 2001 From: Mike Carey <32496966+mike-carey@users.noreply.github.com> Date: Tue, 29 Apr 2025 10:24:37 -0500 Subject: [PATCH 3/3] Adds another lazy evaluate to avoid plan-time errors --- modules/records/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/records/main.tf b/modules/records/main.tf index 28c3bad..9dd630f 100644 --- a/modules/records/main.tf +++ b/modules/records/main.tf @@ -22,7 +22,7 @@ data "aws_route53_zone" "this" { } resource "aws_route53_record" "this" { - for_each = { for k, v in local.recordsets : k => v if var.create && (var.zone_id != null || var.zone_name != null) } + for_each = { for k, v in local.recordsets : k => v if var.skip_zone_lookup ? true : var.create && (var.zone_id != null || var.zone_name != null) } zone_id = local.zone_id