Skip to content

Azure Front Door

Azure Front Door (AFD) Standard is the global entry point for all Microtec ERP traffic. It provides TLS termination, WAF protection, custom domain routing, and origin health monitoring for both backend Container Apps and frontend Static Web Apps.


Architecture Overview


AFD Profile Inventory

All AFD profiles reside in the shared mic-erp-global-rg resource group (not per-environment RGs):

AFD ProfileEnvironmentsDDoS Protection
mic-erp-fddev, stageDisabled
mic-erp-fd-2preprod, uatDisabled
mic-erp-prod-fdproductionDisabled

All AFD Profiles in mic-erp-global-rg

AFD profiles are shared infrastructure. They are NOT deployed into per-environment resource groups. enableDdosProtection is false for all profiles.


Custom Domains per Environment

Each environment has its own set of custom domains configured in AFD:

EnvironmentGateway / API DomainAuth DomainFrontend Domain
devgateway.microtec-test.comauth.microtec-test.com*.microtec-test.com
stagegateway.microtecstage.comauth.microtecstage.com*.microtecstage.com
preprodgateway.microtec-preprod.comauth.microtec-preprod.com*.microtec-preprod.com
uatgateway.microtec-uat.comauth.microtec-uat.com*.microtec-uat.com
productiongateway.onlinemicrotec.com.saauth.onlinemicrotec.com.sa*.onlinemicrotec.com.sa

TLS certificates are managed by AFD (auto-renewed via DigiCert). Wildcard certificates cover all subdomains per environment.


Origin Groups

Backend Origin Group

Routes requests to the Public CAE container apps:

bicep
resource backendOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = {
  name: 'backend-${environment}'
  parent: afdProfile
  properties: {
    loadBalancingSettings: {
      sampleSize: 4
      successfulSamplesRequired: 3
      additionalLatencyInMilliseconds: 50
    }
    healthProbeSettings: {
      probePath: '/health/live'
      probeRequestType: 'GET'
      probeProtocol: 'Https'
      probeIntervalInSeconds: 30
    }
    sessionAffinityState: 'Disabled'
  }
}

Origins in this group:

ServiceOrigin FQDNPort
Gateway.API{cae-name}.{region}.azurecontainerapps.io443
Keycloak{cae-name}.{region}.azurecontainerapps.io443

Frontend Origin Group

Routes requests to Static Web Apps or Blob Storage:

bicep
resource frontendOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = {
  name: 'frontend-${environment}'
  parent: afdProfile
  properties: {
    loadBalancingSettings: {
      sampleSize: 4
      successfulSamplesRequired: 2
      additionalLatencyInMilliseconds: 0
    }
    healthProbeSettings: {
      probePath: '/index.html'
      probeRequestType: 'HEAD'
      probeProtocol: 'Https'
      probeIntervalInSeconds: 60
    }
  }
}

Route Rules

AFD routes requests based on domain + path pattern:

Route NameDomain PatternPath PatternOrigin GroupDescription
api-routeapi.*/*BackendAll API calls → Gateway
auth-routeauth.*/*Backend (Keycloak)Keycloak OIDC traffic
frontend-routeapp.*/*FrontendAngular MFE apps
admin-blockauth.*/admin/*WAF rule blocks non-office IPs

Bicep Route Example

bicep
resource apiRoute 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = {
  name: 'api-route'
  parent: afdEndpoint
  properties: {
    originGroup: { id: backendOriginGroup.id }
    supportedProtocols: ['Https']
    patternsToMatch: ['/*']
    forwardingProtocol: 'HttpsOnly'
    linkToDefaultDomain: 'Enabled'
    httpsRedirect: 'Enabled'
    customDomains: [{ id: apiCustomDomain.id }]
    cacheConfiguration: {
      queryStringCachingBehavior: 'IgnoreQueryString'
      compressionSettings: {
        contentTypesToCompress: ['application/json']
        isCompressionEnabled: true
      }
    }
  }
}

WAF Policy

AFD Standard uses a Standard_AzureFrontDoor SKU WAF policy attached to the profile. Each environment gets its own WAF policy for independent tuning.

Default Ruleset

bicep
resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' = {
  name: 'mic-erp-${environment}-waf'
  sku: { name: 'Standard_AzureFrontDoor' }
  properties: {
    policySettings: {
      mode: 'Prevention'
      enabledState: 'Enabled'
    }
    managedRules: {
      managedRuleSets: [
        {
          ruleSetType: 'Microsoft_DefaultRuleSet'
          ruleSetVersion: '2.1'
          ruleSetAction: 'Block'
        }
        {
          ruleSetType: 'Microsoft_BotManagerRuleSet'
          ruleSetVersion: '1.0'
        }
      ]
    }
  }
}

Custom Rules

Rule NamePriorityConditionAction
BlockKeycloakAdmin100Path starts with /admin/ AND IP not in office rangeBlock
AllowOfficeIPs90Source IP in {office-ip-list}Allow
RateLimitLogin200Path /protocol/openid-connect/tokenRate limit (100 req/min per IP)
BlockSQLi300Detected SQL injection patternBlock
GeoBlockHighRisk400Source country in high-risk listBlock (prod only)

WAF Detection Mode for New Rules

When adding new custom WAF rules, first set them to Detection mode for 48 hours and monitor the WAF logs before switching to Prevention mode. Overly broad rules have caused legitimate traffic to be blocked in the past.


Health Probes

AFD actively probes each origin to detect failures:

EndpointIntervalThresholdAction on Failure
/health/live (Gateway)30s3 failuresMark origin unhealthy, re-route
/health/ready (Keycloak)30s3 failuresMark origin unhealthy
/index.html (Frontend)60s2 failuresFall back to secondary origin

Health probe requests originate from AFD edge nodes. Ensure the backend health/live endpoint does NOT require authentication and does NOT count against rate limits.


Cache Configuration

AFD caches static assets for frontend origins:

Content TypeCache DurationRules
text/htmlNo cacheAlways fetch (index.html must be fresh)
application/javascript30 daysCache by URL (includes content hash)
text/css30 daysCache by URL
image/*, font/*365 daysLong-term cache
application/json (API)No cacheAPIs are not cached

Angular MFE builds output content-hashed filenames (e.g., main.abc12345.js), making long-term caching safe for JS/CSS assets.

Cache Purge

Cache is purged automatically by the update-afd.yml pipeline template after each frontend deployment:

bash
az afd endpoint purge \
  --resource-group mic-erp-fr-{env}-network-rg \
  --profile-name mic-erp-afd \
  --endpoint-name mic-erp-{env}-endpoint \
  --domains app.{env-domain} \
  --content-paths '/*'

Logs and Diagnostics

AFD logs are sent to the Log Analytics Workspace:

bash
# Query WAF block events (last hour)
az monitor log-analytics query \
  --workspace {workspace-id} \
  --analytics-query \
    "AzureDiagnostics
     | where Category == 'FrontdoorWebApplicationFirewallLog'
     | where action_s == 'Block'
     | where TimeGenerated > ago(1h)
     | project TimeGenerated, clientIP_s, requestUri_s, ruleName_s"

Internal Documentation — Microtec Platform Team