Configure zone-aware multi-region deployments
The Camunda Helm chart deploys an Orchestration Cluster across named zones through orchestration.partitioning. Each zone runs its own release of the chart, and every release describes the same cluster-wide topology. The zone list is therefore identical everywhere, and only the local zone name changes.
For what zones are and how the application places partition replicas across them, see zone-aware clusters.
Move from global.multiregion
Chart v15 (Camunda 8.10) deprecates global.multiregion. Only the Orchestration Cluster ever read these keys, so they now live under orchestration.partitioning. The deprecated keys still work and still render in v15. Chart v16 removes them, so move them before you upgrade to v16.
Two keys shipped under global.multiregion: regions and regionId. They configure the broker numbering for dual-region deployments. The new block describes zones rather than regions, so the keys change name as well as location:
| Deprecated key | Replacement |
|---|---|
global.multiregion.regions | orchestration.partitioning.numberOfZones |
global.multiregion.regionId | orchestration.partitioning.zoneIndex |
The values do not change. Only the names and their location change:
# Before
global:
multiregion:
regions: 2
regionId: 1
# After
orchestration:
partitioning:
numberOfZones: 2
zoneIndex: 1
Keeping the old names under the new block fails the render. The schema declares orchestration.partitioning with additionalProperties: false. It allows only scheme, zone, zones, numberOfZones, zoneIndex, and keepUnzonedBrokers. The chart therefore rejects the old pair with additional properties 'regionId', 'regions' not allowed instead of ignoring it.
Both key paths produce the same broker numbering. The deprecated one renders identically and adds a deprecation warning. Setting both blocks fails the render. The chart does not pick one, because neither block merges into the other. The ignored block would describe a topology you don't get.
You configure zone awareness only under orchestration.partitioning. The scheme, zone, and zones keys have never existed under global.multiregion, so there is nothing to migrate for a zone-aware cluster.
Choose a partitioning scheme
orchestration.partitioning.scheme selects how the chart distributes partitions and how it identifies brokers. It mirrors the engine property camunda.cluster.partitioning.scheme, so the values are the engine's own enum, lower-cased and hyphenated. It does not set the number of partitions, which is orchestration.partitionCount. It sets how the chart places the replicas of those partitions.
| Scheme | Behavior |
|---|---|
round-robin | Default. Brokers get numeric node IDs and the region is inferred from parity. Two regions at most. |
zone-aware | Brokers belong to named zones and are identified as <zone>_<index>. Any number of zones. |
These are the two schemes the chart renders, not the whole engine enum. camunda.cluster.partitioning.scheme also accepts FIXED, which pins each partition to an explicit broker list. The chart has no value that produces it. Use it only through orchestration.configuration, which replaces the generated configuration outright.
Existing deployments keep their behavior. When you don't set scheme, the chart renders as it did before zone awareness existed.
The scheme is fixed for the life of the cluster
Zone-aware brokers carry the composite ID <zone>_<index>. Round-robin brokers carry a plain node ID. Do not change scheme on a running release. To move an existing cluster onto zone awareness, follow the migration procedure.
Changing orchestration.partitioning.scheme on a running release is not a values change you can apply on its own. The migration procedure keeps both broker generations alive through orchestration.partitioning.keepUnzonedBrokers. It then moves the partition distribution with the cluster management API. Set the scheme when you create the cluster, or follow that procedure. Do not edit the key in place.
The chart states the same constraint at render time. An upgrade that flips the scheme prints a warning instead of failing silently.
Describe the topology
With the zone-aware scheme, set the local zone and list every zone in the cluster:
orchestration:
partitioning:
scheme: zone-aware
zone: region-a
zones:
- name: region-a
numberOfBrokers: 2
numberOfReplicas: 2
priority: 100
- name: region-b
numberOfBrokers: 3
numberOfReplicas: 3
priority: 50
Use the same zones list in every region and change only zone to name the local one. The list accepts any number of zones. One, two, and three are the common cases.
Each zone field maps to an application property. For what these properties do, see zone-aware clusters and the camunda.cluster.partitioning reference.
| Helm value | Application property |
|---|---|
name | name |
numberOfBrokers | number-of-brokers |
numberOfReplicas | number-of-replicas |
priority | priority |
Values the chart derives from the zone list
You describe the topology once, and the chart computes the rest. Knowing what it derives tells you which values you must not set yourself.
| Rendered setting | Derived from |
|---|---|
camunda.cluster.size | Sum of numberOfBrokers across all zones |
camunda.cluster.replication-factor | Sum of numberOfReplicas across all zones |
| StatefulSet replica count | numberOfBrokers of the local zone |
CAMUNDA_CLUSTER_ZONE in the pod | orchestration.partitioning.zone |
camunda.cluster.node-id | The pod ordinal, which is the broker's index inside its own zone |
A zone-aware broker uses the composite ID <zone>_<index>, so the zone name keeps each broker unique across the cluster. The index restarts at 0 in every zone, and no cluster-wide offset applies.
Provide initial contact points beyond one zone
The chart generates initial contact points only for a single-zone cluster, because one zone sits behind one headless service the chart can address itself. Once the cluster spans more than one zone, the chart cannot know how brokers reach each other across zones. It then generates nothing, and you supply the list through the application environment variables.
A cluster that spans more than one zone with no contact points still renders and installs. The chart prints a [camunda][warning] that tells you to set CAMUNDA_CLUSTER_INITIALCONTACTPOINTS through orchestration.env. The chart does not fail the render. A missing list therefore appears as brokers that never form a cluster, not as a failed helm upgrade. Treat the warning as an error.
One entry per zone is enough, and it does not have to name a specific broker. A broker resolves a contact point once, to a single address. An entry that points at a zone's headless Zeebe service reaches whichever broker pod DNS returns.
A broker only has to reach one live member to join. SWIM membership gossip carries the rest of the cluster from there. For what contact points do, see setting up a cluster. The chart sets publishNotReadyAddresses: true on that service. The name therefore resolves to a pod during a cold start, before any broker is ready. For how that flag works, see Kubernetes headless services.
You can also list every broker pod. That list tolerates more of the zone being down at bootstrap. You then rewrite the list whenever a zone's broker count changes.
Contact points matter only while the cluster bootstraps. Once brokers have found each other, membership gossip carries new members, so a broker joining later does not need to appear in anyone's list.
A single zone is still one cluster
Zone awareness with one zone gives brokers named identities. It cannot bias leaders between failure domains, because every replica has the same zone priority. The chart treats one zone as one cluster, and it generates the initial contact points for you. A second zone spreads the deployment and lets different priorities influence leader placement.
Adding a zone that was not part of the original zone list is not a Helm-only change. The partition distribution has to be updated through the cluster management API as well, because existing partitions have to be told about the new zone.
To add a zone, start the brokers in the new zone first. Then update the configuration and add the zone through the Add a zone API. Do not declare a zone before its brokers run, because every partition then runs one zone short.
Custom application configuration is not merged
orchestration.configuration replaces the generated application configuration rather than merging with it. With the zone-aware scheme, the chart therefore does not inject camunda.cluster.partitioning into your custom content. If you supply orchestration.configuration, describe the zone-aware settings there yourself.
The chart still injects CAMUNDA_CLUSTER_ZONE into the pod environment, because that value is per-deployment rather than part of the shared configuration.
What the chart validates
The chart rejects the inputs that would otherwise render a cluster that cannot form:
| Rejected | What would happen without the check |
|---|---|
zone or zones set while scheme is not zone-aware | The topology would be ignored and the cluster would come up single-region with no bootstrap peers. |
zone unset, or naming a zone absent from zones | The release would take the broker IDs of the first zone and collide with it. |
| A zone name that repeats | Zone names are member ID prefixes, so a duplicate collapses two zones into one identity space. |
A zone with more numberOfReplicas than numberOfBrokers | A zone cannot hold more replicas of a partition than it has brokers to hold them. |
orchestration.clusterSize or orchestration.replicationFactor that contradicts the zone list | Both are derived from the zone list in zoned mode, so a stale value would be discarded in silence. Restating the derived total is allowed. |
numberOfZones or zoneIndex carrying a non-default value | They belong to the round-robin broker numbering that zone awareness replaces, so the zone list would silently lose to them. |
The schema also requires each zones entry to declare name, numberOfBrokers, numberOfReplicas, and priority, with each numeric value at least 1.
The chart rejects the last two keys only when they carry a non-default value. Helm gives no reliable way to tell a value you supplied from the chart default. A key that equals its default therefore stays inert instead of failing the render. numberOfZones and zoneIndex may also carry their round-robin values while keepUnzonedBrokers is set, where they still describe the retained broker generation. The chart keeps all of these keys, and they keep working with the round-robin scheme.
The application validates what the chart cannot validate from values alone, including replica counts against the resulting partition distribution and the remaining zone constraints.
Related resources
- Zone-aware clusters: how the application places partition replicas and biases leadership across zones.
- Configure pod scheduling: make Kubernetes schedule broker pods into the zones you assigned them to.
- Multi-Region RDBMS: a three-region architecture built on zone awareness.
- Migrate to zone-aware brokers: the operational procedure for moving an existing numbered cluster onto zone awareness.