-1

I am trying to create an AWS route53 hosted zone and add records to it. I added the following resources to a module main.tf

resource "aws_route53_zone" "zone" {
  name = var.name
}

data "aws_route53_zone" "zone_data" {
  name = var.name

}

resource "aws_route53_record" "record" {
  zone_id = data.aws_route53_zone.zone_data.zone_id
  name    = var.record_name
  type    = var.record_type
  ttl     = var.record_ttl
  records = var.record_value
}

Then I reference that module in a stack main.py as follows:

module "route53" {
  source = "../../modules/route53"
  name   = "website.com"
  type   = "NS"
  ttl    = "30"

}

My issue is that building the stack will use the same name variable for both zone and record resources. How do I add another name to the stack module route53 for the record resource that is different from the zone resource?

Marcin
  • 215,873
  • 14
  • 235
  • 294
mallet
  • 2,454
  • 3
  • 37
  • 64
  • 1
    What is the point of the data source here? What are you actually trying to create here? Like the end product? – theherk Aug 14 '22 at 12:43
  • You should never have a `resource` and `data` that point to the same thing. Everything on `data.aws_route53_zone.zone_data` is also available via the resource `aws_route53_zone.zone`. The first time you run this, before the zone is created, the data source will actually throw an error because it is evaluated before the resource is created. – Mark B Aug 14 '22 at 12:55
  • @theherk I used the data source to access the zone id when creating the records for the zone. The end product is creating a hosted zone on AWS Route53 and assigning Records to it. – mallet Aug 14 '22 at 12:57
  • 1
    @mallet: Does the zone already exist outside this state or not? If sone, use the data source. If not, use the resource. But not both. – theherk Aug 14 '22 at 12:59
  • @MarkB and theherk, got you. The zone actually exists; hence I haven't received any error as you mentioned. Probably it is more appropriate to access the zone id from the resource directly. – mallet Aug 14 '22 at 13:04

3 Answers3

1

If all you're trying to do in the module is create a zone and a record, you could use split to get the zone from the record name given. Like this:

main.tf

module "route53" {
  source = "./modules/route53"
  name   = "something.website.com"
  type   = "NS"
  ttl    = "30"
}

modules/route53/main.tf

variable "name" {}
variable "type" {}
variable "ttl" {}

resource "aws_route53_zone" "this" {
  name = split(".", var.name)[0]
}

resource "aws_route53_record" "this" {
  zone_id = aws_route53_zone.this.zone_id
  name    = var.name
  type    = var.type
  ttl     = var.ttl
  records = [var.name]
}

If however, you want multiple records in that zone, you could consider something like this, but this will depend heavily on what record configuration you're after.

main.tf

module "route53" {
  source = "./modules/route53"
  name   = "website.com"

  record_configs = {
    something = {
      type    = "A"
      records = ["192.168.0.99"]
    }
    other = {
      type    = "CNAME"
      records = ["something.website.com"]
    }
  }
}

modules/route53/main.tf

variable "name" {}
variable "record_configs" {}

resource "aws_route53_zone" "this" {
  name = var.name
}

resource "aws_route53_record" "this" {
  for_each = var.record_configs

  zone_id = aws_route53_zone.this.zone_id
  name    = each.key
  type    = each.value.type
  records = each.value.records
}
theherk
  • 6,954
  • 3
  • 27
  • 52
0

If you have multiple records and names, the best way is to use for_each. For example:

variable "names" {
    default = ["website.com", "website1.com", "website2.com"]
}

then

module "route53" {
  source = "../../modules/route53"
  for_each = toset(var.name)
  name   = each.key
  type   = "NS"
  ttl    = "30"

}

This way you can have same module for multiple names.

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • I can see this work for creating multiple zones using. the `zone` resource but won't affect the `record` zone as required. – mallet Aug 14 '22 at 12:19
0

Randomly experimenting with solutions got me to add the resource variables' names as arguments to the module. This seems to allow referring to arguments of a specific resource in the root module if its argument name is the same as other resources (e.g. record_name vs name).

module "route53" {
  source = "../../modules/route53"
  name   = "website.com"
  record_name   = "_auth.website.com"
  record_type   = "NS"
  record_ttl    = "30"

}
mallet
  • 2,454
  • 3
  • 37
  • 64