Skip to main content

Helm chart

Production Kubernetes deployment: one all-in-one workload scaled by replicaCount, a leader-elected scheduler, External Secrets integration, and the graceful-shutdown behaviour upgrades depend on.

Install

# The chart is published to the OCI registry — there is no classic Helm repo to add.
helm install cap oci://ghcr.io/cloudnativeworks/charts/certautopilot \
--namespace cap --create-namespace \
--version <chart-version> \
-f values.yaml

Minimum values.yaml

image:
tag: "1.4.0"

replicaCount: 2 # backend replicas; the scheduler inside them is leader-elected

externalMongodb:
enabled: true
uri: mongodb://mongo-rs-0.mongo:27017,mongo-rs-1.mongo:27017,mongo-rs-2.mongo:27017/certautopilot?replicaSet=rs0

secrets:
jwt:
secret: "<random string>" # required in release mode unless secrets.existingSecret is set
encryption:
provider: env
currentVersion: 1 # seeds the first install only; the keystore is authoritative afterwards
kekVersions:
"1": "<64 hex chars>" # every version existing data references must stay listed

scheduler:
leaderLockTTL: "90s" # chart default is 2h — see below
warning
externalMongodb.uri is rendered into a ConfigMap in plaintext

It is not a Secret path. If the connection string carries credentials, they end up readable by anyone who can read ConfigMaps in the namespace.

warning
Set scheduler.leaderLockTTL

The chart ships 2h, while the code's own default is 90 s. Left alone, a scheduler failover on Kubernetes can take up to two hours. Set it to 90s unless you have a reason not to.

Workloads

The chart deploys two Deployments and two Services, plus an optional ServiceMonitor and PrometheusRule.

WorkloadModeNotes
backendall — fixedRuns API, worker and scheduler in one process. Scale with replicaCount; the scheduler is leader-elected via MongoDB, so extra replicas are safe.
frontendServes the React bundle.

There is no Ingress, no HorizontalPodAutoscaler and no PodDisruptionBudget in the chart — add your own if you need them. There is also no per-mode split: the backend's arguments are fixed at serve --mode=all, so api: / worker: / scheduler: value keys do nothing.

External Secrets

In release mode the chart requires either plaintext secrets.jwt.secret and secrets.encryption.kekVersions in values, or secrets.existingSecret naming a pre-created Secret — rendering fails with an explicit error if neither is present. Use existingSecret to keep secrets out of values.yaml entirely. Most users wire them up via External Secrets Operator pulling from AWS Secrets Manager, GCP SM, or Vault.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata: {name: cap-kek, namespace: cap}
spec:
refreshInterval: 1h
secretStoreRef: {name: aws-sm, kind: ClusterSecretStore}
target: {name: cap-kek}
data:
- secretKey: encryption-env-kek-v1 # 64 hex chars, not raw bytes
remoteRef: {key: certautopilot/prod/kek-v1}
- secretKey: encryption-current-version
remoteRef: {key: certautopilot/prod/kek-current-version}
- secretKey: jwt-secret
remoteRef: {key: certautopilot/prod/jwt}

Point the chart at it with secrets.existingSecret: cap-kek and secrets.existingSecretVersions: [1]. The key names are fixed — the chart reads encryption-env-kek-v{N}, one per version, and refuses to render if kekVersions is empty while provider: env.

Metrics

/metrics is served over HTTPS on the backend's own port (config.server.port, 8181 by default) — not on a separate 9090. Set serviceMonitor.enabled=true (note: top-level, not metrics.serviceMonitor) to deploy the ServiceMonitor for Prometheus Operator users.

Draining nodes

The chart ships no PodDisruptionBudget. On SIGTERM the worker waits up to 55 seconds for its in-flight job to finish and only then releases the lock. The chart, however, sets terminationGracePeriodSeconds: 30 and installs no preStop hook — so a job still running at 30 seconds is SIGKILLed, and its lock is only reclaimed after the 5-minute lock TTL expires.

Raise terminationGracePeriodSeconds to 60 if your jobs routinely run longer than 30 seconds. Size drain windows against the 5-minute TTL either way, and add your own PDB if you need to bound simultaneous evictions.

Upgrade

helm upgrade cap oci://ghcr.io/cloudnativeworks/charts/certautopilot \
--namespace cap \
--version <chart-version> \
-f values.yaml \
--atomic --wait

There is no migration job — the chart ships none, and there are no schema migrations to run. --atomic rolls back if the rollout fails.

See also