Skip to main content

5. Domain, DNS and certificates

What it is​

DNS turns names like api.example.com into addresses. A hosted zone in AWS Route 53 holds the DNS records for one domain or subdomain. We put the main zone in the prod account and give each other environment its own subdomain zone in its own account, linked by delegation (an NS record that says "ask that other zone"). Certificates from AWS Certificate Manager (ACM) make https:// work, free, and renew themselves.

Why we do it​

  • Each environment manages its own names without touching prod.
  • Predictable names: anyone can guess api.staging.example.com.
  • ACM certificates renew automatically as long as the DNS validation record stays.

Before you start​

  • Access to the domain's registrar (where it was bought: GoDaddy, Namecheap, Route 53).
  • The list of existing records the client uses, especially email (MX) and website records. Export them before changing anything.
  • AWS SSO access to prod, staging and dev from step 4.

The naming plan​

Whatprodstagingdev
Zoneexample.com (prod account)staging.example.com (staging account)dev.example.com (dev account)
APIapi.example.comapi.staging.example.comapi.dev.example.com
Web appapp.example.comapp.staging.example.comapp.dev.example.com
Adminadmin.example.comadmin.staging.example.comadmin.dev.example.com
Email sendingmail.example.com

How it fits together​

Steps​

1. Create the main zone in prod​

Route 53, Hosted zones, Create hosted zone, name example.com, type Public. Note the four NS values it shows.

If the domain already has records elsewhere, copy every existing record into the new zone first (website, MX, TXT for email and verification). Then:

2. Point the registrar at Route 53​

At the registrar, replace the domain's nameservers with the four NS values from step 1. This can take up to 48 hours to spread, usually less than one. Do it on a weekday morning, never before a launch.

3. Create the environment zones and delegate them​

In the dev account: create a public hosted zone dev.example.com and note its four NS values. In the prod account's example.com zone, add a record:

NameTypeValue
devNSthe four values from the dev zone

Repeat for staging. Do it in two Terraform applies: create the zone, then add the delegation, because the second needs the first's output.

4. Request certificates​

In each account, Certificate Manager, Request a public certificate:

AccountNamesRegion
prodexample.com, *.example.commain region (for load balancers) and us-east-1 (for CloudFront)
staging*.staging.example.comsame two
dev*.dev.example.comsame two

Choose DNS validation, then Create records in Route 53. The status turns to Issued within minutes. Leave the validation records in place forever; renewal uses them.

A wildcard (*.dev.example.com) also means individual host names are not listed in public certificate logs, which scanners watch.

Check it worked​

dig NS example.com +short # the four Route 53 nameservers
dig NS dev.example.com +short # the dev zone's nameservers
dig api.dev.example.com +short # an address, once the load balancer exists

In ACM every certificate shows Issued.

If it goes wrong​

You seeIt means
Email stopped working after step 2The MX records were not copied into the new zone
Certificate stuck in "Pending validation"The validation CNAME is missing, or delegation is not working yet
CloudFront will not accept the certificateIt must be in us-east-1
dig answers differ between laptopsOld answers are cached. Wait for the TTL

Rules​

Rule

Export and copy every existing record before you change nameservers. Losing the client's email records stops their company email.

Rule

Never delete an ACM validation record. The certificate silently fails to renew a year later.

Done when​

  • example.com zone in prod with all existing records copied.
  • Registrar points at Route 53.
  • dev and staging zones delegated.
  • Wildcard certificates issued in the main region and us-east-1, per environment.