Subdomain Management for Multi-Tenant SaaS 
Imagine this: Your SaaS platform powers over 500 healthcare facilities, each on a custom subdomain like clinic.healthcorp.com.
Then HealthCorp calls —
“We’re rebranding the clinic to sunrise. Can it go live by tomorrow with zero or with minimal downtime?”
Traditional approaches might involve certificate reissuance, infrastructure changes, or complex DNS juggling.
The Business Challenge
Multi-tenant SaaS platforms face a unique challenge: dynamic subdomain management at scale. Most platforms use a hierarchical subdomain structure:
<facility>.<enterprise>.com
Real-world scenarios demand support for:
Branded subdomains for each tenant
Frequent changes due to rebranding, mergers, and compliance
Security and uptime guarantees
Architecture Overview
Here’s how we’ve structured our platform to support this dynamic need:
- A single CloudFront distribution serves all tenants.
- A wildcard ACM certificate (
*.healthcorp.com) covers all subdomains. - Route 53 ALIAS A records point subdomains to the CloudFront distribution.
- SSM Parameter Store holds environment-specific identifiers (e.g., hosted zone ID, CloudFront distribution ID).
This setup allows us to change subdomains dynamically without redeploying CloudFront or reissuing certificates.
Workflow: Handling a Subdomain Change
When a facility requests a subdomain change, our backend executes the following steps:
1.
Fetch Configuration from SSM
Use SSM Parameter Store to fetch:
- Hosted zone ID
- CloudFront domain name
- CloudFront distribution ID
const hosted_zone = await fetchSSMParameter({ parameter_name: 'hostZoneId', withDecryption: false });
const cloudfront_domain = `${await fetchSSMParameter({ parameter_name: 'FACILITY_DISTRIBUTION_DOMAIN', withDecryption: false })}.`;
const cloudfront_hosted_zone_id = await verifyExistingRecord({
hosted_zone_id,
record_name: current_sub_domain,
record_type: 'A',
max_items: 1,
});
const cloudfront_distribution_id = await fetchSSMParameter({ parameter_name: 'FACILITY_DISTRIBUTION_ID', withDecryption: false });
2.
Update Route 53 Records
Replace the old DNS record with a new ALIAS record that points to the same CloudFront distribution.
Changes: [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "clinic.healthcorp.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "<cloudfront_hosted_zone_id>",
"DNSName": "<cloudfront_domain>",
"EvaluateTargetHealth": false
}
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "sunrise.healthcorp.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "<cloudfront_hosted_zone_id>",
"DNSName": "<cloudfront_domain>",
"EvaluateTargetHealth": false
}
}
}
]
Note: This is a controlled replace pattern, not a pure UPSERT.
- Explicitly deleting the old DNS record before creating the new one ensures a clean and deterministic transition.
- This avoids scenarios where an UPSERT might silently fail or conflict with existing entries—especially during tenant migrations or renames.
- It also ensures that stale or duplicate records don’t linger, which could lead to DNS resolution issues or security risks.
- In regulated environments like healthcare, this pattern provides better auditability and rollback control.
3.
Wait for Route 53 to Sync
Use polling to ensure the DNS change has fully propagated.
const status = await waitForChangePropagation({ change_id });
4.
Invalidate CloudFront Cache
Even after DNS updates, CloudFront may serve cached content from the old subdomain. This can cause:
- Session inconsistencies
- Stale UI assets
- HTTP errors (e.g., 404s)
To prevent this, invalidate the CloudFront cache:
await createInvalidation({
distribution_id: cloudfront_distribution_id,
paths: ['/*'],
});
This ensures new content is served immediately after the subdomain change.
Final Thoughts
Managing tenant-specific subdomains in a multi-tenant SaaS can be a complex endeavor—but it doesn’t have to be. By leveraging AWS tools like Route 53, CloudFront, ACM, and SSM Parameter Store, we’ve streamlined the process into a scalable, reliable system.
“Just remember: Always invalidate the CloudFront cache after changing DNS. It’s the secret ingredient to a smooth subdomain transition.”