> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.site/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuring Ingress Endpoints

> Expose the Arize AX UI and services with HTTPS ingress on GCP, AWS, Azure, Traefik, and other environments.

The previous steps explain how to install Arize AX and access the UI with a local port-forward. To expose Arize AX to the broader organization, create a secure HTTPS endpoint.

| Host                                | Prefix | Service               | Target Port |
| ----------------------------------- | ------ | --------------------- | ----------- |
| arize-app.\<my-organization-domain> | */*    | internalendpoints-app | 443         |

Pick the tab that matches your environment. For NGINX, Istio, Kong, and Traefik manifests, see [Other controllers](/ax/selfhosting/installation/ingress/other-controllers).

<Tabs>
  <Tab title="GCP">
    First review the Terraform documentation in `./terraform/README.md` as it includes parameters required to create static IP addresses. Re-apply Terraform if you change those resources. Static IP addresses are preferred as they allow a future rebuild of the cluster without impacting DNS entries.

    Make a copy of the example file.

    ```bash theme={null}
    $ cp ./examples/endpoints/gcp/app-services.yaml my-app-services.yaml
    ```

    Review the following annotation to confirm it aligns with the desired static IP. If you use the Terraform modules from the distribution, these names already align with the values in Terraform outputs.

    ```yaml theme={null}
    annotations:
      kubernetes.io/ingress.global-static-ip-name: arize-app-services
    ```

    Replace the placeholder hostname/domain name with the domain available in your organization. This domain name must be added to your DNS server and map to the static IP addresses mentioned above.

    ```text theme={null}
    '{{CUSTOMER_APP_DOMAIN}}' --> 'arize-app.<my-organization-domain>'
    ```

    If configured correctly, the DNS server will resolve the domain to the correct IP address. Use `nslookup` to verify.

    ```bash theme={null}
    $ nslookup arize-app.<my-organization-domain>
    ```

    Apply the manifest.

    ```bash theme={null}
    $ kubectl -n arize apply -f my-app-services.yaml
    ```

    Wait for a few minutes and verify the state of the ingress.

    ```bash theme={null}
    $ kubectl -n arize describe ingress arize-app-services
    ```

    The `ingressMode` parameter may need to be set correctly in `values.yaml` to work with certain ingress controllers or if a user desires to port-forward to the service for testing. Further details are in the **Ingress Controllers** table below.

    From a web browser enter `https://arize-app.<my-organization-domain>` to verify access. GCP may initially return an SSL error until the HTTPS certificate has been validated; if so, check back 30 minutes later. Add these parameters to `values.yaml` and apply the changes.

    ```yaml theme={null}
    appBaseUrl: "https://arize-app.<my-organization-domain>"
    expBaseUrl: "arize-app.<my-organization-domain>"
    ```
  </Tab>

  <Tab title="AWS">
    Since TLS termination is required, a Layer 7 ALB is the recommended option for AWS. The ALB can be created automatically by AWS when a Kubernetes Ingress resource is created and the AWS Load Balancer Controller is deployed.

    If you use the Terraform modules from the distribution, review the Terraform options to enable the Web Identity role and deploy the AWS Load Balancer Controller. Otherwise, refer to [Installing the AWS Load Balancer Controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html) to deploy it manually.

    A few notes about the AWS Load Balancer Controller:

    * It requires public networks, an Internet Gateway, and routes in order to get an external IP.
    * Private subnets need the label `kubernetes.io/role/internal-elb` for subnet discovery.
    * Public subnets need the label `kubernetes.io/role/elb` for subnet discovery.

    Make a copy of the example file.

    ```bash theme={null}
    $ cp ./examples/endpoints/aws/app-services.yaml my-app-services.yaml
    ```

    Edit the following annotations. For a public endpoint use `internet-facing`. Point the certificate annotation at a valid certificate.

    ```yaml theme={null}
    annotations:
      ...
      alb.ingress.kubernetes.io/scheme: "internal" # Use "internet-facing" for public endpoint
      alb.ingress.kubernetes.io/certificate-arn: "<certificate-arn>"
    ```

    Apply the manifest.

    ```bash theme={null}
    $ kubectl -n arize apply -f my-app-services.yaml
    ```

    Wait for a few minutes and verify the state of the ingress.

    ```bash theme={null}
    $ kubectl -n arize describe ingress arize-app-services
    ```

    In some environments the `external-dns.alpha.kubernetes.io/hostname` annotation can be used to automatically create a DNS entry in Route 53. If another DNS system is used, collect the ELB address from the ingress resource and request a DNS entry mapping `arize-app.<my-organization-domain>` to it.

    If configured correctly, the DNS server will resolve the domain to the correct IP address. Use `nslookup` to verify.

    ```bash theme={null}
    $ nslookup arize-app.<my-organization-domain>
    ```

    From a web browser enter `https://arize-app.<my-organization-domain>` to verify access. Add these parameters to `values.yaml` and apply the changes.

    ```yaml theme={null}
    appBaseUrl: "https://arize-app.<my-organization-domain>"
    expBaseUrl: "arize-app.<my-organization-domain>"
    ```
  </Tab>

  <Tab title="Azure">
    The Azure AGIC does not currently support gRPC. For this reason Arize AI recommends using a Network Load Balancer and terminating TLS at the Arize AX pods.

    Make a copy of the example file and review its content.

    ```bash theme={null}
    $ cp ./examples/endpoints/azure/app-services.yaml my-app-services.yaml
    ```

    Apply the manifest.

    ```bash theme={null}
    $ kubectl -n arize apply -f my-app-services.yaml
    ```

    Wait for a few minutes and verify the state of the service.

    ```bash theme={null}
    $ kubectl -n arize describe service arize-app-services
    ```

    Create a DNS entry pointing your desired domain/hostname (for example `arize-app.<my-organization-domain>`) to the IP address of the Network Load Balancer. If a certificate is not available, generate a self-signed certificate matching your domain:

    ```bash theme={null}
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -out app-tls.crt \
        -keyout app-tls.key \
        -subj "/CN=arize-app.<my-organization-domain>/O=<company-name>" -addext "subjectAltName = DNS:arize-app.<my-organization-domain>"
    ```

    Load the certificate into Arize AX by updating `values.yaml`:

    ```yaml theme={null}
    internalEndpointsAppTlsCert: '<base64 encoded contents of TLS certificate file>'
    internalEndpointsAppTlsKey: '<base64 encoded contents of TLS private key file>'
    ```

    From a web browser enter `https://arize-app.<my-organization-domain>` to verify access. Add these parameters to `values.yaml` and apply the changes.

    ```yaml theme={null}
    appBaseUrl: "https://arize-app.<my-organization-domain>"
    expBaseUrl: "arize-app.<my-organization-domain>"
    ```
  </Tab>

  <Tab title="OpenShift">
    The OpenShift ingress controller configures an underlying HAProxy component. For proper gRPC operation certain settings on the OpenShift routes are required. To enable HTTP/2 support, run this command against the target Ingress Controller (either a specific one or the default). This annotation can also be applied via the console UI under *Administration → CustomResourceDefinitions → IngressController → Instances → default*. If HTTP/2 is not enabled, gRPC clients may encounter errors such as *Cannot check peer: missing selected ALPN property* or *Selected ALPN Protocol: None*.

    ```bash theme={null}
    oc -n openshift-ingress-operator annotate ingresscontrollers/default ingress.operator.openshift.io/default-enable-http2=true
    ```

    In `values.yaml`, set `ingressMode` to `openshift`. **Important:** this configuration must be applied before creating any routes, as OpenShift references the resulting `appProtocol` on the Arize AX ports during route creation. Specifically, for internal HTTP/2 ports, the `appProtocol` is set to `h2c`, indicating HTTP/2 without TLS.

    ```yaml theme={null}
    ingressMode: 'openshift'
    ```

    From the OpenShift console UI as an administrator, use **Create Route** from the Networking → Routes panel and enter the following data in the `arize` namespace project to create the endpoints. Use Secure Route `enabled` and TLS termination `Edge` on each route. OpenShift does not allow a wildcard certificate with gRPC/HTTP/2 protocols, so create a non-wildcard certificate on the `arize-app` route or create a second `arize-api` route for API functions.

    | Host                                | Prefix | Service               | Target Port | Certificate              |
    | ----------------------------------- | ------ | --------------------- | ----------- | ------------------------ |
    | arize-app.\<my-organization-domain> | */*    | internalendpoints-app | 443         | Wildcard or non-wildcard |
    | arize-api.\<my-organization-domain> | */*    | internalendpoints-app | 443         | Non-wildcard             |

    Edit the `arize-app` (or `arize-api`) route to add a non-wildcard certificate and key matching the route's `Host` field. This per-route certificate is mentioned in [Enabling HTTP/2](https://docs.openshift.com/container-platform/4.16/networking/ingress-operator.html#nw-http2-haproxy_configuring-ingress) to allow gRPC traffic to transit the controller. Generate the certificate with openssl:

    ```bash theme={null}
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -out app-tls.crt \
        -keyout app-tls.key \
        -subj "/CN=arize-app.<my-organization-domain>/O=<company-name>" -addext "subjectAltName = DNS:arize-app.<my-organization-domain>"
    ```

    If using TLS termination `Edge` is not an option, a fallback method is to use a single `passthrough` route and mount the certificate at the pods:

    ```yaml theme={null}
    ingressMode: 'tls'
    internalEndpointsAppTlsCert: '<base64 encoded contents of TLS certificate file>'
    internalEndpointsAppTlsKey: '<base64 encoded contents of TLS private key file>'
    ```
  </Tab>
</Tabs>

## Ingress Controllers

For gRPC protocols like OTLP and flightserver, the `ingressMode` parameter may need to be set correctly in `values.yaml` to work with certain ingress controllers or if a user desires to port-forward to the service for testing.

Recommended settings:

| Controller / Load Balancer             | ingressMode   | internalEndpointsAppTlsCert / internalEndpointsAppTlsKey |
| -------------------------------------- | ------------- | -------------------------------------------------------- |
| GCP                                    | tls (default) | N/A                                                      |
| AWS ALB                                | tls (default) | N/A                                                      |
| Azure NLB                              | tls (default) | Custom certificate                                       |
| Nginx                                  | tls (default) | N/A                                                      |
| Kong                                   | tls (default) | N/A                                                      |
| Traefik                                | notls         | N/A                                                      |
| Istio                                  | istio         | N/A                                                      |
| OpenShift — Edge                       | openshift     | N/A                                                      |
| OpenShift — Pass-through               | tls           | Custom certificate                                       |
| Local port-forward                     | notls         | N/A                                                      |
| TLS Termination at Arize AX Pods (NLB) | tls           | Custom certificate                                       |

More details on working with an OpenShift ingress controller are in the OpenShift tab above.
