In Phase 1, we deployed regional App Services.
In Phase 2, we elevate the architecture:
π Add a global entry point
π Terminate TLS at the edge
π Route traffic intelligently to regional backends
All using Azure CLI in Cloud Shell.
π§ Architecture Goal
We want this flow:
User
β
Azure Front Door (Global Edge)
β
Origin Group
β
App Service (SEA)
More details
Even with a single region (quota constraints), this gives us:
- Global Anycast entry
- Edge TLS termination
- Health-probe-based routing
- Future-ready multi-region expansion
π Phase 2 Resources
Inside one Resource Group:
- Azure Front Door Profile (Standard)
- Endpoint
- Origin Group
- Origin (App Service)
- Route
- App Service (SEA region)
π Step 1 β Create Front Door Profile
RG=rg-afd-lab
PROFILE_NAME=afd-profile
ENDPOINT_NAME=afd-endpoint
az afd profile create \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--sku Standard_AzureFrontDoor
π Step 2 β Create Endpoint
az afd endpoint create \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--endpoint-name $ENDPOINT_NAME \
--enabled-state Enabled
Get hostname:
az afd endpoint show \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--endpoint-name $ENDPOINT_NAME \
--query hostName -o tsv
Youβll get:
<endpoint>.z01.azurefd.net
π― Step 3 β Create Origin Group
ORIGIN_GROUP=app-origin-group
az afd origin-group create \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--origin-group-name $ORIGIN_GROUP \
--probe-request-type GET \
--probe-protocol Https \
--probe-path "/" \
--probe-interval-in-seconds 30
This enables health checks every 30 seconds on /.
π₯ Step 4 β Add App Service as Origin
az afd origin create \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--origin-group-name $ORIGIN_GROUP \
--origin-name sea-origin \
--host-name app-sea-3446.azurewebsites.net \
--origin-host-header app-sea-3446.azurewebsites.net \
--priority 1 \
--weight 1000 \
--enabled-state Enabled
Important:
-
origin-host-headermust match the App Service hostname - HTTPS certificate name check is enforced by default
π£ Step 5 β Create Route (Critical)
This is where many people hit issues.
β In Standard SKU, you MUST link the route to a domain.
az afd route create \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--endpoint-name $ENDPOINT_NAME \
--route-name app-route \
--origin-group $ORIGIN_GROUP \
--supported-protocols Http Https \
--patterns-to-match "/*" \
--forwarding-protocol MatchRequest \
--https-redirect Enabled \
--link-to-default-domain Enabled
If you omit:
--link-to-default-domain Enabled
Youβll get:
(BadRequest) At least one domain is required for the route.
π§ͺ Step 6 β Validate Deployment
Check route:
az afd route list \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--endpoint-name $ENDPOINT_NAME \
-o table
You want:
ProvisioningState = Succeeded
DeploymentStatus = Succeeded
If you see:
DeploymentStatus = NotStarted
Trigger activation:
curl https://<endpoint-hostname>
Front Door deploys globally on first traffic.
If all succeed, we'll something like this
[ ~ ]$ curl -s https://afd-endpoint-dxd8bebma8dbdsed.z01.azurefd.net
Hello from Southeast Asia
π Troubleshooting 404 Errors
If you see:
404 Not Found
X-Cache: CONFIG_NOCACHE
That means:
Route not fully deployed to edge yet.
It is NOT your backend.
Verify backend:
curl -I https://app-sea-3446.azurewebsites.net
If backend returns 200, the issue is route activation.
If route gets stuck:
az afd route delete ...
az afd route create ...
Recreating the route forces global redeployment.
π Health Probe Verification
Check origin group:
az afd origin-group show \
--resource-group $RG \
--profile-name $PROFILE_NAME \
--origin-group-name $ORIGIN_GROUP
You should see:
"probePath": "/",
"probeProtocol": "Https",
"provisioningState": "Succeeded"
π§± Final Working Architecture
Internet
β
Azure Front Door Edge (Anycast)
β
Origin Group
β
App Service (SEA)
Even with one region, you now have:
- Global entry point
- Edge TLS termination
- Health-probe routing
- Production-ready structure
- Multi-region expansion capability
π§ What We Learned
Key lessons from Phase 2:
- Standard SKU requires domain linkage for routes
- DeploymentStatus = NotStarted means edge not activated
- CONFIG_NOCACHE 404 is configuration-level, not backend
- Route object triggers global edge deployment
- Health probes must succeed before activation
π Whatβs Next (Phase 3)
In Phase 3 we can add:
- π Web Application Firewall (WAF)
- π Custom domain + managed TLS
- π Azure Monitor diagnostics
- π Active/Passive failover
- π Multi-region scaling


Top comments (0)