Exposing Appian Outside Kubernetes

Overview

This page details methods of exposing Appian sites outside of Kubernetes for self-managed customers. Specifically, it allows you to expose the Webapp component or Apache Web Server (httpd) component (if enabled) so that Appian can send and receive web traffic. It should be used in conjunction with Restricting Traffic as a security measure.

If you've enabled network policies via the .spec.networkPolicies.enabled field on Appian custom resources, make sure to also refer to the Restricting Traffic page.

NodePort Services

The Appian operator and Appian custom resource definition (CRD) support exposing Appian sites outside of Kubernetes via NodePort Services with the .spec.service field on Appian custom resources.

Specifically, the .spec.service.type field can be set to NodePort to instruct the operator to change the Service it creates from a ClusterIP Service to a NodePort Service. The nodePort field can also be used to specify the port on each node on which the Service should be exposed (for example, the Service's .spec.ports[0].nodePort field).

If you expect users to enter the node port in their browser, you must ensure that the port number is specified via the .spec.webapp.url field and .spec.webapp.staticUrl and .spec.webapp.dynamicUrl fields, if applicable. In this scenario, it is required to specify the nodePort field because the port number assigned by the system is not known ahead of time otherwise.

If running multiple Webapp replicas and Apache Web Server (httpd) is disabled, you may need to enable session affinity at the Kubernetes layer. This can be done by changing the sessionAffinity field to ClientIP from its default value of None. In this case, session affinity can be further tuned via the sessionAffinityConfig field.

If you are using ExternalDNS to synchronize exposed Kubernetes Services and Ingresses with your DNS provider, you may also wish to set the external-dns.alpha.kubernetes.io/hostname annotation on the created Service resource (for more info on this annotation, see the FAQ in the ExternalDNS docs). This can be done via the annotations field.

The following custom resource snippet defines an Appian site with Apache Web Server (httpd) disabled and multiple Webapp replicas exposed on port 30000 on each node via a NodePort Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: crd.k8s.appian.com/v1alpha1
kind: Appian
metadata:
  name: appian-k8s-nodeport
spec:
  webapp:
    url: http://appian.example.com:30000
    staticUrl: http://appian.example-static.com:30000
    dynamicUrl: http://appian.example-dynamic.com:30000

    replicas: 3

  service:
    annotations:
      external-dns.alpha.kubernetes.io/hostname: "appian.example.com,appian.example-static.com,appian.example-dynamic.com"

    type: NodePort
    nodePort: 30000
    sessionAffinity: ClientIP

LoadBalancer Services

The Appian operator and Appian custom resource definition (CRD) support exposing Appian sites outside of Kubernetes via LoadBalancer Services with the .spec.service field on Appian custom resources.

Specifically, the .spec.service.type field can be set to LoadBalancer to instruct the operator to change the Service it creates from a ClusterIP Service to a LoadBalancer Service. The port field can be used to specify the port that will be exposed by the Service (for example, the Service's .spec.ports[0].port field). The loadBalancerIP field can be used to specify a specific IP with which the load balancer should be created. The nodePort field can also be used to specify the port on each node on which the Service should be exposed (for example, the Service's .spec.ports[0].nodePort field).

If running multiple Webapp replicas and Apache Web Server (httpd) is disabled, you may need to enable session affinity at the Kubernetes layer. This can be done by changing the sessionAffinity field to ClientIP from its default value of None. In this case, session affinity can be further tuned via the sessionAffinityConfig field.

In some environments, including AWS, enabling session affinity for LoadBalancer Services is prohibited.

If you are using ExternalDNS to synchronize exposed Kubernetes Services and Ingresses with your DNS provider, you may also wish to set the external-dns.alpha.kubernetes.io/hostname annotation on the created Service resource (for more info on this annotation, see the FAQ in the ExternalDNS docs). This can be done via the annotations field.

Exposing LoadBalancer Services on AWS

The subsections below detail custom resource snippets that show how to expose Appian sites via LoadBalancer Services on AWS (implementing on other providers is not yet available).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: crd.k8s.appian.com/v1alpha1
kind: Appian
metadata:
  name: appian-k8s-aws-loadbalancer
spec:
  webapp:
    url: https://appian.example.com
    staticUrl: https://appian.example-static.com
    dynamicUrl: https://appian.example-dynamic.com

  service:
    annotations:
      external-dns.alpha.kubernetes.io/hostname: "appian.example.com,appian.example-static.com,appian.example-dynamic.com"

      # Enable TLS/SSL support by specifying an SSL certificate and negotiation
      # policy. The backend protocol must be set to http since neither Webapp
      # nor Apache Web Server (httpd) speak HTTPS/SSL
      # https://kubernetes.io/docs/concepts/services-networking/service/#ssl-support-on-aws
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:<REGION>:<ACCOUNT_ID>:certificate/<CERTIFICATE_ID>
      service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: ELBSecurityPolicy-TLS-1-2-2017-01
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http

      # Enables operations in Appian with delayed responses, such as application
      # import inspection in Appian Designer, by increasing the time, in
      # seconds, that the connection is allowed to be idle (no data has been
      # sent over the connection) before it is closed by the load balancer
      # https://kubernetes.io/docs/concepts/services-networking/service/#other-elb-annotations
      service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "300"

    type: LoadBalancer

    # So that the created load balancer listens on port 443
    port: 443

Ingress

The Appian operator and Appian custom resource definition (CRD) support enabling and configuring Ingress for Appian sites via the .spec.ingress field on Appian custom resources.

To enable Ingress for a given site, set .spec.ingress.enabled to true. To set annotations on the created Ingress resource, define .spec.ingress.annotations.

The operator does not support the new IngressClass resource and ingressClassName field added in Kubernetes v1.18. Users must instead specify the deprecated kubernetes.io/ingress.class annotation.

The operator does not yet support spec.DefaultBackend and pathType added in Kubernetes v1.22.

An Ingress controller is responsible for fulfilling the Ingress. Appian sites in Kubernetes should work with a variety of Ingress controllers provided both the Ingress resource and controller are properly configured. The subsection below details how to configure Ingress via Appian custom resources for NGINX.

NGINX Ingress

Like many Ingress controllers, NGINX Ingress supports specifying annotations on Ingress resources to customize their behavior.

All Appian sites exposed via NGINX Ingress require the following annotations:

1
2
3
4
5
6
7
8
9
10
# Enables large file uploads in Appian by disabling client request body size
# checks
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#custom-max-body-size
nginx.ingress.kubernetes.io/proxy-body-size: "0"

# Enables operations in Appian with delayed responses, such as application
# import inspection in Appian Designer, by increasing the timeout for reading a
# response from the proxied server
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#custom-timeouts
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"

Appian sites with Apache Web Server (httpd) disabled (the default) also require the following annotations:

1
2
3
4
5
# Enables redirects from / to /<APPLICATION_CONTEXT> where <APPLICATION_CONTEXT>
# is defined by .spec.webapp.applicationContext - defaulting to suite if
# undefined
# https://kubernetes.github.io/ingress-nginx/examples/rewrite/
nginx.ingress.kubernetes.io/app-root: /suite

Appian sites with Apache Web Server (httpd) disabled (the default) and .spec.service.protocol set to ajp instead of the default value of http also require the following annotations:

1
2
3
4
# Changes the backend protocol from HTTP to Apache JServ Protocol (AJP) since
# Ingress traffic routes to Tomcat's AJP connector
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol
nginx.ingress.kubernetes.io/backend-protocol: AJP

Appian sites with Apache Web Server (httpd) disabled (the default) and multiple Webapp replicas also require the following annotations:

1
2
3
4
5
# Enables cookie-based session affinity and disables rebalancing sessions to new
# servers
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#session-affinity
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/affinity-mode: persistent

Finally, Appian sites with Apache Web Server (httpd) enabled also require the following annotations:

1
2
3
4
5
6
# Suppresses an issue where Apache Web Server (httpd) returns temporary
# redirects to http:// by setting the text that should be changed in the
# Location and Refresh header fields of a proxied server response
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#proxy-redirect
nginx.ingress.kubernetes.io/proxy-redirect-from: http://
nginx.ingress.kubernetes.io/proxy-redirect-to: https://

Additional annotations may be required depending on your specific use case. For a full list of annotations supported by NGINX Ingress, refer to its documentation.

Open in Github Built: Tue, Mar 28, 2023 (09:28:18 PM)

On This Page

FEEDBACK