π End-to-End Tutorial: Azure Blob Storage + Azure Front Door CDN for Website Assets¶
π Use Case¶
You have:
- A frontend website hosted in Azure App Service
-
Static assets like:
-
Images (
.png,.jpg,.webp) - Videos (
.mp4) - JS/CSS files
You want:
β CDN caching β Faster global delivery β Reduced load on App Service β Best practice Azure architecture
π Recommended Architecture¶
Users
β
Azure Front Door (CDN + Edge Cache)
β
Azure Blob Storage (Assets Container)
Frontend Website
β
Azure App Service
β Why Use Blob + Front Door?¶
App Service is meant for:
- Hosting frontend/backend apps
- Running server logic
Blob Storage is meant for:
- Cheap static storage
- Large media files
- Unlimited scaling
Front Door provides:
- Global CDN edge caching
- HTTPS support
- Custom domain support
- WAF security (optional)
β Step 1: Create Blob Storage for Assets¶
1. Storage Account¶
If Storage Account already exists, reference it:
data "azurerm_storage_account" "assets_sa" {
name = var.storage_account_name
resource_group_name = var.resource_group_name
}
2. Create Container for Assets¶
resource "azurerm_storage_container" "assets_container" {
name = "assets"
storage_account_name = data.azurerm_storage_account.assets_sa.name
container_access_type = "blob"
}
Now your assets will be stored like:
β Step 2: Create Azure Front Door Profile¶
Front Door Profile is the main CDN service.
resource "azurerm_cdn_frontdoor_profile" "cdn_profile" {
name = var.frontdoor_profile_name
resource_group_name = var.resource_group_name
sku_name = "Standard_AzureFrontDoor"
}
Example:
β Step 3: Create Front Door Endpoint¶
Endpoint gives you the CDN URL:
Terraform:
resource "azurerm_cdn_frontdoor_endpoint" "cdn_endpoint" {
name = var.frontdoor_endpoint_name
cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.cdn_profile.id
}
Example:
β Step 4: Configure Origin Group¶
Origin Group manages backend health + load balancing.
resource "azurerm_cdn_frontdoor_origin_group" "origin_group" {
name = var.origin_group_name
cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.cdn_profile.id
load_balancing {
sample_size = 4
successful_samples_required = 3
}
}
Example:
β Step 5: Add Blob Storage as Origin¶
Front Door Origin = Blob Storage endpoint.
resource "azurerm_cdn_frontdoor_origin" "blob_origin" {
name = var.origin_name
cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.origin_group.id
enabled = true
host_name = data.azurerm_storage_account.assets_sa.primary_blob_host
origin_host_header = data.azurerm_storage_account.assets_sa.primary_blob_host
certificate_name_check_enabled = true
http_port = 80
https_port = 443
priority = 1
weight = 100
}
Example:
β Step 6: Create Front Door Route (Container Mapping)¶
Azure Front Door does not directly know the container name.
So you must route requests like:
Terraform:
resource "azurerm_cdn_frontdoor_route" "assets_route" {
name = var.route_name
cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.cdn_endpoint.id
cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.origin_group.id
cdn_frontdoor_origin_ids = [
azurerm_cdn_frontdoor_origin.blob_origin.id
]
enabled = true
patterns_to_match = [
"/${azurerm_storage_container.assets_container.name}/*"
]
supported_protocols = ["Http", "Https"]
forwarding_protocol = "HttpsOnly"
link_to_default_domain = true
cache {
compression_enabled = false
query_string_caching_behavior = "IgnoreQueryString"
}
}
Example:
β Step 7: Deploy Terraform¶
Run:
β Step 8: Upload Assets to Blob¶
Example upload:
az storage blob upload \
--account-name <storage-account-name> \
--container-name assets \
--name images/logo.png \
--file ./logo.png
β Step 9: Access Assets Through CDN¶
Blob URL:¶
Front Door CDN URL:¶
Now assets are served globally from edge cache π
β Step 10: Use CDN in App Service Frontend¶
In your frontend code:
For videos:
<video controls>
<source src="https://assets-cdn-endpoint.azurefd.net/assets/videos/demo.mp4" />
</video>
β Production Improvements (Next Step)¶
To make this enterprise-ready:
β
Custom domain: cdn.yoursite.com
β
Private Blob + Origin Access Control
β
Cache TTL rules (30 days)
β
WAF protection
β Final Result¶
You implemented a scalable CDN architecture:
- Frontend hosted on App Service
- Assets stored in Blob Storage
- Azure Front Door providing CDN caching globally
This is the best practice setup in Azure today.
β CDN Setup for Other Azure Services¶
Azure has one main modern CDN platform now:
β Azure Front Door (Standard/Premium)¶
Front Door can sit in front of:
- Blob Storage
- App Service
- Static Web Apps
- AKS Ingress
- API Management
- Any public HTTP backend
β Best CDN Options by Service¶
1οΈβ£ App Service + Front Door CDN (Full Website Acceleration)¶
If you want CDN for your full frontend site:
Use Case:¶
- Global website performance
- Custom domain + SSL
- WAF protection
Terraform origin becomes App Service host:
resource "azurerm_cdn_frontdoor_origin" "app_origin" {
name = "appservice-origin"
cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.origin_group.id
host_name = azurerm_linux_web_app.frontend.default_hostname
origin_host_header = azurerm_linux_web_app.frontend.default_hostname
https_port = 443
}
Then route:
2οΈβ£ Azure Static Web Apps (Built-in CDN)¶
Static Web Apps already includes global distribution.
So no extra CDN needed if:
β Fully static React/Vue frontend
URL:
Best for:
- Static sites
- Jamstack apps
3οΈβ£ AKS + Front Door CDN (Kubernetes Workloads)¶
If your frontend/backend runs in AKS:
Origin is Ingress public IP / DNS:
Best for:
- Microservices
- Global traffic routing
4οΈβ£ API Management + Front Door¶
For APIs:
Benefits:
- API caching
- WAF protection
- Global routing
Origin:
5οΈβ£ Azure Storage (Blob, Static Website, Files)¶
Blob is the most common CDN backend.
Best for:
- Images
- Videos
- Downloads
6οΈβ£ Azure Container Apps + Front Door¶
Container Apps provide a public endpoint.
Origin host:
7οΈβ£ Azure VM / NGINX + Front Door¶
If you have a VM running a website:
Origin:
π₯ One Front Door, Multiple Origins (Best Practice)¶
You can configure:
/assets/*β Blob Storage/api/*β API Management/*β App Service frontend
Example routing:
| Path Pattern | Backend |
|---|---|
/assets/* |
Blob Storage |
/api/* |
API Management |
/* |
App Service |
Thatβs the most scalable production setup.
β Recommended Setup for You¶
Since you already have:
β App Service frontend β Blob assets CDN
Next best:
Add App Service itself behind Front Door¶
So users access:
And assets load from: