AKS nginx ingress migration before support ends

Choose a supported replacement by routing behaviour, engineering effort and overlap cost—not by whether the YAML converts.

30 October 2026 · 10 min read · Cloudline Consulting

Three engineers reviewing a printed infrastructure diagram and checklist beside laptops in a naturally lit office.

Your AKS nginx ingress migration starts with a replacement decision, not a manifest converter. Microsoft’s critical-security-patch support for the managed application-routing NGINX add-on runs through November 2026, but the recommended Gateway API replacement cannot preserve every NGINX behaviour. Rate limits, Lua and request-size controls can change the answer. Use a behaviour-first scorecard to choose a supported platform, estimate the engineering work and overlap budget, then prove TLS, authentication and rollback before moving production traffic.

In this article
  1. Which replacement preserves your application’s behaviour?
  2. Find the annotations and IP dependencies that decide the work
  3. Map annotations to capabilities before choosing the default
  4. Build a parallel gateway and prove the customer journeys
  5. Price the overlap and the annotation remediation separately
  6. Cut over only while DNS and IP rollback still work
  7. Leave with a migration decision your team can execute

Which replacement preserves your application’s behaviour?

Engineers comparing three infrastructure options on a meeting-room whiteboard.
Choose the platform that preserves the contract your applications depend on. Photo: locusresearch (BY 2.0)
Buyer scorecard Application-routing Gateway API Application Gateway for Containers Gateway API ingress through AKS Istio
Ordinary HTTP/HTTPS routing Sensible starting candidate Azure-managed alternative Managed mesh ingress path
Custom policy requirements Check supported policies Map requirements to supported capabilities Check policies; custom extensions have separate support boundaries
Data-plane ownership Runs in your AKS cluster Traffic processing outside AKS Runs in your AKS cluster
Upgrade responsibility Microsoft-managed add-on; you validate application behaviour Azure-managed service; you validate configuration changes Microsoft-managed mesh; you plan revision upgrades
Azure integration AKS application-routing add-on Azure gateway resource and Kubernetes integration AKS Istio service mesh add-on
Commercial fit Compare cluster and load-balancer costs Price gateway, capacity and overlap Include gateway resources and mesh operations

Use Cloudline’s Behaviour, Ownership, Budget and Exit framework for your AKS nginx ingress migration. Mandatory behaviour is a veto: broken authentication, redirects or timeouts disqualify a candidate. Ownership and budget rank only those that pass. Exit means retaining a workable rollback, not merely exporting YAML.

Application-routing Gateway API is the starting candidate for straightforward ingress, not an automatic winner. Application Gateway for Containers cost needs its own calculation. Neither managed branding nor Gateway API compatibility guarantees nginx annotation migration without application changes.

Planning date: 30 October 2026. Upstream ingress-nginx maintenance ended in March 2026; Microsoft’s managed-add-on security-patch bridge runs through November 2026. These are different deadlines. Target internal cutover by 6 November, leaving at least two weeks for observation and recovery while DNS and IP rollback remain usable.

This decision spans application behaviour, platform operations and spend—the scope of Cloudline’s Kubernetes and cloud services.

A replacement that drops a mandatory control is not the cheaper option.

Share this quote

Find the annotations and IP dependencies that decide the work

An engineer reviewing terminal output on a laptop at a desk.
An ingress inventory must include behaviour and upstream dependencies. Photo: Nicola since 1972 (BY 2.0)

Start the AKS nginx ingress migration with a live inventory, not the default controller name. Set the production resource names and confirm your Kubernetes context before collecting:

RG='rg-saas-prod-uksouth'
CLUSTER='aks-saas-prod-uksouth'
az aks show -g "$RG" -n "$CLUSTER" --query '{version:kubernetesVersion,appRouting:ingressProfile.webAppRouting,nodeRG:nodeResourceGroup}' -o json
kubectl get nginxingresscontrollers -o custom-columns=NAME:.metadata.name,CLASS:.spec.ingressClassName
kubectl get ingress -A -o wide
kubectl get svc -n app-routing-system -o wide
kubectl get ingress -A -o json | jq -r '.items[] | . as $i | (.metadata.annotations // {} | to_entries[]) | select(.key | startswith("nginx.ingress.kubernetes.io/")) | [$i.metadata.namespace,$i.metadata.name,($i.spec.ingressClassName // $i.metadata.annotations["kubernetes.io/ingress.class"] // ""),.key,.value] | @tsv'

Inventory every discovered class, not just webapprouting.kubernetes.azure.com. Include legacy class annotations and classless Ingresses. Microsoft’s migration procedure explicitly covers multiple controllers and their separate public addresses.

The TSV export produces an audit input, not a compatibility verdict for nginx annotation migration. Inspect controller ConfigMaps, snippets and Helm/GitOps definitions too: annotations alone are not the estate.

Inventory unitRecord
Each routeHostname, path, namespace, Service and port, controller class
SecurityCertificate source and renewal owner; authentication mechanism
AccountabilityOwner and acceptance test, including expected redirects and failures
Each controllerService, public IP, Azure resource ID and configuration source

Trace the dependency chain: client → DNS or Front Door → controller public IP → route → Service → pod. Add Traffic Manager, customer allowlists, webhook destinations and fixed-IP consumers. Record who controls each dependency and how long changes take; a healthy gateway does not prove customers can reach it.

Where pre-existing Azure resources need controlled infrastructure ownership, use Terraform import into existing modules alongside reviewed configuration and plans. Import alone does not make ownership changes safe.

Map annotations to capabilities before choosing the default

An engineer recording technical requirements in a notebook beside a laptop.
Each legacy behaviour needs a destination capability and a passing test. Photo: A.Davey (BY 2.0)

For nginx annotation migration, map required behaviour—not annotation names. Native means a documented capability, not identical semantics. Redesign changes the architecture; Custom extension adds team-owned configuration; Blocker means the required control is unavailable in that implementation.

Legacy behaviour Application-routing Gateway API Application Gateway for Containers Istio ingress Support boundary Required test
rewrite-target, use-regex Native: prefix; Redesign: captures Native: documented rewrites; Redesign: captures Native: routing; Redesign: captures No automatic NGINX translation Captures, query strings, trailing slashes
HTTPS redirects Native Native Native Configure redirect and TLS separately Status, hostname, port, query preservation
auth-url, auth-signin Redesign Redesign Custom extension Own the authentication integration Login, callback, cookies, logout
proxy-body-size Blocker Redesign Custom extension Managed default lacks configurable limits Uploads immediately below/above boundary
Header-size controls Blocker Redesign Custom extension Platform ceilings are not configurable parity Large cookies; oversized-header rejection
limit-rps, limit-connections Blocker Redesign Custom extension Own throttle semantics and dependencies Burst, concurrency, replicas, client identity
Snippets/Lua-dependent behaviour Blocker Redesign Custom extension No portable snippet/Lua contract Every programmable branch

A standard prefix rewrite proves neither regex captures nor trailing-slash behaviour. Authentication needs an explicit destination architecture: application middleware, an authentication proxy or a supported gateway integration—not copied annotations.

The managed migration guide identifies unavailable configurable body/header limits, Lua and local/global rate limiting. EnvoyFilter is not an escape hatch for application routing Gateway API.

Application Gateway for Containers documents routing, TLS and WAF capabilities. Neither Application Gateway v2 features nor arbitrary NGINX annotations establish compatibility; external authentication, exact throttling and programmable Lua require redesign.

Istio permits gateway-scoped customisation, but Azure excludes problems caused by custom EnvoyFilter configuration. The specific Istio Gateway API ingress guide describes ingress without requiring workload sidecars.

Do not choose the default while a mandatory control lacks a supported implementation and accountable owner. Hypothetically, /health passes while login redirects loop or an upload boundary changes. Like our cgroup v2 go/no-go gates, this is an explicit compatibility decision—not shared implementation guidance.

Converted YAML is a starting point, not evidence of equivalent behaviour.

Share this quote

Build a parallel gateway and prove the customer journeys

Two engineers comparing application test results at adjacent monitors.
Exercise the production hostname against the new endpoint before changing DNS. Photo: Juan Lauriente (BY 2.0)

Build this parallel gateway only if the application-routing candidate passed your scorecard. This AKS nginx ingress migration example is not a generic replacement for every controller.

Require Azure CLI 2.86.0 or later and AKS-managed Gateway API CRDs; do not install upstream CRDs separately. The edge namespace must already contain TLS Secret api-tls and Service api, exposing port 8080.

az aks update -g "$RG" -n "$CLUSTER" --enable-gateway-api --enable-app-routing-istio

Apply this baseline alongside NGINX. It does not recreate authentication, rate limits or body limits.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public-gateway
  namespace: edge
spec:
  gatewayClassName: approuting-istio
  listeners:
    - name: https
      hostname: api.example.co.uk
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
          - group: ""
            kind: Secret
            name: api-tls
      allowedRoutes:
        namespaces:
          from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api
  namespace: edge
spec:
  parentRefs:
    - name: public-gateway
      sectionName: https
  hostnames:
    - api.example.co.uk
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api
          port: 8080

For managed Key Vault certificates, use the documented listener TLS options and workload identity configuration. The application-routing operator synchronises certificates from Key Vault. Test rotation rather than assuming it works.

Check Gateway Programmed=True and the route’s matching parent conditions: Accepted=True and ResolvedRefs=True. Confirm they reflect the current configuration.

kubectl get gateway public-gateway -n edge -o yaml
kubectl get httproute api -n edge -o yaml

HOST=api.example.co.uk
GW_IP=$(kubectl get gateway public-gateway -n edge \
  -o jsonpath='{.status.addresses[0].value}')

curl --resolve "${HOST}:443:${GW_IP}" "https://${HOST}/api/health"
openssl s_client -connect "${GW_IP}:443" -servername "$HOST" -verify_hostname "$HOST" -verify_return_error </dev/null

Keep production DNS publication outside this parallel test. Use controlled client overrides for browser journeys too, including callback hosts. Never hide certificate failures with -k.

  • Verify trusted chain, hostname SAN and certificate rotation.
  • Exercise valid, expired and missing tokens; login callbacks and cookies; authentication outages must fail closed.
  • Send spoofed forwarded headers. Test body limits at one byte below and above the configured threshold.
  • Exercise throttling and streaming where used, including sustained connections.

Define expected outcomes from the old contract: status, headers, redirects, cookies and connection behaviour—not universal 200 responses. Use backend readiness and draining checks for workload continuity; they do not replace controller migration tests.

Price the overlap and the annotation remediation separately

A calculator beside a notebook containing an infrastructure budget.
The overlap bill and the compatibility work belong on separate budget lines. Photo: adactio (BY 2.0)

Price infrastructure overlap separately from nginx annotation migration. Cheap gateway hours do not make incompatible behaviours cheap to replace.

Use one production cluster in UK South, with 14 days (336 hours) of overlap: one non-WAF Application Gateway for Containers, one frontend and one association. Assume five average capacity units—not a sizing recommendation. Capacity considers connections and throughput; five units are not a universal request-rate allowance.

Copyable cost worksheet

Retrieve GBP retail rates:

curl -fsSG 'https://prices.azure.com/api/retail/prices' --data-urlencode "currencyCode='GBP'" --data-urlencode "\$filter=armRegionName eq 'uksouth' and serviceName eq 'Application Gateway' and priceType eq 'Consumption'" | jq '.Items[] | select(.productName | contains("Containers")) | {productName,skuName,meterName,retailPrice,unitOfMeasure,effectiveStartDate}'

Follow every NextPageLink until empty. Explicitly select non-WAF meters. Archive raw pages: this projection omits meterId. GBP API values are budgeting references, not contracted invoice quotes.

Worksheet entryRecord or calculate
EvidenceRetrieval date, meter IDs, effective dates and units
Four separate hourly rates (£)G: gateway; F: frontend; A: association; C: capacity unit
New AGC overlap336 × (G + F + A + 5C)
730-hour steady state730 × (G + F + A + 5C)

Keep existing baseline and incremental migration spend in separate columns. Use baseline tagging and spend ownership; never charge unchanged production traffic twice. Itemise:

  • Retained NGINX capacity: existing baseline versus any extension.
  • New proxy/control-plane capacity or ALB-controller headroom; incremental nodes and disks if required.
  • Load balancer/public IP charges where applicable; DNS/Key Vault operations.
  • Log ingestion/retention; additional test/egress traffic.

Budget engineering independently

Cloudline’s illustrative model: three engineer-days for inventory and platform setup; half a day per distinct simple behaviour family; two days per incompatible family; two days for acceptance and cutover preparation.

Four simple families and two incompatible families total 11 engineer-days. Add 25% planning contingency: 13.75, approximately 14 days of effort. Two engineers do not automatically mean seven elapsed days: dependencies, review and acceptance constrain parallel work.

Cut over only while DNS and IP rollback still work

Two rows of server racks in a brightly lit data centre.
Preserve both paths until rollback and traffic drain have been demonstrated. Photo: Steve Parker (BY 2.0)

For an AKS nginx ingress migration, every gate needs evidence and a named owner. Any failed gate means no-go.

GateEvidenceOwnerRollback action
Behaviour acceptedAll journeys pass; current-generation Gateway Accepted/Programmed and route Accepted/ResolvedRefs conditions are True.Application leadKeep old path serving.
Old endpoint survivesIndependently tested; old DNS and origin configuration recorded.Platform leadRestore recorded configuration.
TTL reducedPrevious TTL’s cache window has expired since reduction.DNS ownerDelay cutover; retain old endpoint.
Dependencies reversibleFront Door origins, Traffic Manager endpoints, customer allowlists and certificate/DNS automation have named owners and recorded configurations.Change leadRestore every changed dependency.

The application-routing and Istio service mesh Gateway API implementations cannot coexist on one cluster. NGINX can remain alongside either selected target. Comparing these two Istio-based options therefore needs separate clusters or sequential experiments.

Agree estate-specific abort thresholds. Suggested triggers: any authentication bypass, a failed critical upload journey, or five minutes of 5xx exceeding baseline by one percentage point. Agree numerical latency and business-transaction thresholds too.

On abort, restore DNS and every changed origin dependency, then test both paths during cache drain. DNS reversal is not instantaneous; persistent connections can outlast the TTL. Do not promise exact convergence.

Do not move the old controller’s cloud-managed public IP to the new Service. Deleting its owning Service can remove the address even when labelled Static. Keep separate addresses throughout rollback eligibility.

Before deleting controllers, complete an agreed observation period and require negligible old-path traffic, with every residual caller understood. Controller deletion is the point of no return: it ends the simple DNS-only rollback path.

Leave with a migration decision your team can execute

A small engineering team reviewing a checklist around a meeting table.
A useful assessment ends with owners, evidence and an executable decision. Photo: Accretion Disc (BY 2.0)

Your AKS nginx ingress migration should end with a signed retirement decision, not “the new endpoint responds”. A healthy gateway does not prove that customer behaviour survives or that recovery works.

Keep a one-page readiness record

  • Target and alternatives: record the selected controller, rejected options and reasons. For application routing Gateway API, identify the implementation and required features.
  • Behaviour mappings: map mandatory nginx annotations to tested replacements, including rewrites, authentication, timeouts, TLS and client-IP handling.
  • Support boundaries: document who supports each extension, its upgrade constraints and any unsupported dependency.
  • Owners and effort: name accountable engineers for routing, application changes, DNS and recovery. Separate platform effort from annotation remediation, with estimates and dependencies.
  • UK South overlap worksheet: record dated rates, currency, gateway capacity, public IPs, logging and overlap days. Separate temporary duplication from ongoing running costs.
  • Acceptance evidence: link critical-journey results, response comparisons, telemetry and a rehearsed recovery test.
  • DNS/origin rollback: record exact changes, previous values, TTLs, preserved IP dependencies, triggers and the engineer authorised to revert.
  • Old-controller removal gate: require no remaining dependencies or traffic, completed acceptance, an explicitly closed rollback window and owner approval.

Choose one outcome: ready to schedule; ready after named remediation, with owners and dates; or not ready, because a critical behaviour or recovery path remains unresolved. Only the first authorises scheduling controller retirement.

Cloudline’s migration-readiness assessment can produce an annotation/capability map, target recommendation, effort range, overlap budget and go/no-go checklist. Bring sanitised Ingress exports and the names of your critical customer journeys—never private keys or production credentials. Talk to a cloud engineer about migration readiness.

Final thoughts

The right replacement is the one that preserves your required behaviour within a support and ownership model your team can sustain. Make that decision before spending the remaining migration window converting manifests. Inventory the estate, resolve incompatible controls, budget the overlap and rehearse recovery while the old endpoint still works. Cloudline Consulting can help turn sanitised ingress configuration and critical customer journeys into a migration-readiness assessment with a clear target, engineering estimate and evidence-led cutover decision.

Frequently asked questions

When does AKS managed NGINX ingress support end?
Microsoft states that critical-security-patch support for NGINX in the AKS application-routing add-on continues through November 2026. Upstream Ingress NGINX maintenance ended in March 2026. These are different support timelines; the Microsoft bridge applies to the managed add-on, not every self-managed NGINX deployment on AKS.
Is application-routing Gateway API generally available?
Yes. Microsoft announced general availability of the application-routing Gateway API implementation and AKS-managed Gateway API installation in 2026. The June 10 walkthrough also documents integrated Azure DNS and Key Vault TLS configuration. General availability establishes a supported platform option; it does not establish compatibility with your existing annotations.
Will Gateway API preserve my NGINX annotations?
Do not assume it will. Standard routes and implementation-specific annotations describe different configuration models. In particular, the default application-routing implementation cannot configure Lua, request header/body limits or local/global rate limiting. Treat conversion as a draft, then assign each required behaviour a destination capability, support owner and acceptance test.
Can I use Istio ingress without adding application sidecars?
Yes. Gateway API ingress through the AKS Istio service mesh add-on does not require injecting sidecars into application workloads. It is distinct from the application-routing implementation. If advanced behaviour uses custom EnvoyFilter configuration, account for the fact that Azure support does not cover problems caused by that configuration.
How much does Application Gateway for Containers cost during migration?
The service charges separately for its gateway resource, frontend, association and capacity units. A parallel migration also retains the old ingress and can add controller capacity, logs and test traffic. For a 14-day overlap, multiply the selected UK South hourly meters by 336, then add those estate-specific costs.

Sources and further reading

Found this useful? Share it or cite it: