Skip to main content

Deploy Cadence with Helm on GKE (PostgreSQL + OpenSearch)

A video companion to this Codelab is available on our YouTube channel:

Codelab Overview

This codelab walks you through deploying Cadence on GKE using official Helm charts with PostgreSQL, Kafka, and OpenSearch for advanced visibility.

Prerequisites

  • Google Cloud project with billing enabled
  • An existing GKE cluster with kubectl access
  • Basic familiarity with terminal commands

What you'll build

  • A complete Cadence deployment (frontend, history, matching, worker)
  • PostgreSQL as the main persistence store
  • Kafka for visibility event streaming
  • OpenSearch v2 for advanced visibility
  • Cadence Web UI for workflow monitoring

Step 0: Set up your local tools

This step ensures you have the necessary tools installed and configured. The examples below use macOS commands, but the official documentation links provide instructions for all platforms.

Prerequisites

You'll need these tools installed locally:

Google Cloud SDK (gcloud) - Manages GCP resources and authentication

kubectl - Kubernetes command-line tool for cluster management

Helm - Kubernetes package manager

Quick install (macOS with Homebrew):

brew install --cask google-cloud-sdk
brew install kubectl
brew install helm

Authenticate and configure GCloud

Initialize gcloud (interactive setup):

gcloud init

Or configure manually:

Log in to your Google account:

gcloud auth login

Set your GCP project (replace <YOUR_GCP_PROJECT_ID> with your actual project ID):

gcloud config set project <YOUR_GCP_PROJECT_ID>
Finding your project ID

Run gcloud projects list or check the project dropdown in the Cloud Console.

Set your preferred region:

gcloud config set compute/region us-central1
GKE Autopilot

Autopilot clusters are regional, so you only need to set the region. The zone setting below is optional and only needed for zonal resources.

gcloud config set compute/zone us-central1-a

Get Cadence Helm Charts

This codelab uses the local charts approach. Clone the repository:

git clone https://github.com/cadence-workflow/cadence-charts.git
cd cadence-charts

Alternative approach: Use the remote Helm repository (not used in this codelab):

helm repo add cadence https://cadence-workflow.github.io/cadence-charts
helm repo update
Remote Helm repo

If using the remote repo, replace ./charts/cadence with cadence/cadence in install commands.


Step 1: Connect to your GKE cluster and create a namespace

Prerequisites: You need an existing GKE cluster. In many organizations, platform or infra teams manage cluster creation. If you need to create a cluster yourself, see the official documentation: Creating a GKE cluster

For this guide, we'll assume your cluster is named cadence-test-gke-1. Replace this with your actual cluster name in the commands below.

Connect kubectl to your cluster

Get credentials for your existing GKE cluster (replace cadence-test-gke-1 with your cluster name):

gcloud container clusters get-credentials cadence-test-gke-1
Cluster not found?

If this command fails (404, not found), you may need to specify the region or zone where your cluster is located:

gcloud container clusters get-credentials cadence-test-gke-1 --region us-central1

Verify the connection by listing nodes:

kubectl get nodes

You should see a list of nodes in your cluster with a Ready status.

Create a namespace for Cadence

Namespaces provide logical isolation within the cluster:

kubectl create namespace cadence-postgres-os2

Verify the namespace was created:

kubectl get namespace cadence-postgres-os2

Step 2: Review the Helm values file

This codelab uses the official example values file that configures Cadence with:

  • PostgreSQL - Main persistence store for workflow data
  • Kafka - Event streaming for visibility events (KRaft mode, no ZooKeeper)
  • OpenSearch v2 - Advanced visibility search and filtering (ES v7 API compatible)
  • Cadence services - Frontend, history, matching, worker

The Cadence Helm chart includes subcharts for all dependencies, so everything deploys together automatically.

View the values file

cat charts/cadence/examples/values.postgres-os2.yaml

The values file is well-commented and describes each configuration option. Key points:

  • OpenSearch uses the official OpenSearch Helm chart (not Bitnami)
  • Security is disabled for demo purposes—enable for production
  • Kafka topic provisioning is enabled to avoid race conditions
  • GKE Autopilot compatible with appropriate security contexts

For production environments, consider using managed services (Cloud SQL, Amazon OpenSearch Service, Confluent Cloud) or enabling security features.


Step 3: Install Cadence with Helm

Add required Helm repositories

First, ensure you're in the cadence-charts directory:

cd cadence-charts

Add the Bitnami repo (for PostgreSQL and Kafka):

helm repo add bitnami https://charts.bitnami.com/bitnami

Add the OpenSearch repo:

helm repo add opensearch https://opensearch-project.github.io/helm-charts/

Update repos to fetch the latest chart versions:

helm repo update

Build chart dependencies

Download the dependency charts:

helm dependency build ./charts/cadence

Install Cadence

helm upgrade --install cadence-release ./charts/cadence \
--namespace cadence-postgres-os2 \
-f charts/cadence/examples/values.postgres-os2.yaml \
--wait

The --wait flag keeps the command running until all pods are ready (typically 5-10 minutes).

info

GKE Autopilot warnings about "autopilot-default-resources-mutator" are normal and not errors.

Verify installation

Check that all pods are running:

kubectl get pods -n cadence-postgres-os2

You should see pods for:

  • cadence-release-frontend, cadence-release-history, cadence-release-matching, cadence-release-worker
  • cadence-release-web
  • cadence-release-postgresql
  • cadence-release-kafka-controller, cadence-release-kafka-broker
  • cadence-release-opensearch-master-0
  • Schema jobs (may show as Completed)

All pods should show Running status (or Completed for jobs).

Having issues?

If pods are stuck or crashing, see the Troubleshooting section below.


Step 4: Access Cadence services

Port-forward to Cadence services

Port-forward the frontend (for CLI access):

kubectl port-forward -n cadence-postgres-os2 svc/cadence-release-frontend 7833:7833

Keep this running and open a new terminal.

Port-forward the Web UI:

kubectl port-forward -n cadence-postgres-os2 svc/cadence-release-web 8088:8088

Access the Web UI at http://localhost:8088


Step 5: Create a sample domain

A Cadence domain is a namespace for workflows. We'll exec into a frontend pod to use the CLI.

Find a frontend pod:

POD=$(kubectl get pods -n cadence-postgres-os2 \
-l app.kubernetes.io/component=frontend \
-o jsonpath='{.items[0].metadata.name}')

Register a domain:

kubectl exec -n cadence-postgres-os2 -it "$POD" -- \
cadence --address cadence-release-frontend:7833 --transport grpc \
--do cadence-samples domain register -rd 1
note

The --transport grpc flag is required because the CLI defaults to tchannel protocol, but port 7833 is the gRPC port.

Verify domain creation:

kubectl exec -n cadence-postgres-os2 -it "$POD" -- \
cadence --address cadence-release-frontend:7833 --transport grpc \
--do cadence-samples domain describe

Step 6: Clean up (optional)

warning

These operations will delete all data.

Recommended: Delete the namespace (complete cleanup):

kubectl delete namespace cadence-postgres-os2

This removes all resources including PersistentVolumeClaims. Deletion may take a minute.

Alternative: Helm uninstall (keeps namespace and PVCs):

helm uninstall cadence-release -n cadence-postgres-os2
note

helm uninstall intentionally preserves PersistentVolumeClaims to prevent accidental data loss. To fully clean up after helm uninstall:

kubectl delete pvc --all -n cadence-postgres-os2

Troubleshooting

Installation Issues

Pods stuck in Pending:

kubectl describe pod <pod-name> -n cadence-postgres-os2

Look for resource or quota issues. Scale up your cluster or reduce resource requests.

Helm install times out:

Remove --wait and monitor manually:

kubectl get pods -n cadence-postgres-os2 -w

Schema Job Issues

Check schema job status:

kubectl get jobs -n cadence-postgres-os2

Jobs should show COMPLETIONS as 1/1.

View PostgreSQL schema job logs:

kubectl logs job/cadence-release-schema-postgresql -n cadence-postgres-os2 --tail=100

View OpenSearch schema job logs:

kubectl logs job/cadence-release-schema-elasticsearch -n cadence-postgres-os2 --tail=100

Look for connection errors or permission issues. Schema jobs typically fail if the database or search service isn't ready yet.

OpenSearch Issues

OpenSearch not starting:

kubectl get pods -n cadence-postgres-os2 -l app.kubernetes.io/name=opensearch
kubectl logs -n cadence-postgres-os2 cadence-release-opensearch-master-0 --tail=100

Test OpenSearch connectivity:

kubectl port-forward -n cadence-postgres-os2 svc/cadence-release-opensearch 9200:9200
curl -s http://localhost:9200/cadence-visibility-os2

Kafka Issues

Kafka pods not starting:

kubectl get pods -n cadence-postgres-os2 -l app.kubernetes.io/name=kafka
kubectl logs -n cadence-postgres-os2 -l app.kubernetes.io/component=controller --tail=100

General Debugging

kubectl get all -n cadence-postgres-os2
kubectl logs -n cadence-postgres-os2 <pod-name> --tail=100
kubectl describe pod -n cadence-postgres-os2 <pod-name>
helm status cadence-release -n cadence-postgres-os2

References

Cadence Resources

Kubernetes and Helm

Google Cloud Platform