Skip to main content
logoTetrate AI Agent AcceleratorsVersion: Latest

NGINX Ingress to TEG Resource Mapping

This document provides comprehensive documentation on how NGINX Ingress Controller annotations are converted to Tetrate Enterprise Gateway (TEG) resources. Use this guide for migrating from NGINX Ingress to TEG.

Resource Generation

The Agent converts parsed annotations into Kubernetes Gateway API resources:

  • HTTPRoute - Traffic routing, redirects, rewrites
  • GRPCRoute - gRPC traffic routing (when backend-protocol is GRPC/GRPCS)
  • TLSRoute - TLS passthrough mode
  • SecurityPolicy - CORS, external auth, basic auth, IP access control
  • BackendTrafficPolicy - Rate limiting, retries, session affinity, timeouts
  • ClientTrafficPolicy - Client mTLS, connection limits
  • ExtendedSecurityPolicy - WAF (Coraza)
  • Backend - Backend TLS configuration

Detailed Mappings

1. Traffic Management

Traffic management annotations control HTTP redirects, URL rewrites, and path matching.

NGINX Annotations

AnnotationDescriptionDefault
ssl-redirectRedirect HTTP to HTTPStrue (when TLS configured)
force-ssl-redirectForce HTTPS redirect even without TLSfalse
rewrite-targetURL path rewriting with capture groups-
use-regexEnable regex path matchingfalse
app-rootRedirect "/" to specified path-
permanent-redirect301 redirect to URL-
temporal-redirect302 redirect to URL-

NGINX Input Example

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /api/$1
spec:
rules:
- host: api.example.com
http:
paths:
- path: /v1/(.*)
pathType: ImplementationSpecific
backend:
service:
name: my-service
port:
number: 80

Generated TEG Resources

HTTPRoute (main route with HTTPS):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gw-api-example-com-0
namespace: default
spec:
parentRefs:
- name: gw-api-example-com
sectionName: https
hostnames:
- api.example.com
rules:
- matches:
- path:
type: RegularExpression
value: /v1/(.*)
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplaceFullPath
replaceFullPath: /api/\1
backendRefs:
- name: my-service
port: 80

HTTPRoute (HTTP-to-HTTPS redirect):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gw-api-example-com-redirect-0
namespace: default
spec:
parentRefs:
- name: gw-api-example-com
sectionName: http-redirect
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestRedirect
requestRedirect:
scheme: https
hostname: api.example.com
port: 443
statusCode: 301

Behavioral Differences

BehaviorNGINXTEG
Capture groups$1, $2\1, \2 (auto-converted)
Regex syntaxPCRERE2 (some differences)
Default redirect code301301

Migration Notes

  • Capture groups: NGINX uses $1, $2 for capture groups; TEG uses \1, \2. The agent automatically converts these.
  • Regex compatibility: NGINX uses PCRE regex; TEG/Envoy uses RE2. Most patterns work, but lookahead/lookbehind are not supported in RE2.

2. Rate Limiting

Rate limiting annotations control request frequency limits.

NGINX Annotations

AnnotationDescriptionDefault
limit-rpsRequests per second per remote IP-
limit-rpmRequests per minute per remote IP-
limit-connectionsMaximum concurrent connections-

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/limit-connections: "50"

Generated TEG Resources

BackendTrafficPolicy (rate limiting):

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: gw-api-example-com-0-traffic
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
rateLimit:
type: Local
local:
rules:
- limit:
requests: 100
unit: Second

ClientTrafficPolicy (connection limit):

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: gw-api-example-com-client
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gw-api-example-com
sectionName: http
connection:
connectionLimit:
value: 50

Behavioral Differences

BehaviorNGINXTEG
Rate limit scopePer-routePer-route (BackendTrafficPolicy)
Connection limit scopePer-routePer-Gateway listener (ClientTrafficPolicy)
Burst handlinglimit-burst-multiplierNot directly supported

Migration Notes

  • Connection limits: NGINX applies limit-connections per route; TEG applies it at the Gateway listener level via ClientTrafficPolicy.
  • Burst multiplier: limit-burst-multiplier has no direct equivalent in TEG (logged as unsupported).

3. CORS

CORS (Cross-Origin Resource Sharing) annotations control browser cross-origin access.

NGINX Annotations

AnnotationDescriptionDefault
enable-corsEnable CORSfalse
cors-allow-originAllowed origins*
cors-allow-methodsAllowed HTTP methodsGET, PUT, POST, DELETE, PATCH, OPTIONS
cors-allow-headersAllowed request headersStandard headers
cors-expose-headersHeaders exposed to browser-
cors-allow-credentialsAllow credentialstrue
cors-max-agePreflight cache duration (seconds)1728000 (20 days)

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com, https://app.example.com"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-max-age: "86400"

Generated TEG Resources

SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: gw-api-example-com-0-security
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
cors:
allowOrigins:
- https://example.com
- https://app.example.com
allowMethods:
- GET
- POST
- PUT
- DELETE
allowCredentials: true
maxAge: 86400s

Behavioral Differences

BehaviorNGINXTEG
Max-age formatSeconds (integer)Duration string (e.g., 86400s)
Origin matchingExact + wildcardExact match only

Migration Notes

  • Duration format: NGINX uses seconds as integer; TEG uses duration strings (auto-converted).
  • Large max-age values: Values over 99999 seconds are converted to hours to fit Envoy Gateway's 5-digit limit.

4. Authentication

Authentication annotations configure external auth, basic auth, and client mTLS.

NGINX Annotations

AnnotationDescriptionDefault
auth-urlExternal authorization URL-
auth-response-headersHeaders from auth service to backend-
auth-typeAuthentication type (basic)-
auth-secretSecret name for basic auth-
auth-tls-secretCA certificate for client mTLS-

External Authorization Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/auth-url: "http://authz-service.auth-system.svc.cluster.local:8080/verify"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-User, X-Auth-Roles"

Generated SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: gw-api-example-com-0-security
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
extAuth:
http:
backendRef:
name: authz-service
namespace: auth-system
port: 8080
headersToBackend:
- X-Auth-User
- X-Auth-Roles

Basic Auth Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/auth-type: "basic"
nginx.ingress.kubernetes.io/auth-secret: "my-htpasswd-secret"

Generated SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: gw-api-example-com-0-security
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
basicAuth:
users:
group: ""
kind: Secret
name: my-htpasswd-secret
namespace: default

Client mTLS Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/auth-tls-secret: "certs/client-ca"

Generated ClientTrafficPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: gw-api-example-com-client
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gw-api-example-com
sectionName: https
tls:
clientValidation:
caCertificateRefs:
- group: ""
kind: Secret
name: client-ca
namespace: certs

Behavioral Differences

BehaviorNGINXTEG
External auth patternSubrequest (auth_request)Envoy ext_authz filter
Auth URL formatFull URLService reference (parsed from URL)
gRPC authNot nativeNative support with grpc:// scheme

Migration Notes

  • URL parsing: The auth-url is parsed to extract service name, namespace, and port for the SecurityPolicy backendRef.
  • gRPC support: Use grpc:// scheme in auth-url for gRPC authorization services.

5. Backend Configuration

Backend configuration annotations control upstream protocol and TLS settings.

NGINX Annotations

AnnotationDescriptionDefault
backend-protocolBackend protocol (HTTP, HTTPS, GRPC, GRPCS)HTTP
proxy-ssl-secretCA certificate for backend TLS-
proxy-ssl-verifyVerify backend certificatetrue
proxy-ssl-server-nameEnable SNI (on/off)off
proxy-ssl-nameSNI hostname-
proxy-body-sizeMaximum request body size-

Backend Protocol Example

NGINX Input (GRPC):

annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"

Generated Resource: Creates a GRPCRoute instead of HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: gw-grpc-example-com-grpc-0
namespace: default
spec:
parentRefs:
- name: gw-grpc-example-com
hostnames:
- grpc.example.com
rules:
- backendRefs:
- name: my-grpc-service
port: 9090

Backend TLS Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/proxy-ssl-secret: "certs/backend-ca"
nginx.ingress.kubernetes.io/proxy-ssl-verify: "true"
nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on"
nginx.ingress.kubernetes.io/proxy-ssl-name: "backend.internal"

Generated Backend Resource:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: my-service-backend-tls
namespace: default
spec:
endpoints:
- fqdn:
hostname: my-service.default.svc.cluster.local
port: 443
tls:
caCertificateRefs:
- name: backend-ca
group: ""
kind: Secret
sni: backend.internal

Proxy Body Size Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "100m"

Generated BackendTrafficPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: gw-api-example-com-0-traffic
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
requestBuffer:
limit: 100M

Behavioral Differences

BehaviorNGINXTEG
Unsupported protocols-FCGI, AJP (fallback to HTTP with warning)
Backend referenceInline in IngressSeparate Backend resource
Body size formatKubernetes quantityEnvoy quantity (uppercase suffix)

6. Timeouts & Retries

Timeout and retry annotations control backend connection and request handling.

NGINX Annotations

AnnotationDescriptionDefault
proxy-connect-timeoutTCP connection timeout (seconds)5
proxy-read-timeoutResponse read timeout (seconds)60
proxy-send-timeoutRequest send timeout (seconds)60
proxy-next-upstreamRetry conditionserror timeout
proxy-next-upstream-triesRetry attempts3
proxy-next-upstream-timeoutPer-retry timeout0 (unlimited)

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_502 http_503"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "30s"

Generated BackendTrafficPolicy

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: gw-api-example-com-0-traffic
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
timeout:
tcp:
connectTimeout: 10s
http:
requestTimeout: 120s
retry:
numRetries: 3
perRetry:
timeout: 30s
retryOn:
triggers:
- connect-failure
- reset
- 5xx

Retry Condition Mapping

NGINX ConditionTEG Trigger
errorconnect-failure
timeoutreset
http_500, http_502, http_5035xx
http_504gateway-error
http_429retriable-4xx
non_idempotentNo equivalent (warning)
updatingNo equivalent (warning)
offDisables retry

Behavioral Differences

BehaviorNGINXTEG
Read/send timeoutSeparateCombined as requestTimeout (uses max value)
Retry scopePer-upstreamPer-route

7. Session Affinity

Session affinity annotations enable sticky sessions using cookies.

NGINX Annotations

AnnotationDescriptionDefault
affinityAffinity type (must be cookie)-
session-cookie-nameCookie nameINGRESSCOOKIE
session-cookie-expiresCookie TTL (seconds)-
session-cookie-max-ageCookie max age (seconds)-
session-cookie-samesiteSameSite attribute-

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "MY_SESSION"
nginx.ingress.kubernetes.io/session-cookie-expires: "3600"
nginx.ingress.kubernetes.io/session-cookie-samesite: "Lax"

Generated BackendTrafficPolicy

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: gw-api-example-com-0-traffic
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
loadBalancer:
type: ConsistentHash
consistentHash:
type: Cookie
cookie:
name: MY_SESSION
ttl: 3600s
attributes:
SameSite: Lax

Behavioral Differences

BehaviorNGINXTEG
Supported affinity typescookie onlycookie only
IP-based affinityNot supportedNot supported

8. Canary Deployments

Canary annotations enable gradual traffic shifting between service versions.

NGINX Annotations

AnnotationDescriptionDefault
canaryEnable canary modefalse
canary-weightTraffic percentage to canary0
canary-weight-totalWeight total100
canary-by-headerHeader name for canary routing-
canary-by-header-valueHeader value to matchalways
canary-by-cookieCookie name for canary routing-

Weight-Based Canary Example

NGINX Input (Canary Service):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
backend:
service:
name: my-service-canary
port:
number: 80

Generated HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gw-api-example-com-0
namespace: default
spec:
parentRefs:
- name: gw-api-example-com
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-service
port: 80
weight: 80
- name: my-service-canary
port: 80
weight: 20

Header-Based Canary Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "always"

Generated HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gw-api-example-com-0
namespace: default
spec:
# ... hostnames, parentRefs ...
rules:
- matches:
- path:
type: PathPrefix
value: /
headers:
- name: X-Canary
value: always
backendRefs:
- name: my-service-canary
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-service
port: 80

9. TLS Passthrough

TLS passthrough forwards encrypted traffic directly to backends without termination.

NGINX Annotation

AnnotationDescriptionDefault
ssl-passthroughEnable TLS passthroughfalse

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"

Generated TLSRoute

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: gw-api-example-com-tls-0
namespace: default
spec:
parentRefs:
- name: gw-api-example-com
sectionName: passthrough
hostnames:
- api.example.com
rules:
- backendRefs:
- name: my-service
port: 443

Gateway Listener (Passthrough mode):

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
spec:
listeners:
- name: passthrough
port: 443
protocol: TLS
tls:
mode: Passthrough
hostname: api.example.com

Behavioral Differences

BehaviorNGINXTEG
Route typeIngressTLSRoute (separate resource type)
Gateway listenerSameRequires mode: Passthrough listener

10. Header Modification

Header modification annotations add or rewrite request headers.

NGINX Annotations

AnnotationDescriptionDefault
x-forwarded-prefixAdd X-Forwarded-Prefix header-
upstream-vhostRewrite Host header to backend-

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/x-forwarded-prefix: "/api/v1"
nginx.ingress.kubernetes.io/upstream-vhost: "internal-backend.example.com"

Generated HTTPRoute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gw-api-example-com-0
namespace: default
spec:
# ... parentRefs, hostnames ...
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-Prefix
value: /api/v1
- type: URLRewrite
urlRewrite:
hostname: internal-backend.example.com
backendRefs:
- name: my-service
port: 80

11. IP Access Control

IP access control annotations allow or deny traffic based on client IP addresses.

NGINX Annotations

AnnotationDescriptionDefault
whitelist-source-rangeAllow only specified CIDRs-
denylist-source-rangeDeny specified CIDRs-

Whitelist Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8, 192.168.1.0/24"

Generated SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: gw-api-example-com-0-security
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
authorization:
defaultAction: Deny
rules:
- action: Allow
principal:
clientCIDRs:
- 10.0.0.0/8
- 192.168.1.0/24

Denylist Example

NGINX Input:

annotations:
nginx.ingress.kubernetes.io/denylist-source-range: "203.0.113.0/24"

Generated SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: gw-api-example-com-0-security
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: gw-api-example-com-0
authorization:
defaultAction: Allow
rules:
- action: Deny
principal:
clientCIDRs:
- 203.0.113.0/24

Behavioral Differences

BehaviorNGINXTEG
PrecedenceWhitelist overrides denylistWhitelist takes precedence
IP formatCIDR notationCIDR notation

12. WAF (Web Application Firewall)

WAF annotations enable Coraza-based web application firewall protection.

NGINX Annotations

AnnotationDescriptionDefault
enable-modsecurityEnable WAF enginefalse
enable-owasp-core-rulesInclude OWASP Core Rule Settrue
modsecurity-snippetCustom WAF rules-

NGINX Input Example

annotations:
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRule ARGS:password "@contains admin" "id:1234,deny,status:403"

Generated ExtendedSecurityPolicy

apiVersion: teg.tetrate.io/v1alpha1
kind: ExtendedSecurityPolicy
metadata:
name: gw-api-example-com-waf
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gw-api-example-com
waf:
directives: |
Include @recommended-conf
SecRuleEngine On
SecResponseBodyAccess Off
Include @crs-setup-conf
Include @owasp_crs/*.conf
SecRule ARGS:password "@contains admin" "id:1234,deny,status:403"