Posts Changing the Domain Name With Code
Post
Cancel

Changing the Domain Name With Code

Just like when deploying changes to a production commercial website, updating my website domain from j.eremy.nl to impulsiveventures needed to be transparent, implemented in code, and reversible if anything went wrong. In fact, I had quite a bit of trouble with this because my terraform code technically worked but let me in a state where I wouldn’t be able to apply any future changes. Using terraform allowed me to revert those changes without any downtime, research where I had gone wrong, and then roll it out again later.

DNS is an eventually consistent system, meaning that when a change it made, users of the system will receive inconsistent results for a period of time. To get the ball rolling, I had to register the new domain name and set up nameservers for it in Route53. The remaining steps cannot commence until those nameservers are consistent (to be safe, let’s call it an hour).

I’m going to start using a map to track the domains being supported, so first we add the map to variables.tf:

1
2
3
4
5
6
7
variable "domain_list" {
  type = map
  default = {
    "primary"   = "impulsiveventures.com"
    "secondary" = "eremy.nl"
  }
}

Now, we can use this in dns.tf to create our zone.

1
2
3
4
5
6
resource "aws_route53_zone" "iv" {
  name = var.domain_list["primary"]
  tags = {
    "site" = var.domain_list["primary"]
  }
}

Lastly, we add an output to outputs.tf so that Terraform will tell us our DNS servers.

1
2
3
output "iv_nameservers" {
  value = aws_route53_zone.iv.name_servers
}

After running terraform apply, we’ll get this list back:

1
2
3
4
5
6
7
8
$ terraform apply
[ ... snip ... ]
iv_nameservers = [
  "ns-1345.awsdns-40.org",
  "ns-1596.awsdns-07.co.uk",
  "ns-320.awsdns-40.com",
  "ns-994.awsdns-60.net",
]

The one manual step is to run over to our registrar and update the list of nameservers with this information. Then, we go make some coffee and wait an hour or so. Once we’re sure that these have propagated, we can continue.

First, we’ll update acm.tf so that our SSL certificate will be issued for the new domain name, with alternates of the www and the old j.eremy.nl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
resource "aws_acm_certificate" "cert" {
  domain_name       = var.domain_list["primary"]
  validation_method = "DNS"
  subject_alternative_names = [
    "www.${var.domain_list["primary"]}",
    "j.${var.domain_list["secondary"]}",
  ]
  tags = {
    "site" = var.domain_list["primary"]
  }

  lifecycle {
    create_before_destroy = true
  }
}

Later in this file, we have to create validation records from this certificate, so that Route53 can verify that we own the domain and are authorized to create SSL certs for it. The main problem is that we specified the Zone ID for the eremy.nl domain, but now we have to support two different domains. This requires a small change.

1
zone_id = dvo.domain_name == "j.eremy.nl" ? aws_route53_zone.eremy_nl.zone_id : aws_route53_zone.iv.zone_id

Lastly, we make cloudfront.tf to reflect its new hostnames.

1
2
3
4
5
  aliases = [
    "${var.host_name}.${var.domain_list["secondary"]}",
    var.domain_list["primary"],
    "www.${var.domain_list["primary"]}",
  ]

Apply these changes and we’re done.

This post is licensed under CC BY 4.0 by the author.