terraform-aws-route53 icon indicating copy to clipboard operation
terraform-aws-route53 copied to clipboard

Records module - records attribute is not working properly?

Open grzesiek2115 opened this issue 1 year ago β€’ 0 comments

Description

I have a terraform repository which contains my AWS infrastructure resources. I wanted to use https://registry.terraform.io/modules/terraform-aws-modules/route53/aws/latest module for Route53 records creation. So creating zones went well but I'm stuck on creating records. Let me start with a tree of repo:

└── terraform β”œβ”€β”€ envs β”‚ └── production β”‚ └── dns β”‚ β”œβ”€β”€ acm.tf β”‚ β”œβ”€β”€ main.tf β”‚ β”œβ”€β”€ route53.tf β”‚ └── versions.tf └── modules β”œβ”€β”€ acm β”‚ β”œβ”€β”€ main.tf β”‚ β”œβ”€β”€ outputs.tf β”‚ β”œβ”€β”€ variables.tf β”‚ └── versions.tf └── route53 β”œβ”€β”€ main.tf β”œβ”€β”€ outputs.tf β”œβ”€β”€ variables.tf └── versions.tf image

It seems to be simple and basic structure. I'm trying to pass a set of values within route53_public_hosted_zones from envs/production/dns/route53.tf to module. I'm iterating over route53_public_hosted_zones and each public hosted zone has a route53 records list where I'm specifying my records. Then I'm passing it to module and all the work suppose to be done there. I even changed the name inside of route53_public_hosted_zones map from records to record to avoid some naming convention error but it doesn't change anything even if this list is named xxx or whatever. I actually don't know also why terraform is saying that each.value is object with 3 attributes - which object has 3 attributes in my case? I also checked module code and records are concatenated so in my opinion it shouldn't be issue with that. Maybe I don't see something really simple? I don't think so that I have typos there, I checked that many times. Could you please help my understand why it is behaving this way and it is not working?

Versions

  • Module version [Required]: terraform-aws-modules/route53/aws//modules/zones - 4.1.0 terraform-aws-modules/route53/aws//modules/records - 4.1.0

  • Terraform version: 1.6.6

  • Provider version(s): registry.terraform.io/hashicorp/aws - 5.61.0

Reproduction Code

Here's my module. Creating hosted zones works good with "public_zones" module. Creating records with "public_records" is not. my_aws_project/terraform/modules/route53/main.tf

provider "aws" {
  default_tags {
    tags = {
      Terraform = "true"
    }
  }
}

module "public_zones" {
  source  = "terraform-aws-modules/route53/aws//modules/zones"
  version = "4.1.0"

  for_each = var.public_hosted_zones

  zones = {
    "${each.key}" = {
      comment = each.value.comment == null ? "Domains in this hosted zone are publicly accessible on the internet." : each.value.comment
      force_destroy = each.value.force_destroy == null ? false : each.value.force_destroy
      }
    }
}

module "public_records" {
  source  = "terraform-aws-modules/route53/aws//modules/records"
  version = "4.1.0"

  for_each = var.public_hosted_zones
  zone_name = each.key 
  records = each.value.record # This guy is not working

  # depends_on = [module.zones]
}

Here's my env specific code. my_aws_project/terraform/envs/production/dns/main.tf

provider "aws" {
  default_tags {
    tags = {
      Terraform = "true"
    }
  }
}


locals {
  route53_public_hosted_zones = {
    "mysite.com" = {
      acm_subject_alternative_names = ["*.mysite.com"],
      record = [
        {
          name = "test.mysite.com"
          allow_overwrite = true,
          type            = "NS",
          ttl             = 300,
          records = [
            "ns-111.awsdns-1.net",
            "ns-222.awsdns-2.com",
            "ns-333.awsdns-3.co.uk",
            "ns-444.awsdns-4.org",
          ]
        },
        {
          allow_overwrite = true
          name            = "myothersite"
          type            = "A"
          alias = {
            name                   = "k8s-123456789.us-west-2.elb.amazonaws.com"
            zone_id                = "abc123"
            evaluate_target_health = true
          }
        }
      ]
    },
    "mysite-xyz.com" = {
      acm_subject_alternative_names = ["*.mysite-xyz.com"],
      record = []
    },
    "mysite-xy.com" = {
      acm_subject_alternative_names = ["*.mysite-xy.com"],
      record = []
    },
    "mysite.info" = {
      acm_subject_alternative_names = ["*.mysite.info"],
      record = []
    },
  }
}

and here's a call: my_aws_project/terraform/envs/production/dns/route53.tf

module "route53" {
  source = "../../../modules/route53"

  public_hosted_zones  = local.route53_public_hosted_zones
}

Steps to reproduce the behavior:

terraform plan

Expected behavior

Passing values from my production folder to a module works and terraform plan works without any error.

Actual behavior

While running terraform plan I receive Error: Unsupported attribute which points to records = each.value.record and is saying that each.value is object with 3 attributes

Terminal Output Screenshot(s)

image

Additional context

The key thing is when I'm moving the records list to my module (my_aws_project/terraform/modules/route53/main.tf) and it looks like that:

provider "aws" {
  default_tags {
    tags = {
      Terraform = "true"
    }
  }
}

module "public_zones" {
  source  = "terraform-aws-modules/route53/aws//modules/zones"
  version = "4.1.0"

  for_each = var.public_hosted_zones

  zones = {
    "${each.key}" = {
      comment = each.value.comment == null ? "Domains in this hosted zone are publicly accessible on the internet." : each.value.comment
      force_destroy = each.value.force_destroy == null ? false : each.value.force_destroy
      }
    }
}

module "public_records" {
  source  = "terraform-aws-modules/route53/aws//modules/records"
  version = "4.1.0"

  for_each = var.public_hosted_zones
  zone_name = each.key 
  # records = each.value.record # This guy is not working
  records = [
        {
          name = "test.mysite.com"
          allow_overwrite = true,
          type            = "NS",
          ttl             = 300,
          records = [
            "ns-111.awsdns-1.net",
            "ns-222.awsdns-2.com",
            "ns-333.awsdns-3.co.uk",
            "ns-444.awsdns-4.org",
          ]
        },
        {
          allow_overwrite = true
          name            = "myothersite"
          type            = "A"
          alias = {
            name                   = "k8s-123456789.us-west-2.elb.amazonaws.com"
            zone_id                = "abc123"
            evaluate_target_health = true
          }
        }
      ]
  # depends_on = [module.zones]
}

the terraform plan command is not throwing any error - it's just works as suppose to work and I'm satisfied with an output.

Additionally, I'm doing exactly the same thing next to it on exactly the same set of values - route53_public_hosted_zones. Here's sample. my_aws_project/terraform/envs/production/dns/acm.tf

module "acm" {
  for_each = local.route53_public_hosted_zones

  source = "../../../modules/acm"
  providers = {
    aws = aws
  }

  cert_domain_name               = each.key
  cert_subject_alternative_names = each.value.acm_subject_alternative_names

  depends_on = [module.route53]
}

my_aws_project/terraform/modules/acm/main.tf

resource "aws_acm_certificate" "this" {
  domain_name               = var.cert_domain_name
  subject_alternative_names = var.cert_subject_alternative_names
  validation_method         = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

and passing a list named acm_subject_alternative_names just works. I tried to use exactly same mechanism while calling route53 records module.

grzesiek2115 avatar Oct 17 '24 10:10 grzesiek2115