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:
| 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
CNAMEpointing at the Front Door endpoint, plus the_dnsauthTXTrecord 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.tfvarswith the correctteam - 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