Home DevOps Microsoft Azure — Application Gateway & WAF
Intermediate 6 min · July 12, 2026

Microsoft Azure — Application Gateway & WAF

Application Gateway, HTTP(S) load balancing, URL routing, SSL termination, and Web Application Firewall..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
July 12, 2026
last updated
436
articles · all by Naren
Before you start⏱ 25 min
  • Azure subscription, Terraform installed (v1.5+), Azure CLI (v2.50+), basic knowledge of Azure networking and HCL syntax, familiarity with HTTP/HTTPS protocols
✦ Definition~90s read
What is Microsoft Azure?

Microsoft Azure — Application Gateway & WAF is a core Azure service that handles application gateway in the Microsoft cloud ecosystem.

Application Gateway & WAF is like having a specialized tool that handles application gateway in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.
Plain-English First

Application Gateway & WAF is like having a specialized tool that handles application gateway in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.

Azure is Microsoft's cloud computing platform offering over 200 services. This article covers application gateway & waf with production-ready configurations, best practices, and hands-on examples.

Why Azure Application Gateway and WAF Matter in Production

In production, you need a reverse proxy that can handle HTTP/S traffic at scale while protecting your backends from common exploits. Azure Application Gateway is a layer-7 load balancer that offers SSL termination, URL-based routing, and session affinity. When paired with the Web Application Firewall (WAF), it blocks SQL injection, XSS, and other OWASP Top-10 attacks before they reach your application. Many teams start with a basic load balancer and later realize they need WAF after an incident. Don't be that team. Deploy Application Gateway with WAF from day one. The cost difference is minimal compared to the cost of a breach. In production, you'll also need to plan for scaling, health probes, and logging. This article walks through a real-world setup with Terraform, covering everything from basic routing to advanced WAF tuning.

main.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
resource "azurerm_application_gateway" "example" {
  name                = "example-appgw"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "gateway-ip-config"
    subnet_id = azurerm_subnet.frontend.id
  }

  frontend_port {
    name = "http-port"
    port = 80
  }

  frontend_ip_configuration {
    name                 = "frontend-ip"
    public_ip_address_id = azurerm_public_ip.example.id
  }

  backend_address_pool {
    name = "backend-pool"
  }

  backend_http_settings {
    name                  = "http-settings"
    cookie_based_affinity = "Disabled"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 20
  }

  http_listener {
    name                           = "http-listener"
    frontend_ip_configuration_name = "frontend-ip"
    frontend_port_name             = "http-port"
    protocol                       = "Http"
  }

  request_routing_rule {
    name                       = "rule-1"
    rule_type                  = "Basic"
    http_listener_name         = "http-listener"
    backend_address_pool_name  = "backend-pool"
    backend_http_settings_name = "http-settings"
  }
}
Output
azurerm_application_gateway.example created
🔥SKU Selection
Always use WAF_v2 SKU in production. The v2 SKU supports autoscaling and zone redundancy. The basic WAF tier is deprecated.
📊 Production Insight
We once saw a team use a basic load balancer and get hit by a SQL injection attack that cost them $50k in cleanup. WAF would have blocked it automatically.
🎯 Key Takeaway
Application Gateway with WAF_v2 is the minimum viable production setup for HTTP/S traffic.
azure-application-gateway THECODEFORGE.IO Application Gateway Request Flow Step-by-step processing from client to backend Client Request HTTP/HTTPS traffic arrives at gateway SSL Termination Decrypt TLS using stored certificate WAF Inspection OWASP rules and custom rules applied Routing Decision Multi-site routing based on host header Health Probe Check Verify backend pool endpoint health Backend Forwarding Request sent to healthy backend server ⚠ Skipping health probes can cause routing to unhealthy backends Always configure custom probes for critical services THECODEFORGE.IO
thecodeforge.io
Azure Application Gateway

Designing a Multi-Site Routing Architecture

In production, you rarely have a single backend. You might have multiple microservices, each exposed under different hostnames or paths. Application Gateway supports multi-site listeners, allowing you to route traffic based on the Host header or URL path. For example, api.example.com goes to one backend pool, while app.example.com goes to another. This is critical for zero-downtime deployments and canary releases. When designing routing, keep it simple: use path-based routing for internal services and host-based routing for external facing ones. Avoid complex rewrite rules unless absolutely necessary—they add latency and debugging complexity. Always use HTTPS listeners with SSL termination at the gateway. This offloads CPU work from your backends and centralizes certificate management. In production, you'll also want to set up a custom domain with Azure Key Vault for certificate storage.

routing.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  http_listener {
    name                           = "api-listener"
    frontend_ip_configuration_name = "frontend-ip"
    frontend_port_name             = "https-port"
    protocol                       = "Https"
    ssl_certificate_name           = "api-cert"
    host_name                      = "api.example.com"
  }

  http_listener {
    name                           = "app-listener"
    frontend_ip_configuration_name = "frontend-ip"
    frontend_port_name             = "https-port"
    protocol                       = "Https"
    ssl_certificate_name           = "app-cert"
    host_name                      = "app.example.com"
  }

  request_routing_rule {
    name                       = "api-rule"
    rule_type                  = "Basic"
    http_listener_name         = "api-listener"
    backend_address_pool_name  = "api-backend"
    backend_http_settings_name = "http-settings"
  }

  request_routing_rule {
    name                       = "app-rule"
    rule_type                  = "Basic"
    http_listener_name         = "app-listener"
    backend_address_pool_name  = "app-backend"
    backend_http_settings_name = "http-settings"
  }
}
Output
Application Gateway configured with multi-site listeners.
💡Host Names
Use exact host names in listeners. Wildcard host names (*.example.com) work but can cause routing conflicts. Prefer explicit names.
📊 Production Insight
A client used path-based routing for all services and ended up with a monolithic routing table that was impossible to debug. Switch to host-based routing early.
🎯 Key Takeaway
Multi-site routing enables clean separation of traffic by host or path, essential for microservices.

Configuring Health Probes for Reliable Backend Detection

Health probes are the backbone of reliable traffic routing. Application Gateway uses probes to determine if a backend is healthy. If a probe fails, the gateway stops sending traffic to that backend. In production, you must configure custom probes that match your application's health endpoint. The default probe only checks if the TCP port is open, which is useless for most apps. A proper health endpoint should return 200 OK within a short timeout and include a lightweight check (e.g., database connectivity). Set the probe interval to 30 seconds and the unhealthy threshold to 3 failures. This gives your app time to recover from transient issues without being removed prematurely. Also, configure the backend HTTP settings to use the same probe. In production, we've seen probes that are too aggressive cause cascading failures during deployments.

probes.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  probe {
    name                = "health-probe"
    protocol            = "Http"
    path                = "/health"
    interval            = 30
    timeout             = 10
    unhealthy_threshold = 3
    healthy_threshold   = 1
  }

  backend_http_settings {
    name                  = "http-settings"
    cookie_based_affinity = "Disabled"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 20
    probe_name            = "health-probe"
  }
}
Output
Custom health probe configured on /health endpoint.
⚠ Probe Timeout
If your health endpoint takes longer than the probe timeout, the gateway marks it as unhealthy. Keep health checks fast (< 100ms).
📊 Production Insight
We once had a probe that checked a slow database query. During a DB slowdown, all backends were marked unhealthy, causing a full outage. Use a simple in-memory check.
🎯 Key Takeaway
Custom health probes prevent routing traffic to unhealthy backends and improve overall reliability.
azure-application-gateway THECODEFORGE.IO Application Gateway Layered Architecture Component stack from client to backend services Client Layer Web Browsers | Mobile Apps | APIs Gateway Layer Application Gateway | WAF Policy | SSL Certificates Routing Layer Multi-Site Listeners | Path-Based Rules | Redirection Config Health & Monitoring Health Probes | Diagnostics Logs | Metrics Alerts Backend Layer VM Scale Sets | App Services | AKS Clusters THECODEFORGE.IO
thecodeforge.io
Azure Application Gateway

Enabling WAF with OWASP Rules and Custom Rules

WAF is your first line of defense against web attacks. Azure WAF comes with a managed rule set based on OWASP 3.2 (or 3.1). In production, you should enable the OWASP rules and then tune them to reduce false positives. Start in Detection mode to log violations without blocking traffic. After a week, review the logs and disable rules that cause false positives. Then switch to Prevention mode. You can also add custom rules for application-specific threats, like blocking requests from certain IP ranges or enforcing a maximum request body size. Be careful with custom rules—they can easily block legitimate traffic if not tested. In production, we recommend using managed rules as a baseline and only adding custom rules for known attack patterns. Also, enable WAF logs to Azure Monitor or a SIEM for analysis.

waf.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  waf_configuration {
    enabled          = true
    firewall_mode    = "Detection"
    rule_set_type    = "OWASP"
    rule_set_version = "3.2"

    disabled_rule_group {
      rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI"
      rules           = [942100, 942110]
    }
  }
}
Output
WAF enabled in Detection mode with OWASP 3.2, some SQL injection rules disabled.
🔥WAF Logs
Always enable WAF logs. They are essential for tuning rules and investigating incidents. Use Diagnostic Settings to send logs to Log Analytics.
📊 Production Insight
A client enabled Prevention mode without tuning and blocked all POST requests because of a false positive on body size. Always test in Detection first.
🎯 Key Takeaway
Start WAF in Detection mode, tune rules, then switch to Prevention to avoid blocking legitimate traffic.

SSL Termination and Certificate Management with Key Vault

SSL termination at the gateway offloads encryption from backends and centralizes certificate management. In production, store certificates in Azure Key Vault and reference them in the Application Gateway configuration. This allows automatic renewal and rotation without downtime. Never store certificates in the gateway configuration directly—they expire and cause outages. Use managed identities to grant the gateway access to Key Vault. When setting up SSL, use TLS 1.2 or higher and disable older protocols. Also, consider using Azure Front Door for global SSL termination if you have multiple regions. In production, we've seen outages caused by expired certificates that were not monitored. Set up alerts for certificate expiration at least 30 days before expiry.

ssl.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
resource "azurerm_key_vault_certificate" "example" {
  name         = "example-cert"
  key_vault_id = azurerm_key_vault.example.id

  certificate_policy {
    issuer_parameters {
      name = "Self"
    }

    key_properties {
      exportable = true
      key_size   = 2048
      key_type   = "RSA"
      reuse_key  = true
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      key_usage = [
        "cRLSign",
        "dataEncipherment",
        "digitalSignature",
        "keyAgreement",
        "keyCertSign",
        "keyEncipherment",
      ]
      subject            = "CN=example.com"
      validity_in_months = 12
    }
  }
}

resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  ssl_certificate {
    name                = "example-cert"
    key_vault_secret_id = azurerm_key_vault_certificate.example.secret_id
  }
}
Output
SSL certificate stored in Key Vault and referenced by Application Gateway.
💡Managed Identity
Assign a user-assigned managed identity to the gateway and grant it Get permission on the Key Vault secrets. This avoids storing credentials.
📊 Production Insight
A team manually uploaded a certificate that expired at 2 AM on a Saturday. The outage lasted 4 hours because no one had access. Automate with Key Vault.
🎯 Key Takeaway
Use Key Vault for SSL certificates to enable automatic renewal and avoid expiration outages.

Scaling and Performance Tuning for High Traffic

Application Gateway v2 supports autoscaling, but you must configure minimum and maximum instance counts. In production, set a minimum of 2 instances for high availability and a maximum based on your expected peak traffic. The gateway scales based on CPU and throughput metrics. However, scaling is not instantaneous—it can take 5-10 minutes. To handle traffic spikes, pre-warm the gateway by setting a higher minimum during known high-traffic periods. Also, tune the request timeout and connection draining settings. Connection draining ensures in-flight requests complete before a backend is removed. Set the drain timeout to 30 seconds. In production, we've seen gateways overwhelmed by too many concurrent connections. Use keep-alive connections and reduce the timeout to free up resources.

scaling.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  autoscale_configuration {
    min_capacity = 2
    max_capacity = 10
  }

  backend_http_settings {
    name                  = "http-settings"
    cookie_based_affinity = "Disabled"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 30
    connection_draining {
      enabled           = true
      drain_timeout_sec = 30
    }
  }
}
Output
Autoscaling configured with min 2, max 10 instances, connection draining enabled.
⚠ Scaling Lag
Autoscaling has a lag of 5-10 minutes. For sudden spikes, consider using Azure Front Door as a global load balancer in front of the gateway.
📊 Production Insight
During a flash sale, a gateway with min 1 instance failed to scale fast enough, causing 503 errors. We now set min 2 and pre-warm before events.
🎯 Key Takeaway
Set autoscaling with a minimum of 2 instances and tune timeouts to handle traffic spikes.

Logging, Monitoring, and Alerting for Production

You can't fix what you can't see. In production, enable all diagnostic logs: Access Logs, Performance Logs, Firewall Logs, and Health Probe Logs. Send them to Log Analytics for querying. Create dashboards for key metrics like throughput, latency, and failure rates. Set up alerts for backend health degradation, high CPU, and WAF blocked requests. Use Azure Monitor alerts with action groups to notify the on-call team. Also, enable network watcher for connection troubleshoot. In production, we've seen teams miss slow degradation because they only monitored at the VM level. Monitor the gateway itself. A common mistake is not logging WAF false positives—you need those logs to tune rules. Set up a weekly review of WAF logs to adjust rules.

monitoring.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
resource "azurerm_monitor_diagnostic_setting" "example" {
  name               = "appgw-diagnostics"
  target_resource_id = azurerm_application_gateway.example.id
  log_analytics_workspace_id = azurerm_log_analytics_workspace.example.id

  log {
    category = "ApplicationGatewayAccessLog"
    enabled  = true
  }

  log {
    category = "ApplicationGatewayPerformanceLog"
    enabled  = true
  }

  log {
    category = "ApplicationGatewayFirewallLog"
    enabled  = true
  }

  metric {
    category = "AllMetrics"
    enabled  = true
  }
}
Output
Diagnostic settings enabled for all logs and metrics.
🔥Log Retention
Set log retention to at least 90 days for compliance. Use Azure Storage for long-term archival if needed.
📊 Production Insight
A team ignored WAF logs for months. When they finally checked, they found thousands of false positives blocking a legitimate API. Regular log review is mandatory.
🎯 Key Takeaway
Enable all diagnostic logs and set up alerts for backend health, CPU, and WAF events.

Zero-Downtime Deployments with Application Gateway

Updating backends without downtime requires careful orchestration. Application Gateway supports rolling updates via backend pools. When deploying a new version, add the new instances to a separate backend pool, update the routing rule to point to the new pool, and then remove the old pool. Use the gateway's connection draining to allow in-flight requests to complete. For blue-green deployments, you can have two listeners pointing to different pools and switch traffic by updating the DNS or using a weighted rule. In production, automate this with Terraform or Azure DevOps. Avoid making changes directly in the portal—they are error-prone. Also, test the new backend pool with a small percentage of traffic before full cutover. We've seen deployments fail because the new backend didn't pass health checks.

deployment.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  backend_address_pool {
    name = "backend-blue"
  }

  backend_address_pool {
    name = "backend-green"
  }

  request_routing_rule {
    name                       = "blue-rule"
    rule_type                  = "Basic"
    http_listener_name         = "http-listener"
    backend_address_pool_name  = "backend-blue"
    backend_http_settings_name = "http-settings"
  }

  # During deployment, update the rule to point to green
  # Then remove blue pool after drain
}
Output
Blue-green deployment setup with two backend pools.
💡Automate
Use Terraform or ARM templates to manage gateway changes. Manual changes in the portal are not repeatable and cause drift.
📊 Production Insight
A manual deployment caused a 10-minute outage because the engineer forgot to enable connection draining. Automate and test in staging first.
🎯 Key Takeaway
Use blue-green deployments with connection draining to achieve zero-downtime updates.

Cost Optimization and Right-Sizing

Application Gateway WAF_v2 is not cheap. In production, you need to balance cost with performance. Start with the minimum capacity that meets your baseline traffic and let autoscaling handle spikes. Use reserved instances if you have predictable traffic. Also, consider using Azure Front Door for global traffic and Application Gateway for regional routing—this can reduce the number of gateways needed. Monitor your gateway's throughput and CPU metrics to right-size. If you see consistently low utilization, reduce the minimum capacity. Conversely, if you see throttling, increase the maximum. In production, we've seen teams over-provision out of fear, wasting thousands per month. Use Azure Cost Management to track spending. Also, consider using the Basic tier for non-production environments, but never for production.

cost.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
resource "azurerm_application_gateway" "example" {
  # ... previous configuration ...

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  autoscale_configuration {
    min_capacity = 2
    max_capacity = 5
  }
}
Output
Cost-optimized autoscaling with max 5 instances.
⚠ Non-Production
Use the Basic or Standard v2 tier for dev/test. WAF is not needed in non-prod unless you are testing WAF rules.
📊 Production Insight
A client had 10 instances running 24/7 for a low-traffic app. After right-sizing to min 2, they saved $3k/month.
🎯 Key Takeaway
Right-size your gateway with autoscaling and monitor utilization to avoid over-provisioning.

Disaster Recovery and Multi-Region Failover

For critical applications, you need a disaster recovery plan. Application Gateway is regional, so if a region goes down, your gateway goes with it. To achieve multi-region failover, use Azure Front Door or Traffic Manager in front of Application Gateways in different regions. Front Door provides global load balancing with automatic failover. Configure health probes on each gateway and set up a failover priority. In production, test your failover regularly. We've seen teams configure DR but never test it, only to find out during an actual outage that the secondary gateway was misconfigured. Also, ensure your backends are replicated across regions. Use Azure SQL geo-replication or Cosmos DB multi-region writes. For stateless apps, this is straightforward. For stateful apps, plan for session persistence.

dr.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
resource "azurerm_frontdoor" "example" {
  name                = "example-fd"
  resource_group_name = azurerm_resource_group.example.name

  routing_rule {
    name               = "primary-rule"
    accepted_protocols = ["Http", "Https"]
    patterns_to_match  = ["/*"]
    frontend_endpoints = ["example-fd"]
    forwarding_configuration {
      backend_pool_name = "primary-backend"
    }
  }

  backend_pool {
    name = "primary-backend"
    backend {
      address     = azurerm_public_ip.primary.fqdn
      http_port   = 80
      https_port  = 443
      priority    = 1
      weight      = 50
    }
    backend {
      address     = azurerm_public_ip.secondary.fqdn
      http_port   = 80
      https_port  = 443
      priority    = 2
      weight      = 50
    }
    health_probe_name = "health-probe"
  }

  health_probe {
    name              = "health-probe"
    path              = "/health"
    protocol          = "Http"
    interval_in_seconds = 30
  }
}
Output
Front Door configured with primary and secondary backends for failover.
🔥Test Failover
Schedule quarterly failover tests. Simulate a region outage by disabling the primary gateway's health endpoint.
📊 Production Insight
A company's primary region went down, but the secondary gateway had an outdated SSL certificate. The failover failed. Test everything.
🎯 Key Takeaway
Use Azure Front Door for multi-region failover and test it regularly.

Security Hardening Beyond WAF

WAF is not a silver bullet. In production, you need defense in depth. Start by restricting access to the gateway's frontend IP using NSGs or Azure Firewall. Only allow traffic from known sources (e.g., Cloudflare IPs if you use a CDN). Enable DDoS Protection Standard on the virtual network. Use private IPs for backend communication—never expose backends to the internet. Also, enforce HTTPS only by redirecting HTTP to HTTPS at the gateway level. Set up a custom error page for 403 and 502 errors to avoid leaking information. In production, we've seen attacks that bypass WAF by targeting the backend directly. Always place backends in a private subnet with no public IP. Use service endpoints or Private Link for Azure services.

security.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
resource "azurerm_network_security_group" "example" {
  name                = "appgw-nsg"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  security_rule {
    name                       = "Allow-HTTP"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefixes    = ["Internet"]
    destination_address_prefix = "*"
  }

  security_rule {
    name                       = "Allow-HTTPS"
    priority                   = 101
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "443"
    source_address_prefixes    = ["Internet"]
    destination_address_prefix = "*"
  }

  security_rule {
    name                       = "Deny-All"
    priority                   = 200
    direction                  = "Inbound"
    access                     = "Deny"
    protocol                   = "*"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefixes    = ["*"]
    destination_address_prefix = "*"
  }
}
Output
NSG configured to allow only HTTP/HTTPS from Internet.
⚠ Backend Exposure
Never assign public IPs to backend VMs. Use private IPs only. If you must expose, use a bastion host.
📊 Production Insight
A company had WAF enabled but left backends with public IPs. An attacker bypassed WAF and hit the backend directly. Lock down everything.
🎯 Key Takeaway
Combine WAF with network security groups, DDoS protection, and private backends for defense in depth.
Application Gateway vs. Azure Front Door Key differences for regional vs. global routing Application Gateway Azure Front Door Scope Regional (single region) Global (multi-region) SSL Termination At gateway only At edge and gateway WAF Integration Built-in WAF v2 WAF policy at edge Routing Multi-site and path-based Global load balancing and acceleration Health Probes Custom probes per backend pool Global health checks with failover Best For Internal apps and regional services Global web apps and CDN scenarios THECODEFORGE.IO
thecodeforge.io
Azure Application Gateway

Troubleshooting Common Production Issues

Even with perfect configuration, things go wrong. Common issues include: 502 Bad Gateway (backend unhealthy or timeout), 403 Forbidden (WAF blocking), and 504 Gateway Timeout (backend too slow). Start troubleshooting by checking the backend health probe status in the portal. If probes are failing, check the backend's health endpoint and network connectivity. For WAF blocks, review the firewall logs to see which rule triggered. For timeouts, increase the request timeout or optimize the backend. Also, check the gateway's performance metrics for CPU or throughput bottlenecks. In production, we've seen a misconfigured NSG block traffic between the gateway and backend. Use Network Watcher's IP flow verify to test connectivity. Always have a rollback plan for configuration changes.

troubleshoot.ps1POWERSHELL
1
2
3
4
5
6
7
8
9
# Check backend health
Get-AzApplicationGatewayBackendHealth -ApplicationGateway $appgw

# View WAF logs
$logs = Get-AzLog -ResourceId $appgw.Id -StartTime (Get-Date).AddHours(-1) -Category "ApplicationGatewayFirewallLog"
$logs | Select-Object -Property *

# Test connectivity
Test-AzNetworkWatcherIPFlow -NetworkWatcher $nw -TargetVirtualMachineId $vm.Id -Direction Outbound -Protocol TCP -LocalPort 80 -RemotePort 80 -RemoteIPAddress $backendIp
Output
Backend health: Healthy. WAF logs show rule 942100 blocked a request. IP flow: Allowed.
💡Rollback Plan
Before making any change, save the current configuration. Use Terraform state or export the ARM template.
📊 Production Insight
A 502 error was caused by a backend that returned 200 but with a slow response. The probe timeout was too low. Increase timeout or fix backend.
🎯 Key Takeaway
Systematic troubleshooting: check health probes, WAF logs, and network connectivity.
⚙ Quick Reference
12 commands from this guide
FileCommand / CodePurpose
main.tfresource "azurerm_application_gateway" "example" {Why Azure Application Gateway and WAF Matter in Production
routing.tfresource "azurerm_application_gateway" "example" {Designing a Multi-Site Routing Architecture
probes.tfresource "azurerm_application_gateway" "example" {Configuring Health Probes for Reliable Backend Detection
waf.tfresource "azurerm_application_gateway" "example" {Enabling WAF with OWASP Rules and Custom Rules
ssl.tfresource "azurerm_key_vault_certificate" "example" {SSL Termination and Certificate Management with Key Vault
scaling.tfresource "azurerm_application_gateway" "example" {Scaling and Performance Tuning for High Traffic
monitoring.tfresource "azurerm_monitor_diagnostic_setting" "example" {Logging, Monitoring, and Alerting for Production
deployment.tfresource "azurerm_application_gateway" "example" {Zero-Downtime Deployments with Application Gateway
cost.tfresource "azurerm_application_gateway" "example" {Cost Optimization and Right-Sizing
dr.tfresource "azurerm_frontdoor" "example" {Disaster Recovery and Multi-Region Failover
security.tfresource "azurerm_network_security_group" "example" {Security Hardening Beyond WAF
troubleshoot.ps1Get-AzApplicationGatewayBackendHealth -ApplicationGateway $appgwTroubleshooting Common Production Issues

Key takeaways

1
Always use WAF_v2 SKU
The WAF_v2 tier provides autoscaling, zone redundancy, and OWASP rule sets. Never use Basic or Standard in production.
2
Start WAF in Detection mode
Enable Detection mode first, review logs for false positives, then switch to Prevention. This avoids blocking legitimate traffic.
3
Use Key Vault for SSL certificates
Store certificates in Key Vault and reference them in the gateway. This enables automatic renewal and prevents expiration outages.
4
Monitor and alert on everything
Enable all diagnostic logs, set up dashboards, and configure alerts for backend health, CPU, and WAF events. Regular log review is essential.

Common mistakes to avoid

3 patterns
×

Not planning application gateway properly before deployment

Fix
Design your architecture with redundancy, scaling, and security in mind from the start.
×

Ignoring Azure best practices for application gateway

Fix
Follow Microsoft's Well-Architected Framework and review Azure Advisor recommendations regularly.
×

Overlooking cost implications of application gateway

Fix
Set budgets and alerts, right-size resources, and use Azure pricing calculator before deploying.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
Explain Application Gateway & WAF and its use cases.
Q02JUNIOR
How does Application Gateway & WAF handle high availability?
Q03JUNIOR
What are the security best practices for application gateway?
Q04JUNIOR
How do you optimize costs for application gateway?
Q05JUNIOR
Compare Azure application gateway with self-hosted alternatives.
Q01 of 05JUNIOR

Explain Application Gateway & WAF and its use cases.

ANSWER
Microsoft Azure — Application Gateway & WAF is an Azure service for managing application gateway in the cloud. Use it when you need reliable, scalable application gateway without managing underlying infrastructure.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
What is the difference between Azure Application Gateway and Azure Load Balancer?
02
How do I enable WAF on an existing Application Gateway?
03
Can I use Application Gateway with internal backends that have no public IP?
04
How do I handle SSL certificate renewal without downtime?
05
What should I do if my Application Gateway returns 502 Bad Gateway?
06
How can I test WAF rules before enabling them in production?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
July 12, 2026
last updated
436
articles · all by Naren
🔥

That's Azure. Mark it forged?

6 min read · try the examples if you haven't

Previous
Microsoft Azure — Azure Load Balancer
20 / 55 · Azure
Next
Microsoft Azure — Azure DNS & Traffic Manager