Turning an Ingress Migration into a Security Upgrade (NGINX → Azure Application Gateway/AGIC)

Ingress migrations aren’t just networking—they’re chances to raise the security bar without slowing delivery. Here’s the playbook that worked for us moving from NGINX Ingress to Azure Application Gateway (AGIC), with Azure Front Door at the outer edge.

1) Mirror before you move
List exactly what your current edge does: TLS versions, HSTS, CORS allowlist, request/body size limits, header rewrites, timeouts, path normalization. If you can’t name it, you can’t keep it.

2) Place controls where they fit best

  • Outer edge (Front Door): WAF, bot protection, geo/IP controls, and rate limiting.
  • Gateway (App Gateway/AGIC): L7 routing, header rewrites, request-size and timeout guardrails.
  • App/service: Final CORS validation and business‑logic auth.

3) Make security headers explicit
Replace ad‑hoc NGINX snippets with gateway rewrite rules so every route gets the same baseline:

  • Strict-Transport-Security (preload + 1y)
  • X-Content-Type-Options: nosniff
  • Referrer-Policy and a conservative Permissions-Policy

4) CORS: exact, not generous
Allow only known origins, set a short max-age, and avoid wildcards with credentials. Keep the same policy at the app to prevent by‑pass.

5) Right-size requests & timeouts
Small max body size and sane idle/read timeouts reduce slow‑loris style abuse and accidental payload bloat.

6) WAF in “detect → enforce”
Start in detection for a sprint, tag exceptions with an issue ID (not global disables), then enforce. Every exception should have an owner and an expiry date.

7) Certs without ceremony
Use Key Vault + managed identity on App Gateway so cert rotation is hands‑off and auditable. Keep cluster TLS simple when the gateway terminates.

8) Observability that tells a story
Correlate Front Door → App Gateway → AKS logs. Track:

  • WAF matches by rule ID
  • 4xx/5xx by route
  • Latency percentiles at each hop
  • Burst traffic vs. rate‑limit events

9) Put it in the pipeline
Manage WAF policies, rewrite sets, and listeners as code (Bicep/Terraform). Add smoke tests (ZAP/k6) to pre‑prod to catch header/CORS regressions before go‑live.

Tiny before/after (illustrative)

Before (NGINX Ingress)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "1m"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header Referrer-Policy "no-referrer-when-downgrade" always;

After (App Gateway rewrite set – concept)

If path starts_with /api/
  Set response header "Strict-Transport-Security" = "max-age=31536000; includeSubDomains; preload"
  Set response header "X-Content-Type-Options" = "nosniff"
  Set response header "Referrer-Policy" = "no-referrer-when-downgrade"
  Set response header "Permissions-Policy" = "geolocation=(), microphone=()"

Security SLOs that keep you honest

  • 100% ingress routes covered by WAF + security-header rewrite set
  • 0 wildcard CORS origins on protected endpoints
  • ≤30 min to roll WAF signature updates to prod
  • ≤7 days lifetime for any WAF exception

30‑day rollout (one sprint at a time)

  • Week 1: Inventory + mapping sheet (NGINX → AGIC/Front Door)
  • Week 2: Deploy WAF in detect, add header/CORS rewrites
  • Week 3: Enforce WAF, shrink request sizes/timeouts, publish SLOs
  • Week 4: Add pre‑prod security tests and remove temporary exceptions

Takeaway: Treat ingress changes as a security refactor. When guardrails are baked into the edge and the pipeline, teams ship faster—and safer.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top