Red Hat OpenShift

This is a guide on how to deploy Immuta on OpenShift.

Prerequisites

The following managed services must be provisioned and running before proceeding. For further assistance consult the recommendations table for your respective cloud provider.

Feature availability

If deployed without Elasticsearch/OpenSearch, several core services and features will be unavailable. See the deployment requirements for details.

  • PostgreSQL

  • (Optional) Elasticsearch/OpenSearch

Checklist

This checklist outlines the necessary prerequisites for successfully deploying Immuta.

Credentials

PostgreSQL

Elasticsearch

Setup

Helm

Authenticate with OCI registry

echo <token> | helm registry login --password-stdin --username <username> ocir.immuta.com

Kubernetes

Creating a dedicated namespace ensures a logically isolated environment for your Immuta deployment, preventing resource conflicts with other applications.

Create project

  1. Create an OpenShift project named immuta.

    oc new-project immuta
  2. Get the UID range allocated to the project. Each running container's UID must fall within this range. This value will be referenced later on.

    oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
  3. Get the GID range allocated to the project. Each running container's GID must fall within this range. This value will be referenced later on.

    oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
  4. Switch to project immuta.

    oc project immuta

Create registry secret

Create a container registry pull secret. Your credentials to authenticate with ocir.immuta.com can be viewed in your user profile at support.immuta.com.

oc create secret docker-registry immuta-oci-registry \
    --docker-server=https://ocir.immuta.com \
    --docker-username="<username>" \
    --docker-password="<token>" \
    --docker-email=support@immuta.com

PostgreSQL

Connecting a client

There are numerous ways to connect to a PostgreSQL database. This step demonstrates how to connect with psql by creating an ephemeral Kubernetes pod.

Connect to the database

Connect to the database as an admin (e.g., postgres) by creating an ephemeral container inside the Kubernetes cluster. A shell prompt will not be displayed after executing the kubectl run command outlined below. Wait 5 seconds, and then proceed by entering a password.

oc run pgclient \
    --stdin \
    --tty \
    --rm \
    --image docker.io/bitnami/postgresql -- \
    psql --host <postgres-fqdn> --username <postgres-user> --port 5432 --password

Create Role

Temporal's upgrade mechanism utilizes SQL command CREATE EXTENSION when managing database schema changes. However, in cloud-managed PostgreSQL offerings, this command is typically restricted to roles with elevated privileges to protect the database and maintain the stability of the cloud environment.

To ensure Temporal can successfully manage its schema, a pre-defined administrator role must be granted. The role name varies depending on the cloud-managed service:

  • Amazon RDS: rds_superuser

  • Azure Database: azure_pg_admin

  • Google Cloud SQL: cloudsqlsuperuser

  1. Create the immuta role.

    CREATE ROLE immuta with LOGIN ENCRYPTED PASSWORD '<postgres-password>';
    ALTER ROLE immuta SET search_path TO bometadata,public;
  2. Grant administrator privileges to the immuta role. Upon successfully completing this installation guide, you can optionally revoke this role grant.

    GRANT <admin-role> TO immuta;

Create databases

  1. Create databases.

    CREATE DATABASE immuta OWNER immuta;
    CREATE DATABASE temporal OWNER immuta;
    CREATE DATABASE temporal_visibility OWNER immuta;
  2. Grant role immuta additional privileges. Refer to the PostgreSQL documentation for further details on database roles and privileges.

    GRANT ALL ON DATABASE immuta TO immuta;
    GRANT ALL ON DATABASE temporal TO immuta;
    GRANT ALL ON DATABASE temporal_visibility TO immuta;
  3. Configure the immuta database.

    \c immuta
    CREATE EXTENSION pgcrypto;
  4. Configure the temporal database.

    \c temporal
    GRANT CREATE ON SCHEMA public TO immuta;
  5. Configure the temporal_visibility database.

    \c temporal_visibility
    GRANT CREATE ON SCHEMA public TO immuta;
    CREATE EXTENSION btree_gin;
  6. Exit the interactive prompt. Type \q, and then press Enter.

Install Immuta

This section demonstrates how to deploy Immuta using the Immuta Enterprise Helm chart once the prerequisite cloud-managed services are configured.

Why disable Ingress?

In OpenShift, Ingress resources are managed by OpenShift Routes. These routes provide a more integrated and streamlined way to handle external access to your applications. To avoid conflicts and ensure proper functionality, it's necessary to disable the pre-defined Ingress resource in the Helm chart.

Feature availability

If deployed without Elasticsearch/OpenSearch, several core services and features will be unavailable. See the deployment requirements for details.

immuta-values.yaml
global:
  imageRegistry: ocir.immuta.com
  imagePullSecrets:
    - name: immuta-oci-registry
  postgresql:
    host: <postgres-fqdn>
    port: 5432
    username: immuta
    password: <postgres-password>

audit:
  config:
    elasticsearchEndpoint: http://es-db-elasticsearch.immuta.svc.cluster.local:9200
    elasticsearchUsername: <elasticsearch-username>
    elasticsearchPassword: <elasticsearch-password>
  postgresql:
    database: immuta 

  deployment:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  worker:
    podSecurityContext:  
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL 

discover:
  deployment:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

secure:
  ingress:
    enabled: false

  postgresql:
    database: immuta
    ssl: false

  web:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault
  
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL

  backgroundWorker:
    podSecurityContext:
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
      runAsUser: <user-id>
      # A number that is within the project range:
      #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
      runAsGroup: <group-id>
      seccompProfile:
        type: RuntimeDefault
      
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  
temporal:
  enabled: true
  schema:
    createDatabase:
      enabled: false
  server:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
    config:
      persistence:
        default:
          sql:
            database: temporal
            tls:
              enabled: true
        visibility:
          sql:
            database: temporal_visibility
            tls:
              enabled: true
    frontend:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    history:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    matching:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    worker:
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
  schema:
    podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
  proxy:
    deployment:
      podSecurityContext:
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
        runAsUser: <user-id>
        # A number that is within the project range:
        #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
        runAsGroup: <group-id>
        seccompProfile:
          type: RuntimeDefault
      containerSecurityContext:
        enabled: true
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
  1. Create a file named immuta-values.yaml with the above content, making sure to update all placeholder values.

  2. Deploy Immuta.

    helm install immuta oci://ocir.immuta.com/stable/immuta-enterprise \
        --values immuta-values.yaml \
        --version 2024.3.5
  3. Wait for all pods to become ready.

    oc wait --for=condition=Ready pods --all

Validation

This section helps you validate your Immuta installation by temporarily accessing the application locally. However, this access is limited to your own computer. To enable access for other devices, you must proceed with configuring Ingress outlined in the Next steps section.

  1. Determine the name of the Secure service.

    oc get service --selector "app.kubernetes.io/component=secure" --output name
  2. Listen on local port 8080, forwarding TCP traffic to the Secure service's port named http.

    oc port-forward <service-name> 8080:http
  3. In a web browser, navigate to localhost:8080, to ensure the Immuta application loads.

  4. Press Control+C to stop port forwarding.

Next steps

Last updated

Copyright © 2014-2024 Immuta Inc. All rights reserved.