RJPearson94 / terraform-aws-open-next

Terraform Module for Open Next
https://registry.terraform.io/modules/RJPearson94/open-next/aws/latest
Apache License 2.0
73 stars 10 forks source link

How to pass subdomains and domains #21

Closed Saba-Shavidze closed 7 months ago

Saba-Shavidze commented 7 months ago

I'm trying to pass domains to Route53 like this:

  domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    sub_domain = "dev"
    hosted_zones = [
      {
        name = "dev.abc.ge"
      },
      {
        name = "www.dev.abc.ge"
      }
    ]
  }

but getting this error

Error: no matching Route53Zone found │ │ with module.deploy.module.public_resources[0].data.aws_route53_zone.hosted_zone["www.dev.abc.ge-false"], │ on terraform-aws-open-next/modules/tf-aws-open-next-public-resources/data.tf line 5, in data "aws_route53_zone" "hosted_zone": │ 5: data "aws_route53_zone" "hosted_zone" {

What is this -false? What am I doing wrong?

RJPearson94 commented 7 months ago

hi @Saba-Shavidze,

What is this -false? This flag indicates whether the hosted zone is private (true) or public (false). This documentation https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html provides more context on private hosted zones

It looks like the issue is with the "www.dev.abc.ge" hosted zone.

Are you trying to have the domain dev.abc.ge associated with the distribution? If so, assuming you have a hosted zone called abc.ge, you would need to set the subdomain argument to be "dev" If your hosted zone is called dev.abc.ge, then you can omit the subdomain

Saba-Shavidze commented 7 months ago

No, I just need to have two 2 records for this domain dev.abc.ge and www.dev.abc.ge

RJPearson94 commented 7 months ago

Hi @Saba-Shavidze, I just noticed a bit of a flaw in the module. So you can add dev.abc.ge however I need to modify the module to support www.dev.abc.ge

If your hosted zone is set to dev.abc.ge you will need the following config

domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    hosted_zones = [
      {
        name = "dev.abc.ge"
      }
    ]
  }

If your hosted zone is set to abc.ge you will need the following config

domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    sub_domain = "dev"
    hosted_zones = [
      {
        name = "abc.ge"
      }
    ]
  }
RJPearson94 commented 7 months ago

to support www.dev.abc.ge I am going to add another input argument (likely called include_www) to domain_config to allow this to be conditionally enabled. to prevent a change in behaviour the default of this will be false

So the terraform config would be

domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    include_www = true
    sub_domain = "dev"
    hosted_zones = [
      {
        name = "abc.ge"
      }
    ]
  }

Does that work for you?

RJPearson94 commented 7 months ago

I just need to write up some documentation. Hopefully, will have a patch out by the 7th March.

Saba-Shavidze commented 7 months ago

Yes, as soon as possible if u have a time, or give me some sugesstion how to do that. Also, there is an error when trying to update the domain names:

creating Route 53 Record: InvalidChangeBatch: [Tried to create resource record set [name='dev.abc.ge.', type='A'] but it already exists]
│       status code: 400, request id: 346ebe8f-c80b-4bf8-a09c-12

Maybe we need to set allow_overwrite = true for route53

RJPearson94 commented 7 months ago

Hey @Saba-Shavidze, I have pushed out v2.3.0 of the module, this should allow you to set the www subdomain and also configure the module to override the Route53 entries

RJPearson94 commented 7 months ago

You will need to update your terraform configuration to include the following

domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    include_www = true
    route53_record_allow_overwrite = true
    sub_domain = "dev"
    hosted_zones = [
      {
        name = "abc.ge"
      }
    ]
  }

The full documentation for the possible configuration options can be found at https://github.com/RJPearson94/terraform-aws-open-next/blob/main/docs/domain-config.md

Saba-Shavidze commented 7 months ago

Thanks, I will update it for tomorrow and update about my updates as well ❤️😀

Saba-Shavidze commented 7 months ago

One quick question why you changed the route53_entries to temp_aliases in /modules/tf-aws-open-next-public-resources/main.tf

RJPearson94 commented 7 months ago

So I needed a new local variable to hold a value internally then conditionally apply another modification. The aliases local is set using the temp variable

RJPearson94 commented 7 months ago

I misread your message slightly. 2 new locals were introduced for route53_entries and aliases. to hold temporary values to apply subsequent changes conditionally.

Aliases before

aliases = var.domain_config != null ? formatlist(join(".", compact([var.domain_config.sub_domain, "%s"])), distinct([for hosted_zone in var.domain_config.hosted_zones : hosted_zone.name])) : []

Aliases after

temp_aliases = var.domain_config != null ? concat(formatlist(join(".", compact([var.domain_config.sub_domain, "%s"])), distinct([for hosted_zone in var.domain_config.hosted_zones : hosted_zone.name]))) : []

aliases = try(var.domain_config.include_www, false) == true ? flatten([for alias in local.temp_aliases : [alias, "www.${alias}"]]...) : local.temp_aliases

Route 53 entries before

route53_entries = try(var.domain_config.create_route53_entries, false) == true ? { for hosted_zone in var.domain_config.hosted_zones : join("-", compact([hosted_zone.name, hosted_zone.id, hosted_zone.private_zone])) => { name = join(".", compact([var.domain_config.sub_domain, hosted_zone.name])) zone_id = coalesce(hosted_zone.id, data.aws_route53_zone.hosted_zone[join("-", compact([hosted_zone.name, hosted_zone.private_zone]))].zone_id) } } : {}

Route 53 entries after

temp_route53_entries = try(var.domain_config.create_route53_entries, false) == true ? { for hosted_zone in var.domain_config.hosted_zones : join("-", compact([hosted_zone.name, hosted_zone.id, hosted_zone.private_zone])) => { name = join(".", compact([var.domain_config.sub_domain, hosted_zone.name])) zone_id = coalesce(hosted_zone.id, data.aws_route53_zone.hosted_zone[join("-", compact([hosted_zone.name, hosted_zone.private_zone]))].zone_id) allow_overwrite = var.domain_config.route53_record_allow_overwrite } } : {}

route53_entries = try(var.domain_config.include_www, false) == true ? merge([for name, route53_details in local.temp_route53_entries : { "${name}" = route53details, "www${name}" = { name = "www.${route53_details.name}", zone_id = route53_details.zone_id, allow_overwrite = route53_details.allow_overwrite } }]...) : local.temp_route53_entries

RJPearson94 commented 7 months ago

Have you managed to resolve your issue?

Saba-Shavidze commented 7 months ago

@RJPearson94 I'll update you for Monday.

Saba-Shavidze commented 7 months ago

Hi again, It didn't add alternate domain name with www : www.dev.abc.ge

RJPearson94 commented 7 months ago

Are you able to share your terraform/ terragrunt config? Can I just check you are using v2.3.0 of the module too?

Saba-Shavidze commented 7 months ago
  domain_config = {
    viewer_certificate = {
      acm_certificate_arn = local.acm_certificate_arn
    }
    include_www = true
    route53_record_allow_overwrite = true
    hosted_zones = flatten([
      for name in keys(local.route53_zone_zone_id) : { name = name }
    ])
  }

Yes I'm using latest version v2.3.0.

RJPearson94 commented 7 months ago

Hi @Saba-Shavidze,

I have been unable to replicate this using Terraform or OpenTofu. I have been able to deploy a website with www subdomain using the following terraform code

data "aws_caller_identity" "current" {}

locals {
    route53_zone_zone_id = { "abc.co.uk": "test" }
}

module "zone" {
  source = "RJPearson94/open-next/aws//modules/tf-aws-open-next-zone"
  version = "2.3.0"

  prefix = "open-next-sz-${data.aws_caller_identity.current.account_id}"
  folder_path = "./.open-next"
  s3_exclusion_regex = ".*\\.terragrunt*"

  continuous_deployment = {
    use = true
    deployment = "NONE"
    traffic_config = {
      header = {
        name = "aws-cf-cd-staging"
        value = "true"
      }
    }
  }

  website_bucket = {
    force_destroy = true
  }

  domain_config = {
    route53_record_allow_overwrite = true
    include_www = true
    hosted_zones = flatten([
      for name in keys(local.route53_zone_zone_id) : { name = name }
    ])

    viewer_certificate = {
        acm_certificate_arn = "arn:aws:acm:us-east-1:11111111111:certificate/abc1234"
    }
  }

  providers = {
    aws.server_function = aws.server_function
    aws.iam = aws.iam
    aws.dns = aws.dns
    aws.global = aws.global
  }
}

In CloudFront, this created the following

Screenshot 2024-03-12 at 22 07 15

Note: I have changed the html to mask my account/ CloudFront details

I hope this helps, but if you require any further assistance, I would need access to your Terraform script to see if I can replicate the issue

Kind Regards Rob

shavidze commented 7 months ago

hmm, I will try again.

Saba-Shavidze commented 7 months ago
Error: creating Route 53 Record: InvalidChangeBatch: [RRSet of type A with DNS name www.dev.abc.ge. is not permitted because a conflicting RRSet of type CNAME with the same DNS name already exists in zone dev.abc.ge.]
│   status code: 400, request id: ab2200c6-e7a9-40ba-a3d8-03f7939b1f79
│ 
│   with module.deploy.module.public_resources[0].aws_route53_record.route53_a_record["www_dev.abc.ge-false"],
│   on terraform-aws-open-next/modules/tf-aws-open-next-public-resources/main.tf line 1342, in resource "aws_route53_record" "route53_a_record":
│ 1342: resource "aws_route53_record" "route53_a_record" {
│ 
╵
╷
│ Error: creating Route 53 Record: InvalidChangeBatch: [RRSet of type AAAA with DNS name www.dev.abc.ge. is not permitted because a conflicting RRSet of type CNAME with the same DNS name already exists in zone dev.abc.ge.]
│   status code: 400, request id: 6fe98c45-84d5-4968-873c-472dda137e2a
│ 
│   with module.deploy.module.public_resources[0].aws_route53_record.route53_aaaa_record["www_dev.abc.ge-false"],
│   on terraform-aws-open-next/modules/tf-aws-open-next-public-resources/main.tf line 1359, in resource "aws_route53_record" "route53_aaaa_record":
│ 1359: resource "aws_route53_record" "route53_aaaa_record" {

It actually created and add the www domain, but throw this error while deploying application

Saba-Shavidze commented 7 months ago

I resolved it, you can close the issue. Thanks a lot for your help.

RJPearson94 commented 7 months ago

No problem, glad I could help