Zum Hauptinhalt springen

Migration from HAProxy to OORT

Switching away from a deprecated HAProxy solution​

Initially the default CI deployments provided by Jutro's pipeline generator have been based on a HAProxy Ingress. However, the Atmos team is going to drop support for this implementation of Ingress and the recommendation has been made to switch to the OORT-backed solution instead. This guide aims to support the owners of existing Jutro apps with CI pipelines already generated with the process of migrating to the new solution.

Note: All presented examples refer to the default or most typical ingress configs available as part of the base configuration pipelines provided by Jutro's generator. In case of having some additional customizations applied for your app, refer to OORT's docs for finding out the appropriate alternative available in the new solution.

Setting up a gateway config​

  1. Start from creating a gateway manifest file:
touch k8s/gateway.yml
  1. Populate the file with the first config's skeleton:
apiVersion: oort.ccs.guidewire.com/v1alpha1
kind: GatewayConfig
metadata:
namespace: ${NAMESPACE}
name: <%=appNameLowercase=%>-${DEPLOY_ENV}-gateway
spec:
profiles:
- name: Default
cors:
origins:
- .*\.guidewire\.net
- .*localhost.*
methods:
- GET
- OPTIONS
headers:
- '*'
credentials: true
request_transformer:
add:
headers:
- Host:tenant-<%=podName=%>-<%=s3FrontendBucketName=%>-${S3_SUFFIX}.s3-website.us-west-2.amazonaws.com
response_transformer:
add:
headers:
- Content-Security-Policy:frame-ancestors https://*.guidewire.net
path_configs:
- name: Default
paths:
- /**
profiles:
- Default
service_ref: <%=serviceName=%>
service_alias: <%=serviceAlias=%>
enable_sub_domain: false
Warning: The Content-Security-Policy:frame-ancestors https://*.guidewire.net setting prevents clickjacking attacks. Do not modify or remove it. For more information see the OWASP page on clickjacking.
Note: The CORS-related config is optional and might not be needed if your app is not expected to be nested as a micro-frontend.
  1. Replace app-specific parts of the above config with values appropriate for your app. In case of doubts, it might be a good idea to simply copy the existing corresponding values from the k8s/ingress.yml file.
  • <%=appsNameLowercase=%> - Lowercased descriptive name of your app. Appropriate value can be figured out from the k8s/ingress.yml file, specifically the metadata.name property there.
  • <%=podName=%> - Name of your Atmos tenant. Typically your pod's name.
  • <%=s3FrontendBucketName=%> - Name of your apps bucket. Typically constructed as the name of your app (same value as <%=appsNameLowercase=%>) with -bucket suffix appended.
  • <%=serviceName=%> - Name of your ExternalName service. Can be extracted out from your app's ExternalName service defined in k8s/service.yml file - specifically the metadata.name property there.
  • <%=serviceAlias=%> - Main part of the URL under which your app's deploment should be available, eventually combined with the default OORT's suffix for the final URL (for example, <%=serviceAlias=%>.dev.ccs.guidewire.net for the deployments to dev cluster or <%=serviceAlias=%>.int.ccs.guidewire.net for the deployments to int cluster).
Note: The full value for spec.profiles[0].request_transformer.add.headers[0] property can be copied from the existing k8s/ingress.yml file's Ingress config, specifically the value specified for its metadata.annotations['ingress.kubernetes.io/config-backend'] property, next to the http-request set-header Host phrase there.

For example based on the existing ingress.yml file like:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: ${NAMESPACE}
name: myjutroapp-${DEPLOY_ENV}-ingress
annotations:
ingress.kubernetes.io/config-backend: |
http-request set-header Host tenant-mypod-myjutroapp-${S3_SUFFIX}.s3-website.us-west-2.amazonaws.com
ingress.kubernetes.io/enable-cors: \"true\"
ingress.kubernetes.io/cors-allow-methods: GET,OPTIONS
ingress.kubernetes.io/cors-allow-credentials: \"true\"
ingress.kubernetes.io/cors-allow-headers: GW-Tenant,GW-Request-GRN,Accept,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Pragma
spec:
rules:
- host: 'myjutroapp-${NAMESPACE}.${DEPLOY_ENV}.ccs.guidewire.net'
http:
paths:
- backend:
serviceName: myjutroapp-external-name-service
servicePort: 80
path: /

We can have the following gateway.yml file created:

apiVersion: oort.ccs.guidewire.com/v1alpha1
kind: GatewayConfig
metadata:
namespace: ${NAMESPACE}
name: myjutroapp-${DEPLOY_ENV}-gateway
spec:
profiles:
- name: Default
cors:
origins:
- .*\.guidewire\.net
- .*localhost.*
methods:
- GET
- OPTIONS
headers:
- '*'
credentials: true
request_transformer:
add:
headers:
- Host:tenant-mypod-myjutroapp-${S3_SUFFIX}.s3-website.us-west-2.amazonaws.com
response_transformer:
add:
headers:
- Content-Security-Policy:frame-ancestors https://*.guidewire.net
path_configs:
- name: Default
paths:
- /**
profiles:
- Default
service_ref: myjutroapp-external-name-service
service_alias: myjutroapp-${NAMESPACE}
enable_sub_domain: false

Note: make sure to apply the appropriate adjustments corresponding to the content of your existing ingress.yml file

  1. Based on the newly created gateway.yml file let's also create a similar file dedicated to prod deployments.
touch k8s/gateway-prod.yml

Initially it can get fulfilled with the content previously added to the gateway.yml file, with the only two differences being spec.profiles[0].request_transformer.add.headers[0] property adjusted (make sure to replace the placeholders with your own values):

Host:tenant-<%=podName=%>-<%=s3FrontendBucketName=%>-${S3_SUFFIX}.s3-website.us-east-2.amazonaws.com

and an extra spec.base_domain prop added to it:

base_domain: us-east-2.service.guidewire.net
  1. In the same file, an extra internal endpoint needs to be exposed as well. For that, again in the same file:

    5.1. Copy its existing content, add --- line right below it and then again below it paste the copied content. Specifically for the cloned block apply the following adjustments:

    5.2. Append -internal suffix to the metadata.name property.

    5.3. Add a new spec.profiles[0].internal_only property:

    internal_only: true

    5.4. Adjust the base_domain to start with the internal. prefix:

    internal.us-east-2.service.guidewire.net

The final structure of gateway-prod.yml for our example case can look like the following example:

apiVersion: oort.ccs.guidewire.com/v1alpha1
kind: GatewayConfig
metadata:
namespace: ${NAMESPACE}
name: myjutroapp-${DEPLOY_ENV}-gateway
spec:
profiles:
- name: Default
cors:
origins:
- .*\.guidewire\.net
methods:
- GET
- OPTIONS
headers:
- '*'
credentials: true
request_transformer:
add:
headers:
- Host:tenant-mypod-myjutroapp-${S3_SUFFIX}.s3-website.us-east-2.amazonaws.com
response_transformer:
add:
headers:
- Content-Security-Policy:frame-ancestors https://*.guidewire.net
path_configs:
- name: Default
paths:
- /**
profiles:
- Default
service_ref: myjutroapp-external-name-service
service_alias: myjutroapp-${NAMESPACE}
base_domain: us-east-2.service.guidewire.net
enable_sub_domain: false
---
apiVersion: oort.ccs.guidewire.com/v1alpha1
kind: GatewayConfig
metadata:
namespace: ${NAMESPACE}
name: myjutroapp-${DEPLOY_ENV}-gateway-internal
spec:
profiles:
- name: Default
internal_only: true
cors:
origins:
- .*\.guidewire\.net
methods:
- GET
- OPTIONS
headers:
- '*'
credentials: true
request_transformer:
add:
headers:
- Host:tenant-mypod-myjutroapp-${S3_SUFFIX}.s3-website.us-east-2.amazonaws.com
response_transformer:
add:
headers:
- Content-Security-Policy:frame-ancestors https://*.guidewire.net
path_configs:
- name: Default
paths:
- /**
profiles:
- Default
service_ref: myjutroapp-external-name-service
service_alias: myjutroapp-${NAMESPACE}
base_domain: internal.us-east-2.service.guidewire.net
enable_sub_domain: false
Note: Make sure to apply the appropriate adjustments corresponding to the content of your existing ingress-prod.yml file.
  1. In the .teamcity/settings.kts TeamCity config file, adjust the existing references to ingress[-prod].yml files and switch them to the newly created gateway[-prod].yml.

  2. Once your new manifests are adjusted to reflect the existing ingress[-prod].yml configs and are confirmed to meet your needs, remove the old ingress.yml and ingress-prod.yml files. Also make sure to delete the existing HAProxy-based resources from the appropriate clusters before fully switching to OORT, in order to avoid conflicts with exposing 2 configs using the same URL underneath.

On this page