Azure Front Door - CDN Plan for Staging/Prod
Azure Front Door - CDN Plan for Staging/Prod
Background
Game spin requests show ~732ms end-to-end in the browser network tab, while pack-alpha server-side processing is only 148ms. The remaining ~584ms is pure network overhead (client distance to germanywestcentral). Azure Front Door terminates TLS at the nearest edge PoP and routes traffic over Azure's backbone, reducing the client-to-server round trip significantly.
Expected result after Front Door: ~200ms (down from ~732ms), without any server-side changes.
To reach 100ms, Front Door must be combined with server-side RGS optimizations (see separate doc).
Current Staging State (no CDN)
Browser --(internet, full RTT)--> Container Apps (germanywestcentral)
| App | FQDN |
|---|---|
| pack-alpha-staging | pack-alpha-staging.kindfield-50ee1da3.germanywestcentral.azurecontainerapps.io |
| feg-rgs-staging | feg-rgs-staging.kindfield-50ee1da3.germanywestcentral.azurecontainerapps.io |
| feg-cms-staging | feg-cms-staging.kindfield-50ee1da3.germanywestcentral.azurecontainerapps.io |
| feg-external-staging | feg-external-staging.kindfield-50ee1da3.germanywestcentral.azurecontainerapps.io |
No CDN or Front Door profile exists in the subscription today.
Scope: What Gets Front Door
| App | Front Door? | Reason |
|---|---|---|
| pack-alpha | YES | Game frontend calls this directly - biggest latency impact |
| feg-external | YES | Operator integrations call this from outside Azure |
| feg-cms | NO | Internal admin users only, scale-to-zero, cold starts acceptable |
| feg-rgs | NO | Called by pack-alpha over VNet (4-5ms internal hop) - CDN would add latency |
Changes Required
1. New Azure Front Door Standard Profile
One profile per environment (staging, prod) in the same resource group. Front Door Standard supports: custom domains, managed TLS, dynamic forwarding, WAF (optional).
- No caching configured - game API responses are dynamic, caching is not the goal
- Edge termination is the sole benefit: TLS handshake and TCP at PoP, Azure backbone to origin
2. Endpoint + Origin Group + Route (per app, x2)
For each of pack-alpha and feg-external:
- Endpoint: gets a
.z01.azurefd.nethostname - Origin group: points to the Container App FQDN as origin, with health probe on
/games/health(pack-alpha) or/health(external) - Route: forward all traffic (
/*) to origin, caching disabled
3. Migrate Custom Domains from Container App to Front Door
Custom domains currently bound directly to Container Apps must move to Front Door.
DNS change (per domain):
# Before
yourdomain.com CNAME pack-alpha-staging.kindfield-50ee1da3.germanywestcentral.azurecontainerapps.io
# After
yourdomain.com CNAME <pack-alpha-endpoint>.z01.azurefd.net
Steps:
- Add custom domain to Front Door (Front Door issues managed TLS cert automatically)
- Update DNS CNAME to point to Front Door endpoint
- Remove custom domain binding from Container App
4. Lock Down Container Apps to Front Door Only
Without this, the .azurecontainerapps.io URL remains publicly accessible, bypassing Front Door.
Pulumi change - add IP restriction to ingress:
ingress: {
external: true,
targetPort: ...,
transport: 'http',
allowInsecure: false,
ipSecurityRestrictions: [
{
name: 'allow-front-door',
ipAddressRange: 'AzureFrontDoor.Backend', // Azure service tag
action: 'Allow',
},
],
},
Additionally, validate the X-Azure-FDID header in the app to ensure requests came through your
specific Front Door instance (not any other customer's Front Door). The FDID is available from
the Front Door profile resource after creation.
Cost Estimate (Front Door Standard)
| Component | Price | Monthly (staging) |
|---|---|---|
| Base fee | $35/month per profile | $35 |
| Custom domains | $5/month each | ~$10 (pack-alpha + external) |
| Requests | ~$0.009 per 10K | Low for staging |
| Data transfer out | ~$0.08-0.17/GB | Low for staging |
| Estimated total | ~$45-55/month |
Excluding CMS from Front Door does NOT reduce cost - the $35 base fee is per profile, not per origin. The only saving is the $5/month custom domain fee if CMS had a domain on Front Door.
Pulumi Implementation Notes
Resources to add in feg_slot_be/infra/src/index.ts (gated by a new enableFrontDoor config):
cdn.Profile(SKU: Standard_AzureFrontDoor)cdn.AFDEndpointx2 (pack-alpha, external)cdn.OriginGroupx2cdn.AFDOriginx2 (pointing to Container App FQDNs)cdn.Routex2- Update
ContainerAppingress withipSecurityRestrictionsafter Front Door is provisioned
The feg_common/infra stack (RGS, CMS, external) would need the external app's Front Door
resources too - or the Front Door profile can live in feg_slot_be/infra and origins from
feg_common are added as additional origins in the same profile.
Architecture After Front Door
Browser --(~10ms)--> Front Door PoP --(~15ms Azure backbone)--> pack-alpha (148ms) --> back
Total: ~200ms
The VNet, Redis private endpoint, and inter-service communication (pack-alpha -> RGS) are completely unaffected by this change.