Azure Front Door: prepara tu infraestructura para Black Friday
Resumen
Black Friday y Cyber Monday generan picos de tráfico 10-50x normales. Azure Front Door te da CDN global, WAF, load balancing inteligente y failover automático para manejar esos picos sin caídas. En este post verás cómo configurar Front Door para alta disponibilidad y performance.
¿Por qué Azure Front Door para Black Friday?
Problemas típicos en Black Friday:
- Latencia alta: Usuarios globales accediendo desde LATAM, Asia, Europa
- Origin overload: Backend no aguanta 50,000 req/seg
- DDoS attacks: Competidores o bots atacan tu site
- Single point of failure: Un region down = site down
- Cache ineficiente: Mismo contenido descargado millones de veces
Solución Front Door:
flowchart LR
Users[Users Worldwide] --> FD[Azure Front Door
150+ Edge Locations]
FD --> WAF[WAF Rules
DDoS Protection]
WAF --> Cache[Cache Layer
Static Assets]
Cache --> Primary[Primary Origin
West Europe]
Cache --> Secondary[Secondary Origin
East US]
Primary -.Failover.-> Secondary
Setup básico Azure Front Door
Crear Front Door Standard/Premium
# Variables
RESOURCE_GROUP="rg-ecommerce-prod"
FRONT_DOOR_NAME="fd-ecommerce"
SKU="Premium_AzureFrontDoor" # Premium incluye WAF avanzado
# Crear Front Door
az afd profile create \
--profile-name $FRONT_DOOR_NAME \
--resource-group $RESOURCE_GROUP \
--sku $SKU
# Crear endpoint
az afd endpoint create \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name ecommerce-frontend \
--resource-group $RESOURCE_GROUP \
--enabled-state Enabled
# Crear origin group (backends)
az afd origin-group create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--resource-group $RESOURCE_GROUP \
--probe-request-type GET \
--probe-protocol Https \
--probe-path /health \
--probe-interval-in-seconds 30 \
--sample-size 4 \
--successful-samples-required 3 \
--additional-latency-in-milliseconds 50
# Agregar origin primario (West Europe)
az afd origin create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--origin-name webapp-westeurope \
--resource-group $RESOURCE_GROUP \
--host-name webapp-prod-we.azurewebsites.net \
--origin-host-header webapp-prod-we.azurewebsites.net \
--priority 1 \
--weight 1000 \
--enabled-state Enabled \
--http-port 80 \
--https-port 443
# Agregar origin secundario (East US - failover)
az afd origin create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--origin-name webapp-eastus \
--resource-group $RESOURCE_GROUP \
--host-name webapp-prod-eus.azurewebsites.net \
--origin-host-header webapp-prod-eus.azurewebsites.net \
--priority 2 \ # Mayor priority = backup
--weight 500 \
--enabled-state Enabled
# Crear route
az afd route create \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name ecommerce-frontend \
--route-name default-route \
--resource-group $RESOURCE_GROUP \
--origin-group webapp-origins \
--supported-protocols Http Https \
--https-redirect Enabled \
--forwarding-protocol HttpsOnly \
--link-to-default-domain Enabled
Caching strategy para Black Friday
Configurar cache rules
# Rule 1: Cache imágenes por 7 días
az afd rule create \
--profile-name $FRONT_DOOR_NAME \
--rule-set-name CachingRules \
--rule-name CacheImages \
--resource-group $RESOURCE_GROUP \
--order 1 \
--match-variable RequestPath \
--operator BeginsWith \
--match-values "/images/" "/assets/" \
--action-name CacheExpiration \
--cache-behavior OverrideAlways \
--cache-duration "7.00:00:00"
# Rule 2: Cache API productos por 5 minutos
az afd rule create \
--profile-name $FRONT_DOOR_NAME \
--rule-set-name CachingRules \
--rule-name CacheAPIProducts \
--resource-group $RESOURCE_GROUP \
--order 2 \
--match-variable RequestPath \
--operator BeginsWith \
--match-values "/api/products" \
--action-name CacheExpiration \
--cache-behavior OverrideAlways \
--cache-duration "00:05:00"
# Rule 3: NO cache checkout/cart
az afd rule create \
--profile-name $FRONT_DOOR_NAME \
--rule-set-name CachingRules \
--rule-name NoCacheCheckout \
--resource-group $RESOURCE_GROUP \
--order 3 \
--match-variable RequestPath \
--operator Contains \
--match-values "/checkout" "/cart" "/api/orders" \
--action-name CacheExpiration \
--cache-behavior BypassCache
Query string caching
# Cache basado en query strings específicos (ej: ?color=red&size=L)
az afd route update \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name ecommerce-frontend \
--route-name default-route \
--resource-group $RESOURCE_GROUP \
--query-string-caching-behavior IncludeSpecifiedQueryStrings \
--query-parameters "color" "size" "variant"
WAF: protección contra ataques
Configurar WAF policy
# Crear WAF policy
az network front-door waf-policy create \
--name waf-blackfriday \
--resource-group $RESOURCE_GROUP \
--sku Premium_AzureFrontDoor \
--mode Prevention # Detection solo monitoriza, Prevention bloquea
# Regla custom: Rate limiting (max 100 req/min por IP)
az network front-door waf-policy custom-rule create \
--policy-name waf-blackfriday \
--resource-group $RESOURCE_GROUP \
--name RateLimitRule \
--priority 100 \
--rule-type RateLimitRule \
--action Block \
--rate-limit-threshold 100 \
--rate-limit-duration-in-minutes 1 \
--match-condition \
MatchVariable=RequestUri \
Operator=Contains \
MatchValue="/api/"
# Regla: Bloquear IPs sospechosas
az network front-door waf-policy custom-rule create \
--policy-name waf-blackfriday \
--resource-group $RESOURCE_GROUP \
--name BlockBadIPs \
--priority 200 \
--rule-type MatchRule \
--action Block \
--match-condition \
MatchVariable=RemoteAddr \
Operator=IPMatch \
MatchValue="203.0.113.0/24,198.51.100.0/24" # IPs maliciosas
# Managed rules: OWASP Top 10
az network front-door waf-policy managed-rules add \
--policy-name waf-blackfriday \
--resource-group $RESOURCE_GROUP \
--type Microsoft_DefaultRuleSet \
--version 2.1 \
--action Block
# Managed rules: Bot protection
az network front-door waf-policy managed-rules add \
--policy-name waf-blackfriday \
--resource-group $RESOURCE_GROUP \
--type Microsoft_BotManagerRuleSet \
--version 1.0
# Asociar WAF policy a Front Door
az afd security-policy create \
--profile-name $FRONT_DOOR_NAME \
--resource-group $RESOURCE_GROUP \
--security-policy-name waf-policy \
--domains ecommerce-frontend \
--waf-policy /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/waf-blackfriday
Load balancing inteligente
Weighted routing
# Distribuir tráfico: 80% West Europe, 20% East US
az afd origin update \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--origin-name webapp-westeurope \
--resource-group $RESOURCE_GROUP \
--weight 800
az afd origin update \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--origin-name webapp-eastus \
--resource-group $RESOURCE_GROUP \
--weight 200
Latency-based routing
# Front Door automáticamente enruta al origin con menor latencia
az afd origin-group update \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--resource-group $RESOURCE_GROUP \
--additional-latency-in-milliseconds 50 # Tolerar 50ms diferencia antes de failover
Health probes y failover
# Configurar health probe agresivo
az afd origin-group update \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name webapp-origins \
--resource-group $RESOURCE_GROUP \
--probe-interval-in-seconds 10 \ # Check cada 10s (default 30s)
--probe-path /health \
--successful-samples-required 2 \ # 2/4 probes exitosos para marcar healthy
--sample-size 4
Health check endpoint en backend:
// ASP.NET Core health check
app.MapGet("/health", () =>
{
// Verificar DB connection, external APIs, etc.
var dbHealthy = CheckDatabaseConnection();
var cacheHealthy = CheckRedisConnection();
if (!dbHealthy || !cacheHealthy)
return Results.StatusCode(503); // Unhealthy
return Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow });
});
Custom domain y SSL
Configurar dominio custom
# Agregar custom domain
az afd custom-domain create \
--profile-name $FRONT_DOOR_NAME \
--custom-domain-name www-example-com \
--resource-group $RESOURCE_GROUP \
--host-name www.example.com \
--minimum-tls-version TLS12 \
--certificate-type ManagedCertificate # Auto-renovado por Azure
# Asociar domain a route
az afd route update \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name ecommerce-frontend \
--route-name default-route \
--resource-group $RESOURCE_GROUP \
--custom-domains www-example-com
# Obtener CNAME validation
az afd custom-domain show \
--profile-name $FRONT_DOOR_NAME \
--custom-domain-name www-example-com \
--resource-group $RESOURCE_GROUP \
--query "validationProperties.validationToken"
Agregar en DNS:
Monitoring y alertas Black Friday
Metrics críticas
# Dashboard Front Door
az monitor metrics list \
--resource /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Cdn/profiles/$FRONT_DOOR_NAME \
--metric "RequestCount" "TotalLatency" "BackendHealthPercentage" "OriginRequestCount" "WebApplicationFirewallRequestCount" \
--start-time "2025-11-29T00:00:00Z" \
--end-time "2025-11-29T23:59:59Z" \
--interval PT5M \
--aggregation Total Average
Alertas críticas
# Alerta: Backend health < 80%
az monitor metrics alert create \
--name alert-backend-unhealthy \
--resource-group $RESOURCE_GROUP \
--scopes /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Cdn/profiles/$FRONT_DOOR_NAME \
--condition "avg BackendHealthPercentage < 80" \
--window-size 5m \
--evaluation-frequency 1m \
--action ag-blackfriday-oncall \
--description "Backend health degraded"
# Alerta: Latency > 2 segundos
az monitor metrics alert create \
--name alert-high-latency \
--resource-group $RESOURCE_GROUP \
--scopes /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Cdn/profiles/$FRONT_DOOR_NAME \
--condition "avg TotalLatency > 2000" \
--window-size 5m \
--action ag-blackfriday-oncall
# Alerta: WAF blocking spike
az monitor metrics alert create \
--name alert-waf-blocking-spike \
--resource-group $RESOURCE_GROUP \
--scopes /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/waf-blackfriday \
--condition "total BlockedRequestCount > 1000" \
--window-size 5m \
--action ag-security-team
Pre-warming y load testing
Pre-warmar cache antes de Black Friday
#!/bin/bash
# Script: warm-cache.sh
# Ejecutar 1 hora antes de Black Friday
FRONT_DOOR_URL="https://www.example.com"
# Top 100 URLs más visitadas
URLS=(
"/products/bestsellers"
"/products/category/electronics"
"/products/category/clothing"
"/deals/black-friday"
# ... más URLs
)
echo "Warming cache..."
for url in "${URLS[@]}"; do
curl -s -o /dev/null "$FRONT_DOOR_URL$url"
echo "Warmed: $url"
sleep 0.1
done
echo "Cache warming completed"
Load test con Azure Load Testing
# loadtest-blackfriday.yaml
testId: blackfriday-2025
displayName: "Black Friday Load Test"
testPlan: jmeter-test.jmx
engineInstances: 20 # 20 load generators
env:
- name: TARGET_URL
value: https://www.example.com
- name: THREADS
value: "5000" # 5,000 usuarios concurrentes
- name: RAMP_UP
value: "300" # Ramp-up en 5 minutos
- name: DURATION
value: "3600" # Test de 1 hora
# Ejecutar load test
az load test create \
--load-test-resource loadtest-prod \
--resource-group $RESOURCE_GROUP \
--test-id blackfriday-2025 \
--load-test-config-file loadtest-blackfriday.yaml
Checklist preparación Black Friday
2 semanas antes: - [ ] Configurar Front Door con multi-origin (primary + backup) - [ ] Implementar WAF rules (rate limiting, bot protection) - [ ] Configurar cache rules para assets estáticos - [ ] Setup custom domain con SSL - [ ] Crear alertas de monitoring críticas - [ ] Load test con tráfico 5x normal
1 semana antes: - [ ] Validar health checks funcionan correctamente - [ ] Test manual de failover (apagar primary origin) - [ ] Revisar WAF logs para ajustar false positives - [ ] Comunicar runbook a equipo on-call - [ ] Backup de configuración Front Door
1 día antes: - [ ] Pre-warming de cache (top 100 URLs) - [ ] Verificar origins están healthy - [ ] Load test con tráfico 10x normal - [ ] Validar dashboards y alertas funcionan - [ ] Freeze de deployments (no cambios en producción)
Durante Black Friday: - [ ] Monitoring continuo (cada 5 min) - [ ] Revisar WAF blocks para ataques - [ ] Estar listo para escalar backends si necesario - [ ] Documentar incidentes para post-mortem
Troubleshooting común
Problem a: Cache no funciona
# Verificar cache hit ratio
az monitor metrics list \
--resource /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Cdn/profiles/$FRONT_DOOR_NAME \
--metric "CacheHitRatio" \
--start-time "2025-11-29T00:00:00Z" \
--interval PT5M
Fix típico: Headers Cache-Control: no-cache en backend → remover o override en Front Door
Problema: WAF bloqueando legítimo tráfico
# Ver blocked requests
az monitor diagnostic-settings create \
--name waf-logs \
--resource /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/waf-blackfriday \
--logs '[{"category":"FrontdoorAccessLog","enabled":true},{"category":"FrontdoorWebApplicationFirewallLog","enabled":true}]' \
--workspace /subscriptions/$SUB_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.OperationalInsights/workspaces/law-prod
Query Log Analytics:
AzureDiagnostics
| where Category == "FrontdoorWebApplicationFirewallLog"
| where action_s == "Block"
| summarize Count = count() by ruleName_s, clientIP_s
| order by Count desc
Costes Black Friday
Estimación:
Front Door Premium: $35/month base + $0.25/GB egress + $0.018/10k requests
WAF: Incluido en Premium
Origins: 2x App Service P3V3 (~$400/month c/u durante Nov-Dic)
Black Friday (1 día):
- 50M requests: $90
- 5 TB egress: $1,250
- Origins escalados: $27 (1 día)
Total Black Friday: ~$1,400
Tráfico normal (resto mes): ~$500
Total Noviembre: ~$1,900 (vs $15,000 sin CDN/caching)