# 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, AI Assistant
- **Frontend**: Blazor Server web application with BPMN editor, notification center, and AI workflow generation
- **Activity Services**: 28+ activity implementations for various integrations (HTTP, SQL, Azure, AWS, messaging, 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

```bash
# 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

```bash
# 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:

```bash
# 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:

```bash
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:

```yaml
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:

```bash
# 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:

```yaml
global:
  imageCredentials:
    existingSecret: "flow-registry-credentials"
```

### Namespace Configuration

All Flow components are installed into a single namespace for easy management and cleanup:

```yaml
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 flow` removes 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:

```yaml
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.

```yaml
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.

```yaml
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
```yaml
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:

```yaml
podSecurityContext:
  fsGroup: 1000
  runAsNonRoot: true

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  allowPrivilegeEscalation: false
  capabilities:
    drop:
      - ALL
  readOnlyRootFilesystem: true
```

### Network Policies

Enable network policies for production:

```yaml
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](https://cert-manager.io/) must be installed in your cluster

```bash
# 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:**

```yaml
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:**
1. The chart creates a self-signed ClusterIssuer
2. A CA certificate is generated and stored as a Kubernetes secret
3. An Issuer is created that uses the CA to sign certificates
4. 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`
5. Certificates are automatically rotated before expiry

**Multi-namespace deployment:**

If you need to deploy Flow components across multiple namespaces:

```yaml
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):

```yaml
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`

## GitOps Integration
