Bruno Schaatsbergen website Mastodon PGP Key email A drawing of an astronaut in space The Netherlands

Name Server Delegation with Route 53

in
blog
date
3/22/2024

Consider an AWS Organization with multiple accounts and you want to make sure that the team managing “the API” can manage their own DNS records, from the account they run their API from.

A central team has a DNS account where the root domain is registered. They configure delegation for the api.example.com subdomain to the API team’s account.

It’s pretty straightforward:

  • Create a hosted zone for the root domain in the central team’s account.
  • Create a hosted zone for the subdomain in the API team’s account.
  • Update the NS records in the root domain’s hosted zone to the NS records of the subdomain’s hosted zone.

Breaking down the steps:

I’m using Terraform to create the resources and perform the delegation.

Create Root Domain Hosted Zone

The central team creates a hosted zone for the root domain, example.com

resource "aws_route53_zone" "1" {
  name = "example.com"
}

Create Subdomain Hosted Zone:

The API team creates a hosted zone for the subdomain, api.example.com.

resource "aws_route53_zone" "api" {
  name = "api.example.com"
}

Set NS Records for Subdomain:

This is where the magic happens. The central team adds an NS record to the example.com hosted zone, for the api.example.com subdomain, pointing to the nameservers of the api.example.com hosted zone.

Now if the api.example.com is queried, the nameservers from the api.example.com hosted zone will be used to resolve the query, meaning it’s forwarded to the API team’s hosted zone (delegated).

resource "aws_route53_record" "api" {
  name            = "api.example.com"
  ttl             = 172800
  type            = "NS"
  zone_id         = aws_route53_zone.example.zone_id

  records = [
    // .. nameservers from the api.example.com hosted zone
  ]
}

Create A Record in Subdomain Hosted Zone:

The API team creates an A record in their hosted zone for testing delegation.

resource "aws_route53_record" "api" {
  zone_id = aws_route53_zone.api.zone_id
  name    = "api.example.com"
  type    = "A"
  ttl     = 300
  records = ["192.168.0.1"]
}

Testing Delegation

To verify delegation that the api.example.com subdomain is delegated correctly, query the A record for api.example.com and check if the response contains the IP address.

$ dig A api.example.com +short
192.168.0.1

How is NS delegation secured?

The combination of the domain name for a hosted zone and the set of name servers associated with the hosted zone is unique1. This means that when you delegate a subdomain to another account, you are pointing to a unique combination of domain name and name servers, making sure that the delegation goes to the hosted zone you intended to delegate to.


👟 Footnotes

  1. https://repost.aws/questions/QU_4J4J-nLR8WHb7VboZ2A_A/route-53-name-server-collisions#ANGu9EnJ5eQSGq7J6K5XR8Cw ↩︎

/name-server-delegation-with-route-53