For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.ingress hosts and related ingress settings. Go to Configure and customize Ingress and NGINX Controller using overrides to review ingress overrides.

  • Cluster access: kubectl access 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: true

RUN THIS AS A SEPARATE UPGRADE

Upgrade Harness with the config above first. After the CRDs are installed, run a second upgrade to enable Gateway API and Envoy Gateway. This CRD installation is a one-time process. Keep deployCRDsJob.enabled set to true so later SMP upgrades can update the CRDs.

Option 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 gateway

Enable 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.

KEEP INGRESS RULES ENABLED

Keep global.ingress.enabled set to true during and after migration. You still need these ingress rules after you move to Envoy Gateway and remove the NGINX controller. Harness creates the equivalent HTTPRoute resources from those ingress rules.

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.


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.

  1. Inspect your current NGINX controller Service:

  2. Note the metadata.annotations you rely on for load balancer behavior.

  3. 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).

APPLY ANNOTATIONS BEFORE DNS CUTOVER

Add proxyService.annotations when you enable Envoy Gateway. If the LoadBalancer Service was already created without the right annotations, update the overrides and upgrade again, then confirm the cloud load balancer type before you change DNS.


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.

  1. Find the Envoy proxy LoadBalancer service:

  2. Get its external IP (or hostname):

  3. Update your DNS record for the Harness hostname to that address.

  4. 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:


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: hostname must match ng-custom-dashboards.config.lookerPubDomain.

  • Unique listener name: Do not reuse the built-in names https or http.

  • Valid TLS secret: certificateRefs.name must 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.

Gateway API CRDs are missing after a Harness SMP upgrade to Envoy Gateway

Deploy CRDs with platform.envoy-gateway.deployCRDsJob.enabled set to true, or install Envoy Gateway 1.8.1 CRDs externally with crds.gatewayAPI.channel=experimental, then run kubectl get crd | grep -i gateway.

No Gateway or Envoy Gateway resources appear after enabling Gateway API in Harness SMP

Set platform.envoy-gateway.enabled, global.gatewayAPI.enabled, and global.gatewayAPI.create to true, then upgrade the Helm release.

Harness SMP traffic still routes through NGINX after Envoy Gateway cutover

Confirm global.ingress.ingressGatewayServiceUrl is http://envoy-gateway-proxy-envoy-gateway and that service is listed under global.ingress.hosts. For DNS, point at the external IP of the LoadBalancer service selected by app.kubernetes.io/component=proxy,app.kubernetes.io/managed-by=envoy-gateway (the name can include a hash).

Envoy Gateway LoadBalancer is internal or public Harness URL is unreachable after NGINX to Envoy migration on AWS

Envoy does not inherit NGINX Service annotations. Set service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing under global.gatewayAPI.proxyService.annotations, upgrade again, and confirm the LoadBalancer is internet-facing before you update DNS.


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.

Last updated

Was this helpful?