Flow Helm Chart
A Helm chart for deploying the Flow workflow automation platform to Kubernetes.
Overview
Flow is a distributed workflow automation platform consisting of:
- Core Services: Workflow Engine, Activity Registry, Definition Store, Workflow Logging, Connection Store, Tenant Registry
- Frontend: Blazor WebAssembly web application
- Activity Services: 23+ activity implementations for various integrations (HTTP, SQL, Azure, AWS, etc.)
- Infrastructure: RabbitMQ for messaging, PostgreSQL for persistence, Redis for caching (optional)
Prerequisites
- Kubernetes 1.25+
- Helm 3.8+
- PV provisioner (if using built-in PostgreSQL/RabbitMQ)
- cert-manager (optional, for internal TLS)
Quick Start
Add the Helm Repository
# Add the Entit Helm repository
helm repo add entit https://git.kn.entit.eu/EntitAB/Helm-Charts/raw/branch/main
# Update repository cache
helm repo update
# Search for available versions
helm search repo entit/flow --versions
Install the Chart
# Install with default values (uses --namespace flag for installation namespace)
helm install flow entit/flow \
--namespace flow \
--create-namespace
# Install with explicit namespace configuration
helm install flow entit/flow \
--namespace flow \
--create-namespace \
--set global.namespace=flow
# Install with custom values file
helm install flow entit/flow \
--namespace flow \
--create-namespace \
-f values.yaml
Using Example Values Files
Example values files are available in the examples/ directory:
# Download example values for production
curl -O https://git.kn.entit.eu/EntitAB/Helm-Charts/raw/branch/main/examples/values-prod.yaml
# Download example values for development
curl -O https://git.kn.entit.eu/EntitAB/Helm-Charts/raw/branch/main/examples/values-dev.yaml
# Install with production values
helm install flow entit/flow \
--namespace flow \
--create-namespace \
-f values-prod.yaml \
--set global.azureAd.tenantId=YOUR_TENANT_ID \
--set global.azureAd.clientId=YOUR_CLIENT_ID
Configuration
Global Configuration
| Parameter | Description | Default |
|---|---|---|
global.namespace |
Namespace to install all Flow components (uses --namespace if not set) | "" |
global.imageRegistry |
Container registry for all images | cr.kn.entit.eu |
global.imagePullSecrets |
Image pull secrets (list of existing secret names) | [] |
global.imageCredentials.enabled |
Enable creation of image pull secret from credentials | false |
global.imageCredentials.username |
Registry username | "" |
global.imageCredentials.password |
Registry password | "" |
global.azureAd.enabled |
Enable Azure AD authentication | true |
global.azureAd.tenantId |
Azure AD tenant ID | "" |
global.azureAd.clientId |
Azure AD application client ID | "" |
global.database.provider |
Database provider (Postgres/SqlServer) | Postgres |
Harbor Registry Authentication
The Flow images are hosted on Harbor at cr.kn.entit.eu. Harbor requires authentication to pull images even from public repositories.
Option 1: Auto-create Secret with Credentials (Recommended)
Pass Harbor credentials during installation to automatically create the registry secret:
helm install flow entit/flow \
--namespace flow \
--create-namespace \
--set global.imageCredentials.enabled=true \
--set global.imageCredentials.username=$HARBOR_USER \
--set global.imageCredentials.password=$HARBOR_PASSWORD
Or in your values file:
global:
imageRegistry: "cr.kn.entit.eu"
imageCredentials:
enabled: true
username: "" # Set via --set flag
password: "" # Set via --set flag
Option 2: Use Existing Secret
If you prefer to manage the secret separately:
# Create the secret first
kubectl create secret docker-registry flow-registry-credentials \
--docker-server=cr.kn.entit.eu \
--docker-username=$HARBOR_USER \
--docker-password=$HARBOR_PASSWORD \
-n flow
Then reference it in values:
global:
imageCredentials:
existingSecret: "flow-registry-credentials"
Namespace Configuration
All Flow components are installed into a single namespace for easy management and cleanup:
global:
# Explicit namespace - recommended for production
namespace: "flow-production"
If global.namespace is not set, the chart uses the namespace from the helm install --namespace flag.
Benefits of single-namespace deployment:
- Easy cleanup:
kubectl delete namespace flowremoves everything - Simplified RBAC management
- Clear resource ownership
- Simplified network policies
Service URLs
All internal services communicate using full Kubernetes FQDN format:
http://<service-name>.<namespace>.svc.cluster.local:<port>
This ensures reliable cross-namespace communication when services run in separate pods.
Core Services
Each core service supports the following configuration:
| Parameter | Description | Default |
|---|---|---|
<service>.enabled |
Enable the service | true |
<service>.replicaCount |
Number of replicas | 1 |
<service>.image.repository |
Image repository | varies |
<service>.image.tag |
Image tag | "" (uses appVersion) |
<service>.resources |
CPU/Memory resources | varies |
<service>.autoscaling.enabled |
Enable HPA | false |
<service>.ingress.enabled |
Enable ingress | false |
Activity Services
Activity services can be enabled/disabled individually:
httpRequestActivity:
enabled: true
replicaCount: 2
sqlActivity:
enabled: true
# Disable activities not needed
awsS3Activity:
enabled: false
External Managed Services
For production deployments, use external managed services instead of the built-in infrastructure.
External PostgreSQL
Supports Azure Database for PostgreSQL, AWS RDS, Google Cloud SQL, and other managed PostgreSQL services.
global:
database:
provider: "Postgres"
postgres:
external: true
host: "myserver.postgres.database.azure.com"
port: 5432
database: "flow_prod"
username: "flow@myserver" # Azure format: user@server
existingSecret: "flow-db-secret"
existingSecretKey: "postgres-password"
sslMode: "require"
pooling:
minSize: 10
maxSize: 200
postgresql:
enabled: false # Disable built-in PostgreSQL
External RabbitMQ
Supports CloudAMQP, Amazon MQ, and self-hosted clusters.
global:
rabbitmq:
external: true
host: "xyz.rmq.cloudamqp.com"
port: 5672
username: "flow"
existingSecret: "flow-rabbitmq-secret"
existingSecretKey: "rabbitmq-password"
vhost: "/"
tls:
enabled: true
rabbitmq:
enabled: false # Disable built-in RabbitMQ
External Redis
Supports Azure Cache for Redis, Amazon ElastiCache, Redis Cloud, and self-hosted Redis.
Standalone Mode
global:
redis:
enabled: true
external: true
mode: "standalone"
host: "myredis.redis.cache.windows.net"
port: 6380
existingSecret: "flow-redis-secret"
existingSecretKey: "redis-password"
tls:
enabled: true
redis:
enabled: false # Disable built-in Redis
Security
Pod Security
The chart enforces secure defaults:
podSecurityContext:
fsGroup: 1000
runAsNonRoot: true
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
Network Policies
Enable network policies for production:
networkPolicy:
enabled: true
Internal TLS (mTLS between Microservices)
Enable encrypted communication between all Flow microservices using cert-manager with self-signed certificates. This is recommended for production environments to ensure data in transit is encrypted within the cluster.
Prerequisites:
- cert-manager must be installed in your cluster
# Install cert-manager if not already installed
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.0/cert-manager.yaml
Enable Internal TLS:
global:
# All Flow components will be installed in this namespace
namespace: "flow"
tls:
# Enable TLS for all internal service communication
enabled: true
# Additional namespaces for cross-namespace communication (optional)
# Certificates will be valid for services in all listed namespaces
namespaces: []
# Example for multi-namespace deployment:
# namespaces:
# - "flow-activities"
# - "flow-infrastructure"
certManager:
# Use cert-manager to manage certificates
enabled: true
# Create a self-signed CA for internal certificates
createSelfSignedIssuer: true
# Certificate settings
duration: "2160h" # 90 days
renewBefore: "720h" # Renew 30 days before expiry
# Private key algorithm (ECDSA is faster and more secure)
privateKey:
algorithm: "ECDSA"
size: 256
# CA certificate settings
ca:
duration: "87600h" # 10 years
renewBefore: "8760h" # Renew 1 year before expiry
commonName: "Flow Internal CA"
organization: "Your Organization"
# Minimum TLS version
minVersion: "1.2"
How it works:
- The chart creates a self-signed ClusterIssuer
- A CA certificate is generated and stored as a Kubernetes secret
- An Issuer is created that uses the CA to sign certificates
- Each service gets a certificate valid for:
<service-name><release>-<service-name>.<namespace>.svc.cluster.local(for the installation namespace)- Additional namespaces if configured in
tls.namespaces
- Certificates are automatically rotated before expiry
Multi-namespace deployment:
If you need to deploy Flow components across multiple namespaces:
global:
namespace: "flow"
tls:
enabled: true
# Certificates will be valid for services in all these namespaces
namespaces:
- "flow-activities"
- "flow-infrastructure"
Using an existing issuer:
If you already have a cert-manager issuer configured (e.g., using Vault or an enterprise CA):
tls:
enabled: true
certManager:
enabled: true
createSelfSignedIssuer: false
issuerRef:
name: "my-existing-issuer"
kind: "ClusterIssuer" # or "Issuer"
group: "cert-manager.io"
Service URLs with TLS:
When TLS is enabled, service URLs automatically switch to HTTPS:
- Without TLS:
http://flow-workflow-engine.flow.svc.cluster.local:80 - With TLS:
https://flow-workflow-engine.flow.svc.cluster.local:443