Skip to content

Custom Subdomains

How to add a custom subdomain (e.g. mosaic.saif.com) for your team's service, and the one step that is not automated.

Adding a Subdomain

Add an entry to infra/teams/azure/subdomains.tfvars:

custom_subdomains = [
  {
    team      = "Customer"
    subdomain = "mosaic"
  }
]
Field Required Description
team yes Owning team. Must match the team's owner value — entries are filtered per team at plan time.
subdomain yes Lowercase alphanumeric with hyphens, 1–63 chars. Cannot start or end with a hyphen.
internal_access_only no Defaults to true. Restricts the WAF to SAIF traffic only.

Hostnames include the environment outside production — mosaic.test.saif.com in test, mosaic.saif.com in production.

What Terraform Creates

On apply, saif-custom-subdomain-service provisions:

  • A dedicated Azure Front Door endpoint and custom domain, with a managed TLS certificate.
  • A WAF security policy (SAIF-only when internal_access_only = true).
  • Public DNS in AWS Route53 — the CNAME pointing at the Front Door endpoint, plus the _dnsauth TXT record that proves domain ownership to Front Door.

What Terraform Does Not Create

The internal DNS record is a manual request

Terraform only manages the public saif.com zone in Route53. The internal saif.com zone — served by the corp domain controllers — is AD-integrated and managed outside this repo. Your subdomain will not resolve on the SAIF office network or VPN until someone adds the record there.

This bites hardest when internal_access_only = true, because the corp network is then the only intended audience — exactly the audience that cannot resolve the name.

Why it doesn't fall back to public DNS

Corp DNS is authoritative for saif.com. An authoritative server is the source of truth for its zone, so a name it doesn't hold gets NXDOMAIN — "this name does not exist" — rather than being forwarded upstream. That is correct DNS behaviour, and it is also what makes split-horizon safe: internal answers override public ones, and public records can never inject names into the corp namespace. The symptom is a hard failure (DNS_PROBE_STARTED, "DNS address could not be found") that never self-heals.

Requesting the internal record

Raise a ServiceNow request to the infrastructure team that administers the corp domain controllers, asking for a CNAME in the internal saif.com zone:

Name Type TTL Value
<subdomain> CNAME 3600 Front Door endpoint hostname

Get the endpoint hostname by resolving the name against a public resolver — the answer's first alias is the exact value the internal record needs:

nslookup mosaic.saif.com 1.1.1.1
# Aliases:  mosaic.saif.com
#           mosaic-eqdsddcgfybjabej.a03.azurefd.net   <-- CNAME value

Ask for a CNAME, not an A record: Front Door edge IPs rotate, and the CNAME preserves the Host header that Front Door routes on and that the TLS certificate is issued for. No _dnsauth TXT record is needed internally — ownership is already validated via the public zone.

Verifying

# Public resolution (should already work after apply)
nslookup mosaic.saif.com 1.1.1.1

# Internal resolution (works only after the manual record exists)
nslookup mosaic.saif.com 10.1.128.41

If the public lookup succeeds and the internal one returns "Non-existent domain", the internal record is still missing — this is not propagation delay, and waiting will not fix it.

Checklist

  • Entry added to subdomains.tfvars with the correct team
  • Pipeline applied successfully through to production
  • Public name resolves against a public resolver
  • Internal DNS record requested from the infrastructure team
  • Internal name resolves from the corp network / VPN