Skip to content

Deploy on Managed Kubernetes

This page turns the Choose a Cloud Profile map into a concrete, copy-paste deployment. The chart is cloud-agnostic by design; the only per-cloud surface is the secret-store authentication, the storage class, and the ingress annotations.

The reference artifacts live in infra/helm/caracal/examples:

  • values.cloud-managed.yaml — production overlay with externalized state, cert-manager TLS ingress, ServiceMonitor, and tightened egress.
  • external-secrets/ — External Secrets Operator stores for AWS, GCP, and Azure plus one cloud-agnostic ExternalSecret.
ComponentWhy
Managed PostgresAuthoritative product, policy, audit, and delegation state.
Managed RedisStreams for audit, revocation, policy invalidation, and coordination.
External Secrets OperatorProvisions caracal-runtime from your secret manager so no plaintext secret is rendered.
cert-managerIssues TLS certificates for the Gateway and API ingress.
Prometheus OperatorConsumes the chart ServiceMonitor and PrometheusRule.

Load the Caracal secret material into your secret manager under the keys the ExternalSecret reads:

Secret manager keyContents
caracal/postgresusername, password, host, port, database.
caracal/redispassword, host, port, database.
caracal/zone-kekZone key-encryption key.
caracal/audit-hmac-key, caracal/streams-hmac-key, caracal/gateway-sts-hmac-keyIntegrity keys.
caracal/admin-token, caracal/coordinator-tokenControl-plane tokens.
caracal/sts-admin-token, caracal/audit-admin-token, caracal/metrics-bearerOptional service tokens.

2. Apply the Secret Store and ExternalSecret

Section titled “2. Apply the Secret Store and ExternalSecret”

Pick the store for your cloud and apply it with the agnostic ExternalSecret:

Terminal window
cd infra/helm/caracal/examples
kubectl apply -f external-secrets/secretstore-aws.yaml
kubectl apply -f external-secrets/externalsecret-runtime.yaml

The ExternalSecret composes databaseUrl and redisUrl and materializes the exact keys the chart mounts, so secrets.create stays false.

Terminal window
helm upgrade --install caracal infra/helm/caracal \
--namespace caracal --create-namespace \
-f infra/helm/caracal/examples/values.cloud-managed.yaml \
--set secrets.database.host=<managed-postgres-host> \
--set secrets.redis.host=<managed-redis-host>

Stable mode enforces externalized Postgres and Redis hosts and forbids in-chart plaintext secrets, so the render fails fast if either is left at a default.

SettingAWS (EKS)GCP (GKE)Azure (AKS)
Secret storesecretstore-aws.yaml (IRSA)secretstore-gcp.yaml (Workload Identity)secretstore-azure.yaml (Workload Identity)
Managed PostgresRDS / Aurora PostgreSQLCloud SQL for PostgreSQLAzure Database for PostgreSQL
Managed RedisElastiCache / MemoryDBMemorystore for RedisAzure Cache for Redis
replayPersistence.storageClassNamegp3premium-rwomanaged-csi
ingress.*.classNamealbgceazure-application-gateway
Ingress annotationsALB scheme/target-typeGCE managed cert or cert-managerAGIC annotations

Keep networkPolicy.allowOpenDns and allowOpenHttps false; set dnsEgress and extraEgress to the named CIDRs of your managed Postgres, Redis, identity provider, and provider APIs.

Caracal database migrations are forward-only by design. Plan upgrades as roll-forward changes and only roll back application images when they remain schema-compatible. See Upgrade Caracal.

Caracal ships standardized, portable interfaces — External Secrets Operator, cert-manager, and the Helm chart — rather than per-cloud infrastructure-as-code modules. This keeps the deployment surface agnostic and avoids coupling Caracal to a single provider’s resource model. Use your own IaC to provision the managed Postgres, Redis, secret manager, and cluster, then apply these artifacts.

  1. Confirm the ExternalSecret reports SecretSynced and caracal-runtime exists.
  2. Render manifests and confirm no plaintext secret is present.
  3. Confirm cert-manager issued the Gateway and API TLS certificates.
  4. Confirm the ServiceMonitor is scraped and PrometheusRule alerts are loaded.
  5. Run a canary token exchange and a Gateway-protected request, then confirm audit evidence.

Use Harden Production before opening external API or Gateway ingress to production traffic.