Migrate from NGINX Ingress to Envoy Gateway
Migrate Harness Self-Managed Enterprise Edition traffic from NGINX Ingress to Envoy Gateway.
Harness Self-Managed Enterprise Edition (SMP) supports the Kubernetes Gateway API through Envoy Gateway as an alternative to the NGINX Ingress controller. Use this guide to move traffic to Envoy Gateway: deploy the required CRDs, enable Envoy Gateway, update DNS, validate traffic, then remove NGINX when you are ready.
Before you begin
Complete these prerequisites before you start the migration:
Harness SMP install: A Helm-based SMP deployment that you can upgrade with override values. Go to Install using Helm to review the install flow.
Existing ingress values: Your current
global.ingresshosts and related ingress settings. Go to Configure and customize Ingress and NGINX Controller using overrides to review ingress overrides.Cluster access:
kubectlaccess to the SMP namespace so you can inspect CRDs, Gateways, and HTTPRoutes.DNS access: Permission to update DNS records that point at your load balancer.
Migrate to Envoy Gateway
Follow these steps in order. Fresh installs can skip CRD setup; upgrades must deploy CRDs first.
Deploy Gateway API CRDs
Envoy Gateway requires Gateway API custom resource definitions (CRDs) in the cluster before you enable it.
For a first-time Harness SMP install, you can skip this step. The Helm chart deploys the required CRDs during installation.
If you already run Harness SMP, install the CRDs before you enable Envoy Gateway. Choose one of the following options.
Option 1: Deploy CRDs with the native Helm job
Add these overrides and upgrade Harness. The chart deploys Envoy Gateway and runs a job that installs or updates the Gateway API CRDs:
platform:
envoy-gateway:
enabled: true
deployCRDsJob:
enabled: trueOption 2: Deploy CRDs externally
Install the CRDs yourself with the Envoy Gateway Helm chart. Stick to Envoy Gateway version 1.8.1 and set crds.gatewayAPI.channel=experimental.
Go to the Envoy Gateway Helm install guide for the external install steps.
After either option, verify the CRDs:
kubectl get crd | grep -i gatewayEnable Gateway API and Envoy Gateway
Enable Gateway API, deploy Envoy Gateway, and send internal traffic to the Envoy proxy service. Keep your existing primary hostname in global.ingress.hosts, and add the stable Envoy proxy service name envoy-gateway-proxy-envoy-gateway next to it.
For a first-time Harness SMP install, enable Gateway API and Envoy Gateway, and skip the NGINX controller from the start:
For an existing Harness SMP deployment, upgrade with these overrides. Leave the NGINX controller in place until you validate traffic, then remove it in Remove NGINX Ingress.
COPY LOAD BALANCER ANNOTATIONS
Envoy Gateway does not inherit annotations from the NGINX controller LoadBalancer Service. If you skip this, cloud providers can create the wrong load balancer type. On AWS, a missing scheme annotation often creates an internal NLB, so the public endpoint is unreachable. Go to Migrate load balancer annotations before you update DNS.
Migrate load balancer annotations
Copy any load balancer annotations from your NGINX controller Service onto the Envoy proxy Service. Set them under global.gatewayAPI.proxyService.annotations in the same upgrade that enables Gateway API.
Inspect your current NGINX controller Service:
Note the
metadata.annotationsyou rely on for load balancer behavior.Re-apply those annotations under
global.gatewayAPI.proxyService.annotations.
Use the examples below as a starting point. Each tab shows one common configuration, so confirm whether your NGINX Service used a public or internal load balancer before you copy it. Replace or extend the example with the annotations from your NGINX Service.
On AWS, set an internet-facing scheme if users reach Harness over the public internet. Without this annotation, the controller can create an internal NLB.
Other annotations you may need to copy from NGINX include service.beta.kubernetes.io/aws-load-balancer-type, service.beta.kubernetes.io/aws-load-balancer-nlb-target-type, and SSL or backend-protocol annotations.
On GKE, copy the load balancer annotations from your NGINX Service. For an internal load balancer, set the internal type annotation. For a public load balancer, omit the internal type annotation or keep the public settings you already use.
If your NGINX Service used other GKE annotations (for example NEG or custom LB options), copy those same keys and values under proxyService.annotations.
On AKS, copy Azure load balancer annotations from your NGINX Service. Use the internal annotation only when you need a private load balancer.
For a public Azure load balancer, omit azure-load-balancer-internal or set it to "false", and copy any other Azure annotations you used on NGINX (resource group, health probe path, and similar).
Update DNS
After Envoy Gateway and its services are up, point your Harness hostname DNS record at the Envoy Gateway load balancer instead of the NGINX load balancer.
Envoy Gateway creates a separate LoadBalancer service for external traffic. That service name can include a hash (for example envoy-<namespace>-envoy-gateway-<hash>). Use that service for DNS, not the stable ClusterIP service envoy-gateway-proxy-envoy-gateway.
Find the Envoy proxy
LoadBalancerservice:Get its external IP (or hostname):
Update your DNS record for the Harness hostname to that address.
Wait for DNS to update before you validate.
Validate the migration
After you update DNS, confirm that Harness works as expected:
Log in to the Harness UI.
Open a few core pages and modules you use.
Confirm pipeline triggers and other critical traffic paths still succeed.
You can also confirm Gateway API resources in the cluster:
Remove NGINX Ingress
This step applies only to SMP upgrades. Fresh installs already disable the NGINX controller in Enable Gateway API and Envoy Gateway.
After validation succeeds, scale down the NGINX controller, or remove it from the Helm release with these overrides:
REMOVE NGINX ONLY AFTER VALIDATION
Do not disable NGINX until you confirm Harness UI access, pipelines, and other critical paths through Envoy Gateway.
Configure additional Gateway listeners (required for Looker)
If you use Looker for custom dashboards, this step is required. Create an additional Gateway listener whose hostname matches the lookerPubDomain you set under ng-custom-dashboards.
Add a matching listener under global.gatewayAPI.additionalListeners. Use the same value as lookerPubDomain for hostname, and point certificateRefs at the TLS secret for that domain:
Requirements for the Looker listener:
Matching hostname:
hostnamemust matchng-custom-dashboards.config.lookerPubDomain.Unique listener name: Do not reuse the built-in names
httpsorhttp.Valid TLS secret:
certificateRefs.namemust reference a Secret that exists in the Gateway namespace.
Go to Configure custom dashboards to review Looker and lookerPubDomain setup.
Configure a fallback HTTPRoute (optional)
By default, the fallback HTTPRoute is off. During migration, you can turn it on so traffic that does not match an HTTPRoute still goes to NGINX while you validate Envoy Gateway.
Disable the fallback again after your routes are stable:
Troubleshooting
Use these checks if traffic does not move to Envoy Gateway as expected.
Next steps
You have moved traffic from NGINX Ingress to Envoy Gateway. Keep global.ingress.enabled set to true so Harness continues to create HTTPRoutes from your ingress rules. The NGINX controller itself is no longer required after you remove it.
Basic configuration: Review core SMP configuration options.
Install using Helm: Review the Helm install and upgrade flow.
Last updated
Was this helpful?