Skip to content

Presets

A preset is a baseline that many resources inherit. You write the sizing, the topology, the backup policy, and the authentication defaults once. Each resource then names the preset and sets only what is its own. What runs on that shape, the versions and the pinned images, lives in a CamundaRelease. The result is a small manifest per resource, one place to change the shape of a fleet, and one place to roll its versions.

The operator has three preset kinds and one release kind:

Kind Holds Inherited by Reference field
CamundaClusterPreset The shape of a cluster CamundaCluster spec.presetRef
ElasticsearchClusterPreset The shape of an Elasticsearch cluster ElasticsearchCluster spec.presetRef
DatabaseServerPreset The shape of a PostgreSQL server DatabaseServer spec.presetRef
CamundaRelease Every version and the pinned images CamundaCluster, ElasticsearchCluster, DatabaseServer spec.releaseRef

All four are cluster-scoped. They create nothing, and they report no status. The resource that references them merges the preset first, then the release, then its own spec. A later layer wins. The preset baseline is spec.cluster on the two cluster presets, and spec.server on DatabaseServerPreset.

No preset holds a version. All three reject one, so a version roll never edits a preset.

The four layers of a Camunda cluster

A CamundaCluster gets its configuration from four layers:

graph LR
    PFC[CamundaPlatformConfig<br/>one per environment] -.-> CC
    CCP[CamundaClusterPreset<br/>one per cluster shape] -.-> CC
    CR[CamundaRelease<br/>one per rollout] -.-> CC
    CC[CamundaCluster<br/>one per cluster]
Hold "Alt" / "Option" to enable pan & zoom
Layer Holds Who writes it How often
CamundaPlatformConfig The authentication method, the identity provider, the license, the image repositories The platform team Once per environment
CamundaClusterPreset Sizing, topology, connectors, backup policy, auth defaults, administrators The platform team Once per cluster shape, for example small, medium, large
CamundaRelease Every version of the platform, pinned images, the environment a version needs The platform team Once per rollout, for example camunda-8-9-4
CamundaCluster The references, the URL, the storage, and any override The team that owns the cluster Once per cluster

The platform config does not merge. Every cluster that references it gets the same values. The other three merge in order: the preset first, then the release, then the cluster. The merge rules describe how each field merges.

A cluster in a few lines

With a platform config, a preset, and a release in place, a team creates a cluster like this:

apiVersion: core.camunda.io/v1
kind: CamundaCluster
metadata:
  name: orders
  namespace: orders
spec:
  presetRef: medium
  releaseRef: camunda-8-9-4
  platformConfigRef: production
  storageRef: orders-storage
  externalUrl: "https://orders.camunda.example.com"

The broker count, the partitions, the volumes, the connectors, the backup policy, and the administrators all come from the preset medium. The versions come from the release camunda-8-9-4. The authentication method and the identity provider come from the platform config production.

A cluster sets the fields that belong to it alone: the references, the URL, the ServiceAccount, monitoring, suspend, and pause. The API server rejects a preset that sets one of them, or that sets version or connectors.version. The validation rules list them.

An ElasticsearchCluster works the same way. The instance-bound fields are presetRef, releaseRef, secondaryStorageConfig, and suspend:

apiVersion: core.camunda.io/v1
kind: ElasticsearchCluster
metadata:
  name: orders-es
  namespace: orders
spec:
  presetRef: standard
  releaseRef: camunda-8-9-4
  secondaryStorageConfig: orders-storage

A DatabaseServer reads the same release through spec.releaseRef. It takes its PostgreSQL major from the spec.databaseServer.version of that release.

Write a preset

Name a preset for the shape it describes, not for a team. A team picks a shape. A preset that carries a team name invites a copy per team, and then a fleet change becomes many changes.

A CamundaClusterPreset that defines a medium production cluster, with connectors and administrators:

apiVersion: core.camunda.io/v1
kind: CamundaClusterPreset
metadata:
  name: medium
spec:
  cluster:
    zeebe:
      replicas: 3
      partitions: 3
      replicationFactor: 3
      storageClassName: "ssd"
      storageSize: "32Gi"
      resources:
        requests: { cpu: "1", memory: "2Gi" }
        limits: { cpu: "2", memory: "4Gi" }
    gateway:
      mode: Standalone
      replicas: 2
    connectors:
      enabled: true
    backup:
      primaryStorage:
        continuous: true
        schedule: "PT1H"
        retention:
          window: "P7D"
    auth:
      admin:
        mappingRules:
          - id: "platform-admins"
            claimName: "groups"
            claimValue: "camunda-admins"

A CamundaRelease for the rollout that runs on it:

apiVersion: core.camunda.io/v1
kind: CamundaRelease
metadata:
  name: camunda-8-9-4
spec:
  version: "8.9.4"
  connectors:
    version: "8.9.7"
  elasticsearch:
    version: "9.2.8"
  databaseServer:
    version: "17"

One release names every version of the platform. The ElasticsearchCluster and the DatabaseServer that reference it take theirs from it.

An ElasticsearchClusterPreset for the storage that goes with it:

apiVersion: core.camunda.io/v1
kind: ElasticsearchClusterPreset
metadata:
  name: standard
spec:
  cluster:
    replicas: 3
    storageSize: "64Gi"
    storageClassName: "ssd"
    resources:
      requests: { cpu: "1", memory: "2Gi" }
      limits: { memory: "2Gi" }

The backup policy of the preset takes effect on a cluster that sets spec.backupStorageRef. A cluster without a bucket takes no backups and ignores the policy. See the backup guide.

A DatabaseServerPreset carries the shape of a PostgreSQL server under spec.server, and its instance-bound fields are presetRef, releaseRef, databaseServerConfig, and suspend. Its archive block is inheritable, because one bucket serves a fleet and every server writes under a prefix of its own.

The CamundaClusterPreset, ElasticsearchClusterPreset, and DatabaseServerPreset pages list every field.

Three ready-to-apply presets are in config/example/presets, and the release that the example clusters and their storage name is in config/example/releases. The example inventories next to them name both. A CamundaCluster there keeps its references and the fields that belong to that one cluster. The example release is camunda-8-9, a release that you edit in place, see Change a fleet.

Override one field

A cluster overrides a field of the preset by setting it. The other fields of the preset stay, except where the merge rules say otherwise, for example for auth.clientId. A cluster that needs more brokers than medium gives, and nothing else:

apiVersion: core.camunda.io/v1
kind: CamundaCluster
metadata:
  name: payments
  namespace: payments
spec:
  presetRef: medium
  platformConfigRef: production
  storageRef: payments-storage
  externalUrl: "https://payments.camunda.example.com"
  zeebe:
    replicas: 5
    partitions: 5

Most fields merge like this, value by value. A few blocks replace as a whole: scheduling, auth.admin, auth.basic, and backup.dump.scratchVolume. A cluster that sets auth.admin names every administrator again. The merge rules hold the full table.

Change a fleet

When you edit a preset, every cluster that references it takes the new baseline and rolls its pods. A change under auth.basic rolls no pods. A larger storageSize grows the volumes of every cluster in place. A lower storageSize is ignored for a cluster that applied a larger size. That cluster keeps its volumes and records the event StorageShrinkIgnored. A new storageClassName reaches only the clusters that do not have a broker StatefulSet yet. A cluster that inherits the class and has a broker StatefulSet, also a suspended one, keeps its class and records the event StorageClassChangeIgnored. Volumes that whenDeleted: Retain kept from a deleted cluster of the same name keep their class.

You can roll versions in two ways. Name the release for the way you pick:

  • To move every resource at one time, edit the release in place. Name it for the minor line, for example camunda-8-9. Every resource that references it rolls its pods, whatever preset sizes it.
  • To move resources in steps, keep one release per version, for example camunda-8-9-4. Create the next one, for example camunda-8-9-5. Then move resources to it one at a time by changing releaseRef. When every resource is on the new release, delete the old one.

The examples on this page use the second way.

Every cluster whose brokers run a higher version refuses a lower one. Each one reports Ready: False with reason VersionDowngradeRefused and keeps the version its brokers run. To lower a fleet on purpose, lower the release first and let every cluster refuse. Then set the annotation camunda.io/allow-version-downgrade to the version of the release, on each cluster you want to move. Read the caution in Downgrade on purpose first.

A DatabaseServer refuses a PostgreSQL major other than the one its data directory runs, higher or lower. It reports Ready: False with reason VersionChangeRefused and keeps the major it has. No annotation lets that change through. To run a later major, create a server on it and move the data over. The DatabaseServer page states the rule.

A resource that references a preset or a release that does not exist reports Ready: False with reason InvalidReference and keeps running as it is.