Migrate to an External Ingress Controller
Starting with Release 27.1, Digital.ai Release no longer includes ingress controllers as packaged Helm subcharts or as installer-deployed components. Ingress itself is still fully supported. It is no longer managed or deployed by the installer, so you provide your own ingress controller (or opt out and configure ingress later).
This guide applies to both Release and Deploy custom resources (CRs). If Deploy is installed in the same namespace, apply the equivalent steps to its CR as noted below.
Removed Components
The following components are removed from the Release and Deploy Helm charts and installer. None of them can be automatically migrated to an external ingress controller by the installer. Moving off them requires the manual CR changes described in this guide, applied before or during your upgrade.
| Component | Source | Status |
|---|---|---|
nginx-ingress-controller | Bitnami Helm subchart | Removed from the Helm charts. The Bitnami community chart for this controller is no longer supported upstream. |
haproxy-ingress | HAProxy Ingress Helm subchart | Removed from the Helm charts. |
ingress-nginx-controller | Kubernetes community manifest (installed by the installer) | No longer installed or upgraded by the installer. The upstream ingress-nginx project is retired and out of maintenance since March 2026. |
New Installations
When you install Release 27.1 or later, the installer does not prompt you to install an ingress controller. Choose one of the following:
- Option A: External ingress controller (recommended). Ensure an ingress controller is already installed in your cluster and select the
externalingress option during installation. Provide the ingress class name that matches your controller. - Option B: No ingress. Select
noneduring installation. The application is accessible within the cluster but does not expose an external hostname. You can configure ingress later by editing the CR.
Recommendation for 25.3 and 26.1 Installations Using ingress-nginx-controller
The ingress-nginx-controller option remains selectable in Release 25.3 and 26.1 and continues to work there. Because the upstream project is retired and no longer maintained (as of March 2026), use external (pointing at a controller you already manage) instead of ingress-nginx-controller, even if you stay on 25.3 or 26.1 for now. This avoids running an unmaintained ingress controller in production, and avoids the manual cleanup described below when you later upgrade to 27.1 or later.
Upgrade to Release 27.1 or Later
The steps depend on which ingress controller your current installation uses. Identify it first, then follow the matching section.
These steps use the default namespace digitalai. If you installed Release in a custom namespace, replace digitalai with your namespace throughout these steps.
Step 1: Identify the Current Ingress Controller
## Bitnami nginx-ingress-controller (deployed as Helm subchart)
kubectl get pods -n digitalai -l app.kubernetes.io/name=nginx-ingress-controller
## haproxy-ingress (deployed as Helm subchart)
kubectl get pods -n digitalai -l app.kubernetes.io/name=haproxy-ingress
## ingress-nginx-controller (installed via Kubernetes manifest, dai-prefixed resources)
kubectl get pods -n digitalai -l app.kubernetes.io/name=ingress-nginx
Record your current ingress configuration before making any changes:
kubectl get ingress -n digitalai -o yaml
kubectl get route -n digitalai -o yaml # OpenShift only
Note the hostname, path, ingress class or annotations, and any TLS secret names in use. You need these to reconfigure spec.ingress manually.
Step 2: Install or Confirm Your External Ingress Controller
Make sure a supported external ingress controller is already installed and working in your cluster before upgrading. See Common Ingress Controllers if you need to choose or install one.
Step 3: Identify Your CR Names
List the CR names in your namespace:
## Release CR(s)
kubectl get digitalaireleases.xlr.digital.ai -n digitalai
## Deploy CR(s)
kubectl get digitalaideploys.xld.digital.ai -n digitalai
Typical default names created by installer flows:
- Release:
dai-xlr(OpenShift:dai-ocp-xlr; custom namespace variant:dai-xlr-<namespace>ordai-ocp-xlr-<namespace>) - Deploy:
dai-xld(OpenShift:dai-ocp-xld; custom namespace variant:dai-xld-<namespace>ordai-ocp-xld-<namespace>)
Use the exact names returned here in the commands below if your names differ.
Step 4: Controller-Specific Actions Before Upgrade
Follow only the section that matches the controller identified in Step 1.
If Using the Bitnami nginx-ingress-controller
Set .spec.nginx-ingress-controller.install to false in the Release CR (and the Deploy CR, if present):
## Release
kubectl patch digitalaireleases.xlr.digital.ai dai-xlr -n digitalai --type merge \
-p '{"spec":{"nginx-ingress-controller":{"install":false}}}'
## Deploy
kubectl patch digitalaideploys.xld.digital.ai dai-xld -n digitalai --type merge \
-p '{"spec":{"nginx-ingress-controller":{"install":false}}}'
No separate manual deletion step is required for this controller.
The .spec.nginx-ingress-controller key does not exist in the Release and Deploy CRD schema in 27.1 and later, because the subchart is removed from the Helm chart. Apply this patch only on your current pre-27.1 version, before upgrading. Once you are on 27.1 or later, this key no longer exists and setting it has no effect.
If Using haproxy-ingress
Set .spec.haproxy-ingress.install to false in the Release CR (and the Deploy CR, if present):
## Release
kubectl patch digitalaireleases.xlr.digital.ai dai-xlr -n digitalai --type merge \
-p '{"spec":{"haproxy-ingress":{"install":false}}}'
## Deploy
kubectl patch digitalaideploys.xld.digital.ai dai-xld -n digitalai --type merge \
-p '{"spec":{"haproxy-ingress":{"install":false}}}'
No separate manual deletion step is required for this controller.
The .spec.haproxy-ingress key does not exist in the Release and Deploy CRD schema in 27.1 and later, because the subchart is removed from the Helm chart. Apply this patch only on your current pre-27.1 version, before upgrading. Once you are on 27.1 or later, this key no longer exists and setting it has no effect.
If Using ingress-nginx-controller
Migration or continued use of ingress-nginx-controller is not supported going forward. The upstream project is retired, and the installer no longer ships or upgrades it.
spec.ingress values are carried forward from your old CR by the upgrade, but the preserved values may be stale or empty. You must manually edit spec.ingress after the upgrade to point at a real, already-running external ingress controller. The upgrade does not do this for you.
Remove the ingress-nginx-controller resources:
## Deployment, Services, ConfigMap
kubectl delete deployment dai-ingress-nginx-controller -n digitalai
kubectl delete service dai-ingress-nginx-controller dai-ingress-nginx-controller-admission -n digitalai
kubectl delete configmap dai-ingress-nginx-controller -n digitalai
## ServiceAccounts
kubectl delete serviceaccount dai-ingress-nginx dai-ingress-nginx-admission -n digitalai
## Namespaced Roles and RoleBindings
kubectl delete role dai-ingress-nginx dai-ingress-nginx-admission -n digitalai
kubectl delete rolebinding dai-ingress-nginx dai-ingress-nginx-admission -n digitalai
## Admission webhook Jobs and Secret (Jobs may already be completed)
kubectl delete job dai-ingress-nginx-admission-create dai-ingress-nginx-admission-patch -n digitalai --ignore-not-found
kubectl delete secret dai-ingress-nginx-admission -n digitalai --ignore-not-found
## Cluster-scoped resources
kubectl delete clusterrole dai-ingress-nginx dai-ingress-nginx-admission
kubectl delete clusterrolebinding dai-ingress-nginx dai-ingress-nginx-admission
kubectl delete validatingwebhookconfiguration dai-ingress-nginx-admission
kubectl delete ingressclass nginx-dai
On OpenShift, if SCC was enabled, also remove the SecurityContextConstraints:
## The SCC name follows the pattern: dai-ocp-<shortServerName>-ingress-nginx
## (or dai-ocp-<shortServerName>-<namespace>-ingress-nginx if a custom namespace was used)
kubectl delete scc dai-ocp-<shortServerName>-ingress-nginx
These resources are deployed into your product namespace, not a separate ingress-nginx namespace. The nginx-dai IngressClass and the dai-ingress-nginx-admission ValidatingWebhookConfiguration are cluster-scoped and must be removed separately.
Step 5: Reconfigure Ingress in the CR
For all three cases above, manually set spec.ingress (or spec.route on OpenShift) to the correct external ingress class, annotations, hostname, path, and TLS configuration. Do this just before upgrading, or immediately after, before you rely on the application being reachable through ingress.
spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: <your-external-ingress-class>
## add required annotations for your controller
hostname: "<existing-hostname>"
path: /
Step 6: Upgrade to Release 27.1 or Later
Run the xl kube upgrade command. On OpenShift, answer the Clean IngressNginx Controller prompt as described in Step 4 if it appears. No other ingress-controller install prompts are shown during upgrade. Your spec.ingress or spec.route values from the previous CR are carried forward automatically if you were already using external, none, or route.
For the full upgrade procedure, see Upgrade Options Reference.
Step 7: Validate
## Application URL resolves
curl -I http://<your-hostname>/
## Ingress resource created correctly
kubectl get ingress -n digitalai
kubectl describe ingress -n digitalai <ingress-name>
Common Ingress Controllers
The following table lists provider-managed ingress options first, then common self-managed alternatives.
| Provider | Managed option to use first | Ingress class | Notes |
|---|---|---|---|
| AWS (EKS) | AWS Load Balancer Controller (ALB) | alb | Standard ingress choice on EKS for L7 HTTP/HTTPS routing. |
| GKE | GKE Ingress controller | gce (external), gce-internal (internal) | Built-in managed controller in GKE. |
| Azure (AKS) | Application Routing add-on (managed NGINX) | webapprouting.kubernetes.azure.com | Microsoft-managed ingress option for AKS. |
Common self-managed alternatives:
| Controller | Install guide | Common ingress class |
|---|---|---|
| Traefik | Install Traefik ↗ | traefik |
| HAProxy Ingress | HAProxy Ingress ↗ | haproxy |
| Azure Application Gateway Ingress Controller (AGIC) | AGIC ↗ | azure/application-gateway |
Do not select ingress-nginx (https://kubernetes.github.io/ingress-nginx/) for new installations. The upstream project is retired and out of maintenance since March 2026. Migrate away from it if it is currently in use, on any supported version.
CR Ingress Configuration Examples
The following snippets show the spec.ingress block to use in your Release or Deploy CR. For the full set of supported keys, see the Ingress parameters section in the Release Helm chart README ↗.
HTTP Through an External Ingress Controller
spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/ssl-redirect: "false"
hostname: "release.example.com"
path: /
HTTPS with TLS Termination at the Ingress Controller
The ingress controller handles TLS. The application runs HTTP internally.
spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/ssl-redirect: "true"
hostname: "release.example.com"
path: /
tls: true
extraTls:
- hosts:
- "release.example.com"
secretName: "release-tls-secret" ## pre-created TLS secret
HTTPS with Traefik
spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik
ingress.kubernetes.io/ssl-redirect: "true"
hostname: "release.example.com"
path: /
tls: true
extraTls:
- hosts:
- "release.example.com"
secretName: "release-tls-secret"
AWS Load Balancer Controller (ALB)
spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:<region>:<account>:certificate/<id>"
hostname: "release.example.com"
path: /
No Ingress (Configure Later)
spec:
ingress:
enabled: false