skip to Main Content
Setting up DNS Subdomain Delegation with Terraform
Director of Engineering
November 08 2018

How do you set the default DNS NS servers for a hosted zone in Route53 using Terraform?

Sometimes you want to delegate DNS resolution for a subdomain. This happened recently for one of our clients because a third party provider offered a whitelabel service delivering email.

It’s relatively easy to set up within Route53 manually, but I struggled a bit to find the correct syntax for Terraform, which we use to manage DNS. When you are setting up delegation, there are two main pieces. You need to add an NS record in the main domain for the subdomain, pointing to the custom name servers. And you need to create a zone for that domain and make sure the default name servers for the zone are the custom name servers.
The first task was easy, you just create another record. The second turned out to be a little more challenging.

The first thing I did was consult the documentation, which is terse but good. But it wasn’t clear to me how to set the NS records of the new hosted zone. We had already set things up manually, and I then imported the zone and the records. Importing is less helpful than I thought because you basically have to create the enttiy in your .tf file and then import it via “terraform import …”. Then running “terraform plan” tells you how .tf file differs from the import. So it’s still a bit of hunting to make sure configuration lines up. Would be nice if the .tf file was just updated with the remote state.

Finally, after hunting around a bit, I realized that you can specify the default name servers for a zone by adding a record with the same name as the zone.
Here’s the new .tf entries which set up a delegated subdomain:

resource "aws_route53_zone" "sub_example_com" {
name          = ""
comment       = "Managed by Terraform, NS delegate for third party provider"
force_destroy = false
tags {
ManagedBy = "Terraform"

resource "aws_route53_record" "sub_example_com_zone_ns_record" {
zone_id = "${aws_route53_zone.example_com.zone_id}"
name    = "sub"
type    = "NS"
records = ["thirdparty.dns.server", "thirdparty2.dns.server"] ttl     = "86400" } resource "aws_route53_record" "sub_example_com_zone_default_ns_record" { zone_id = "${aws_route53_zone.sub_example_com.zone_id}" type    = "NS" name    = "" records = ["thirdparty.dns.server", "thirdparty2.dns.server"] ttl     = "86400" } 

Hope this helps someone!

Culture Foundry is a next-level digital agency that helps you thrive in digital. We build, evolve and support websites and applications for clients who are graduating to the next level of complexity in their digital ventures. Our uncommon strengths are headless CMS architectures, design systems and 24/7 support. If you're not thriving in digital, you can be: Contact us to learn more.

(Psst! We also happen to be a great place to work.)

Back To Top