NGINX Ingress Migration Tool

Warning: The community-maintained kubernetes/ingress-nginx project has reached end of maintenance. v1.15.1 (March 19, 2026) is the final release — it will receive no further releases, bugfixes, or security patches. The F5 NGINX Ingress Controller (nginx/kubernetes-ingress) is actively maintained and is the recommended migration target.

Overview

This interactive guide helps you migrate from the community-maintained Kubernetes Ingress NGINX (Ingress-NGINX) controller (kubernetes/ingress-nginx) to the F5 NGINX Ingress Controller (nginx/kubernetes-ingress). It covers 130+ annotation mappings, ConfigMap key translations, and CRD migration examples across three tabs:

  • Getting Started — Background on why to migrate, CRD overviews, installation, and a migration checklist
  • Ingress NGINX Config Analyzer — Paste an Ingress manifest and get automatic migration suggestions with ready-to-use YAML
  • Reference Guide — Complete annotation and ConfigMap mapping tables with side-by-side examples

Why Migrate?

The two controllers take fundamentally different approaches to configuring NGINX in Kubernetes.

  • Kubernetes Ingress NGINX (Ingress-NGINX) is annotation-driven — it relies on annotations and ConfigMap keys to customize NGINX. These are opaque strings with no schema validation — a single Ingress resource may carry dozens of annotations as unstructured key-value pairs.
  • F5 NGINX Ingress Controller is CRD-native — it uses Custom Resource Definitions (VirtualServer, Policy, TransportServer) as its primary config model, providing structured, schema-validated YAML with IDE autocompletion.

While the F5 NGINX Ingress Controller still supports annotations for common settings, CRDs unlock capabilities that annotations cannot express:

  • Schema validation — Kubernetes validates CRD fields at apply time, catching misconfigurations before they reach NGINX
  • Structured configuration — Nested YAML objects replace long annotation strings, making complex routing, traffic splitting, and security policies readable and maintainable
  • Reusability — Policies (rate limiting, auth, WAF) are defined once and attached to any number of routes
  • Layer 4 support — TransportServer CRDs handle TCP/UDP workloads that annotations cannot express
  • IDE and tooling support — CRD schemas enable autocompletion, linting, and documentation in editors and CI pipelines

Phased Migration Strategy

Rather than performing a "big bang" cutover, F5 recommends a phased migration that allows you to validate each workload before decommissioning the community controller. Both controllers can run side-by-side in the same cluster using separate IngressClass resources.

  1. Deploy side-by-side — Install the F5 NGINX Ingress Controller alongside the community controller using a distinct IngressClass (e.g., nginx-nic). This ensures existing traffic is unaffected.
  2. Migrate service-by-service — Update each Ingress resource's ingressClassName to point to the new controller. Convert annotations as described in the Reference Guide, validate routing and TLS behavior, and promote to production before moving on to the next service.
  3. Decommission — After all workloads have been migrated and validated, remove the community controller deployment, its IngressClass, and any unused ConfigMaps.
Tip: Use the Ingress NGINX Config Analyzer tab to process each Ingress manifest during step 2. It will flag unsupported annotations and generate the equivalent F5 NGINX Ingress Controller configuration.

CRDs Summary

The F5 NGINX Ingress Controller uses Custom Resource Definitions (CRDs) to extend Kubernetes with NGINX-specific configuration. CRDs provide type-safe, validated configuration that goes beyond what standard Ingress annotations can offer.

VirtualServer CRD

The primary CRD for configuring HTTP/HTTPS load balancing. It replaces Ingress resources and provides advanced traffic management capabilities with full validation.

  • Traffic Splitting: Route percentages of traffic to different backends for canary/blue-green deployments
  • Content-Based Routing: Route based on headers, cookies, arguments, or variables
  • Path Rewriting: Modify request URIs with regex support before forwarding to backends
  • Error Pages: Custom responses for specific HTTP error codes
  • Request/Response Headers: Add, modify, or remove headers in transit
  • Health Checks: Active health monitoring of upstream servers
  • Session Persistence: Cookie-based sticky sessions

VirtualServerRoute CRD

Enables delegation of route configuration to different namespaces. Allows teams to manage their own routing rules while maintaining centralized control over the domain.

  • Cross-Namespace Routing: Reference services in different namespaces
  • Path Delegation: Delegate path prefixes to other teams/namespaces
  • Independent Updates: Teams update routes without modifying the parent VirtualServer
  • Access Control: Limit which namespaces can define routes for a host

Policy CRD

Reusable security and traffic policies that can be attached to VirtualServers or specific routes. Policies enable consistent security controls across multiple applications.

  • Rate Limiting: Limit request rates by IP, header, or custom key
  • Access Control: IP allowlists and denylists
  • Basic Auth: Username/password authentication via htpasswd
  • JWT Validation: Validate JSON Web Tokens (Plus)
  • OIDC: Native OpenID Connect integration (Plus)
  • API Key Auth: Authenticate via API keys in headers/query
  • mTLS: Client certificate verification (ingress) and backend TLS (egress)
  • WAF: F5 WAF for NGINX web application firewall (Plus)

TransportServer CRD

Configures TCP/UDP load balancing for non-HTTP protocols. Essential for databases, message queues, gaming servers, and other Layer 4 applications.

  • TCP Load Balancing: MySQL, PostgreSQL, Redis, custom TCP services
  • UDP Load Balancing: DNS, RADIUS, gaming protocols
  • TLS Passthrough: Pass encrypted traffic directly to backends
  • Health Checks: TCP/UDP health monitoring
  • Session Persistence: IP hash-based session affinity

GlobalConfiguration CRD

Cluster-wide configuration for the F5 NGINX Ingress Controller. Defines global listeners for TCP/UDP and TLS passthrough that TransportServers can reference.

  • TCP/UDP Listeners: Define ports for non-HTTP traffic
  • TLS Passthrough Listeners: Configure SNI-based routing
  • Global Settings: Controller-wide configuration options

Installing CRDs

CRDs can be installed via Helm or manually using manifests, depending on your deployment method. See the F5 NGINX Ingress Controller installation docs for full instructions.

Helm (example)

If you install the F5 NGINX Ingress Controller via Helm, CRDs are included automatically. To ensure they are enabled:

helm install nginx-ingress oci://ghcr.io/nginx/charts/nginx-ingress --version 2.6.1 --set controller.enableCustomResources=true

The controller.enableCustomResources flag is true by default. If you previously disabled it, re-enable it to use CRD resources. See the Helm installation guide for details.

Manifests (example)

If you deploy using manifests, install CRDs manually before deploying the controller:

kubectl apply -f https://raw.githubusercontent.com/nginx/kubernetes-ingress/v5.5.1/deploy/crds.yaml

Replace the version number with your target controller version. See the manifest installation guide for the full step-by-step process.

Note: The crds.yaml file contains all CRDs (VirtualServer, VirtualServerRoute, Policy, TransportServer, GlobalConfiguration) in a single manifest.
Note: Replace version numbers with your target controller version.

Migration Checklist

Progress is saved in your browser.
  • Install CRDs via Helm (controller.enableCustomResources=true) or manifests (deploy/crds.yaml)
  • Review annotation mappings — not all nginx.ingress.kubernetes.io/ annotations have a direct nginx.org/ equivalent (see NGINX Mappings)
  • Map rewrite-target annotation to nginx.org/rewrite-target (not nginx.org/rewrites)
  • Migrate ConfigMap keys that differ between controllers (see ConfigMap Mappings)
  • Convert HSTS ConfigMap keys to nginx.org/hsts annotations for per-Ingress control
  • Convert server-tokens ConfigMap key to nginx.org/server-tokens annotation
  • Convert access control annotations to Policy CRD (accessControl)
  • Convert authentication annotations to Policy CRD (apiKey, basicAuth, externalAuth, jwt, oidc)
  • Convert canary/traffic splitting to VirtualServer splits/matches
  • Convert mTLS annotations to ingressMTLS/egressMTLS policies
  • Convert CORS annotations to the cors Policy CRD via nginx.org/policies (v5.4.0+), falling back to snippets only where needed
  • Convert custom error pages to VirtualServer errorPages
  • Convert header manipulation to VirtualServer requestHeaders/responseHeaders
  • Convert rate limiting annotations to Policy CRD (rateLimit)
  • Convert redirect annotations to VirtualServer action.redirect
  • Convert session affinity annotations to VirtualServer upstream sessionCookie
  • Convert SSL passthrough to TransportServer CRD
  • Convert TCP/UDP services to TransportServer CRD
  • Replace ssl-redirect with nginx.org/ssl-redirect (not the deprecated ingress.kubernetes.io/ssl-redirect)
  • Verify snippets (configuration-snippet, server-snippet) use F5 NGINX Ingress Controller equivalents
  • Test in staging environment
  • Update monitoring and alerting

Additional Resources