Repository: camunda/camunda-platform-helm
Pull request #890 (2023-09-15 12:43:16)

feat: adding Zeebe configuration for Multi-tenancy
### Which problem does the PR fix?
Adding Zeebe configuration for Multi-tenancy 

Fixes:
- #782
- https://github.com/camunda/zeebe/issues/14307

<!-- Which GitHub issues related to or fixed by this PR, if any. -->
### What's in this PR?
- Updating Zeebe charts config and introducing the following new Zeebe configurations:
  - `ZEEBE_GATEWAY_MULTITENANCY_ENABLED`
  - `ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED`
<!--
  Explain the contents of the PR.
  Give an overview about the implementation, which decisions were made and why.
-->

### Checklist

Please make sure to follow our [Contributing Guide](../blob/main/CONTRIBUTING.md).

<!-- Place an '[x]' (no spaces) in all applicable fields. Please remove unrelated fields. -->

**Before opening the PR:**

- [x] There is no other open [pull request](../pulls) for the same update/change.
- [x] The commits follow our [Commit Guidelines](../blob/main/CONTRIBUTING.md#commit-guidelines).
- [x] Tests for charts are added (if needed).
- [ ] The main Helm chart and sub-chart are updated (if needed).
- [ ] In-repo [documentation](../blob/main/CONTRIBUTING.md#documentation) are updated (if needed).

**After opening the PR:**

- [ ] Did you sign our CLA (Contributor License Agreement)? It will show once you open the PR.
- [ ] Did all checks/tests pass in the PR?

<!--
### To-Do

- [ ] If the PR is not complete but you want to discuss the approach,
  list what remains to be done here.
-->


aabouzaid: @abbasadel I've fixed that golden value issue. Please rebase.

Patch:
diff --git a/charts/camunda-platform/README.md b/charts/camunda-platform/README.md
index 4f43fec1..246740fa 100644
--- a/charts/camunda-platform/README.md
+++ b/charts/camunda-platform/README.md
@@ -229,6 +229,7 @@ Check out the default [values.yaml](values.yaml) file, which contains the same c
 | `global` | | Global variables which can be accessed by all sub charts | |
 | | `annotations` | Can be used to define common annotations, which should be applied to all deployments | |
 | | `labels` | Can be used to define common labels, which should be applied to all deployments | |
+| | `multitenancy.enabled` | If true, then enable multitenancy in all applicable component | `false` |
 | | `image.tag` | Defines the tag / version which should be used in the chart. | |
 | | `image.pullPolicy` | Defines the [image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) which should be used. | IfNotPresent |
 | | `image.pullSecrets` | Can be used to configure [image pull secrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). Also it could be configured per component separately. | `[]` |
@@ -272,7 +273,6 @@ Check out the default [values.yaml](values.yaml) file, which contains the same c
 | | `identity.keycloak.auth.adminUser` |    Can be used to configure admin user to access existing Keycloak | `""` |
 | | `identity.keycloak.auth.existingSecret` |    Can be used to configure existing Secret object which has admin password to access existing Keycloak | `""` |
 | | `identity.keycloak.auth.existingSecretKey` |    Can be used to configure the key inside existing Secret object which has admin password to access existing Keycloak | `"admin-password"` |
-| `elasticsearch`| `enabled` | Enable Elasticsearch deployment as part of the Camunda Platform Cluster | `true` |
 
 ### Camunda Platform
 
@@ -336,7 +336,8 @@ For more information about Zeebe, visit [Zeebe Overview](https://docs.camunda.io
 | | `pvcStorageClassName` | Can be used to set the storage class name which should be used by the persistent volume claim. It is recommended to use a storage class, which is backed with a SSD. | ` ` |
 | | `extraVolumes` | Can be used to define extra volumes for the broker pods, useful for additional exporters | `[ ]`|
 | | `extraVolumeMounts` | Can be used to mount extra volumes for the broker pods, useful for additional exporters | `[ ]` |
-| | `extraInitContainers` | Can be used to set up extra init containers for the broker pods, useful for additional exporters | `[ ]` |
+| | `extraInitContainers` | (Deprecated - use `initContainers` instead) Can be used to set up extra init containers for the broker pods, useful for additional exporters | `[ ]` |
+| | `initContainers` | Can be used to set up extra init containers for the broker pods, useful for additional exporters | `[ ]` |
 | | `podAnnotations` | Can be used to define extra broker pod annotations | `{ }` |
 | | `podLabels` | Can be used to define extra broker pod labels | `{ }` |
 | | `podDisruptionBudget` | Configuration to configure a [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for the broker pods | |
@@ -434,7 +435,8 @@ For more information about Zeebe Gateway, visit
 | | `affinity` | Can be used to define [pod affinity or anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity). The default defined PodAntiAffinity allows constraining on which nodes the [Zeebe gateway pods are scheduled on](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity). It uses a hard requirement for scheduling and works based on the Zeebe gateway pod labels. | `podAntiAffinity:</br>  requiredDuringSchedulingIgnoredDuringExecution:</br>  - labelSelector: </br>    matchExpressions:</br>    - key: "app.kubernetes.io/component"</br>    operator: In</br>    values:</br>    - zeebe-gatway</br>  topologyKey: "kubernetes.io/hostname"` |
 | | `extraVolumeMounts` | Can be used to mount extra volumes for the gateway pods, useful for enabling TLS between gateway and broker | `[ ]` |
 | | `extraVolumes` | Can be used to define extra volumes for the gateway pods, useful for enabling TLS between gateway and broker | `[ ]` |
-| | `extraInitContainers` | Can be used to set up extra init containers for the gateway pods, useful for adding interceptors | `[ ]` |
+| | `extraInitContainers` | (Deprecated - use `initContainers` instead) Can be used to set up extra init containers for the gateway pods, useful for adding interceptors | `[ ]` |
+| | `initContainers` | Can be used to set up extra init containers for the broker pods, useful for additional exporters | `[ ]` |
 | | `service` | Configuration for the gateway service | |
 | | `service.type` | Defines the [type of the service](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | `ClusterIP` |
 | | `service.loadBalancerIP` | Can be used to set [ip address](https://cloud.google.com/kubernetes-engine/docs/how-to/service-parameters#lb_ip) if service.type is LoadBalancer | `""` |
@@ -475,6 +477,7 @@ For more information about Operate, visit
 | | `image.tag` | Can be set to overwrite the global tag, which should be used in that chart. | `` |
 | | `image.pullSecrets` | Can be set to overwrite the global.image.pullSecrets | `{{ global.image.pullSecrets }}` |
 | | `sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
+| | `initContainers` | Can be used to set up extra init containers for the operate pods, useful for additional exporters | `[ ]` |
 | | `contextPath` |  Can be used to make Operate web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain. | |
 | | `podAnnotations` | Can be used to define extra Operate pod annotations | `{ }` |
 | | `podLabels` |  Can be used to define extra Operate pod labels | `{ }` |
@@ -547,6 +550,7 @@ For more information about Tasklist, visit
 | | `image.tag` | Can be set to overwrite the global tag, which should be used in that chart. | `` |
 | | `image.pullSecrets` | Can be set to overwrite the global.image.pullSecrets | `{{ global.image.pullSecrets }}` |
 | | `sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
+| | `initContainers` | Can be used to set up extra init containers for the taskList pods, useful for adding interceptors | `[ ]` |
 | | `contextPath` |  Can be used to make Tasklist web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain. | |
 | | `podAnnotations` | Can be used to define extra Tasklist pod annotations | `{ }` |
 | | `podLabels` |  Can be used to define extra Tasklist pod labels | `{ }` |
@@ -621,6 +625,7 @@ For more information, visit [Optimize Introduction](https://docs.camunda.io/opti
 | | `partitionCount` |  Defines how many Zeebe partitions are set up in the cluster and which should be imported by Optimize | `"3"` |
 | | `env` |  Can be used to set extra environment variables in each Optimize container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[]` |
 | | `command` | Can be used to [override the default command provided by the container image](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) | `[]` |
+| | `initContainers` | Can be used to set up extra init containers for the optimize pods, useful for adding interceptors | `[ ]` |
 | | `extraVolumes` |  Can be used to define extra volumes for the Optimize pods, useful for tls and self-signed certificates | `[]` |
 | | `extraVolumeMounts` |  Can be used to mount extra volumes for the Optimize pods, useful for tls and self-signed certificates | `[]` |
 | | `serviceAccount` |  Configuration for the service account where the Optimize pods are assigned to | |
@@ -694,6 +699,7 @@ For more information, visit [Identity Overview](https://docs.camunda.io/docs/sel
 | | `image.tag` |   Can be set to overwrite the global.image.tag | `` |
 | | `image.pullSecrets` | Can be set to overwrite the global.image.pullSecrets | `{{ global.image.pullSecrets }}` |
 | | `sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
+| | `initContainers` | Can be used to set up extra init containers for the identity pods, useful for adding interceptors | `[ ]` |
 | | `fullURL` |  Can be used when Ingress is configured (for both multi and single domain setup). <br/> Note: If the `ContextPath` is configured, then value of `ContextPath` should be included in the fullURL too. | |
 | | `contextPath` |  Can be used to make Identity web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain. **Note:** Identity cannot be accessed over HTTP if a "contextPath" is configured. Which means that Identity cannot be configured in combined Ingress without HTTPS. To use Identity over HTTP, setup a separated Ingress using "identity.ingress" and don't set "contextPath". | `` |
 | | `podAnnotations` | Can be used to define extra Identity pod annotations | `{ }` |
@@ -797,6 +803,7 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `restapi` | Configuration of the Web Modeler restapi component | |
 | | `restapi.image` | Configuration of the restapi Docker image | |
 | | `restapi.image.repository` | Defines which image repository to use for the restapi Docker image | `web-modeler-ee/modeler-restapi` |
+| | `restapi.initContainers` | Can be used to set up extra init containers | `[]` |
 | | `restapi.sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
 | | `restapi.externalDatabase` | Can be used to configure a connection to an external database. This will only be applied if the postgresql dependency chart is disabled (by setting `postgresql.enabled` to `false`).<br/>Note: Currently, the only supported database system is PostgreSQL.| |
 | | `restapi.externalDatabase.host` | Defines the host name of the database instance | |
@@ -857,6 +864,7 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `webapp.image` | Configuration of the webapp Docker image | |
 | | `webapp.image.repository` | Defines which image repository to use for the webapp Docker image | `web-modeler-ee/modeler-webapp` |
 | | `webapp.sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
+| | `webapp.initContainers` | Can be used to set up extra init containers | `[]` |
 | | `webapp.podAnnotations` | Can be used to define extra webapp pod annotations | `{}` |
 | | `webapp.podLabels` | Can be used to define extra webapp pod labels | `{}` |
 | | `webapp.env` | Can be used to set extra environment variables in each webapp container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[]` |
@@ -901,6 +909,7 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `websockets.image` | Configuration of the websockets Docker image | |
 | | `websockets.image.repository` | Defines which image repository to use for the websockets Docker image | `web-modeler-ee/modeler-websockets` |
 | | `websockets.sidecars` | Can be used to deploy extra containers in the same pod | `[]` |
+| | `websockets.initContainers` | Can be used to set up extra init containers | `[]` |
 | | `websockets.publicHost` | Can be used to define the host on which the WebSockets server can be reached from the Web Modeler client in the browser. The default value assumes that a port-forwarding to the websockets service has been created.<br/>Note: The host will only be used if the Ingress resource for Web Modeler is disabled. | `localhost` |
 | | `websockets.publicPort` | Can be used to define the port number on which the WebSockets server can be reached from the Web Modeler client in the browser. The default value assumes that a port-forwarding to the websockets service on port `8085` has been created.<br/>Note: The port will only be used if the Ingress resource for Web Modeler is disabled. | `8085` |
 | | `websockets.podAnnotations` | Can be used to define extra websockets pod annotations | `{}` |
@@ -996,6 +1005,7 @@ For more information, visit [Introduction to Connectors](https://docs.camunda.io
 |              | `env`                                | Can be used to set extra environment variables in each Connectors container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence.                                                                                                                                                      | `[]`                                                                                                  |
 |              | `extraVolumes`                       | Can be used to define extra volumes for the Connectors pods, useful for TLS and self-signed certificates                                                                                                                                          | `[]`                                                                                                  |
 |              | `extraVolumeMounts`                  | Can be used to mount extra volumes for the Connectors pods, useful for TLS and self-signed certificates                                                                                                                                           | `[]`                                                                                                  |
+|              | `initContainers`                     | Can be used to set up extra init containers for the identity pods, useful for adding interceptors                                                                                                                                                 | `[]`                                                                                                  |
 |              | `command`                            | Can be used to [override the default command provided by the container image](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/)                                                                        | `[]`                                                                                                  |
 |              | `serviceAccount`                     | Configuration for the service account where the Connectors pods are assigned to                                                                                                                                                                   |                                                                                                       |
 |              | `serviceAccount.enabled`             | If true, enables the Connectors service account                                                                                                                                                                                                   | `true`                                                                                                |
diff --git a/charts/camunda-platform/charts/identity/templates/deployment.yaml b/charts/camunda-platform/charts/identity/templates/deployment.yaml
index a55ad402..59da806e 100644
--- a/charts/camunda-platform/charts/identity/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/identity/templates/deployment.yaml
@@ -22,6 +22,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ .Chart.Name }}
         image: {{ include "camundaPlatform.image" . | quote }}
diff --git a/charts/camunda-platform/charts/operate/templates/deployment.yaml b/charts/camunda-platform/charts/operate/templates/deployment.yaml
index 2b513a53..67ee963a 100644
--- a/charts/camunda-platform/charts/operate/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/operate/templates/deployment.yaml
@@ -22,6 +22,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ .Chart.Name }}
         image: {{ include "camundaPlatform.image" . | quote }}
diff --git a/charts/camunda-platform/charts/optimize/templates/deployment.yaml b/charts/camunda-platform/charts/optimize/templates/deployment.yaml
index b886c40d..9171b850 100644
--- a/charts/camunda-platform/charts/optimize/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/optimize/templates/deployment.yaml
@@ -23,6 +23,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ .Chart.Name }}
         image: {{ include "camundaPlatform.image" . | quote }}
diff --git a/charts/camunda-platform/charts/tasklist/templates/deployment.yaml b/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
index 6f53df22..e42d9481 100644
--- a/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
@@ -23,6 +23,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ .Chart.Name }}
         image: {{ include "camundaPlatform.image" . | quote }}
diff --git a/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml b/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml
index a9c79569..eb1fb20d 100644
--- a/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml
+++ b/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml
@@ -25,12 +25,8 @@ spec:
       {{- end }}
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
-      {{- if .Values.extraInitContainers }}
       initContainers:
-        {{- with .Values.extraInitContainers }}
-          {{- tpl (toYaml . ) $ | nindent 8 }}
-        {{- end }}
-      {{- end }}
+        {{- tpl ((coalesce .Values.initContainers .Values.extraInitContainers) | default list | toYaml | nindent 8) $ }}
       containers:
         - name: {{ .Chart.Name }}
           image: {{ include "camundaPlatform.image" . | quote }}
@@ -81,6 +77,12 @@ spec:
             - name: ZEEBE_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_AUDIENCE
               value: "zeebe-api"
             {{- end }}
+            {{- if .Values.global.multitenancy.enabled }}
+            - name: ZEEBE_GATEWAY_MULTITENANCY_ENABLED
+              value: "true"
+            - name: ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED
+              value: "true"
+            {{- end }}
             {{- with .Values.env }}
               {{- tpl (toYaml .) $ | nindent 12 }}
             {{- end }}
diff --git a/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml b/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
index ad757f80..366d8ac8 100644
--- a/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
+++ b/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
@@ -34,9 +34,7 @@ spec:
       imagePullSecrets:
         {{- include "camundaPlatform.imagePullSecrets" . | nindent 8 }}
       initContainers:
-        {{- with .Values.extraInitContainers }}
-        {{- tpl (toYaml . ) $ | nindent 8  }}
-        {{- end }}
+        {{- tpl ((coalesce .Values.initContainers .Values.extraInitContainers) | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ .Chart.Name }}
         image: {{ include "camundaPlatform.image" . | quote }}
diff --git a/charts/camunda-platform/templates/connectors/deployment.yaml b/charts/camunda-platform/templates/connectors/deployment.yaml
index c60640c3..c178eb9d 100644
--- a/charts/camunda-platform/templates/connectors/deployment.yaml
+++ b/charts/camunda-platform/templates/connectors/deployment.yaml
@@ -21,6 +21,8 @@ spec:
       {{- end }}
     spec:
       imagePullSecrets: {{- include "connectors.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.connectors.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
         - name: connectors
           image: {{ include "camundaPlatform.imageByParams" (dict "base" .Values.global "overlay" .Values.connectors) }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
index 4b8ebfad..99a8d15a 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
@@ -22,6 +22,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "webModeler.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.webModeler.restapi.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ include "webModeler.name" . }}-restapi
         image: {{ include "webModeler.restapi.image" . | quote }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml b/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
index 82811a64..f291fbe9 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
@@ -22,6 +22,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "webModeler.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.webModeler.webapp.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ include "webModeler.name" . }}-webapp
         image: {{ include "webModeler.webapp.image" . | quote }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
index b9a7d371..ec80ac13 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
@@ -22,6 +22,8 @@ spec:
     spec:
       imagePullSecrets:
         {{- include "webModeler.imagePullSecrets" . | nindent 8 }}
+      initContainers:
+        {{- tpl (.Values.webModeler.websockets.initContainers | default list | toYaml | nindent 8) $ }}
       containers:
       - name: {{ include "webModeler.name" . }}-websockets
         image: {{ include "webModeler.websockets.image" . | quote }}
diff --git a/charts/camunda-platform/values.yaml b/charts/camunda-platform/values.yaml
index df9d5b86..2b0e4587 100644
--- a/charts/camunda-platform/values.yaml
+++ b/charts/camunda-platform/values.yaml
@@ -41,6 +41,11 @@ global:
   labels:
     app: camunda-platform
 
+  # Multitenancy configuration which is shared between the sub charts
+  multitenancy:
+    # multitenancy.enabled if true, then enable multitenancy in all applicable component.
+    enabled: false
+
   # Image configuration to be used in each sub chart
   # https://hub.docker.com/u/camunda
   image:
@@ -310,8 +315,10 @@ zeebe:
   extraVolumes: []
   # ExtraVolumeMounts can be used to mount extra volumes for the broker pods, useful for additional exporters
   extraVolumeMounts: []
-  # ExtraInitContainers can be used to set up extra init containers for the broker pods, useful for additional exporters
+  # (Deprecated - use `initContainers` instead) ExtraInitContainers can be used to set up extra init containers for the broker pods, useful for additional exporters
   extraInitContainers: []
+ # initContainers can be used to set up extra init containers for the broker pods, useful for additional exporters
+  initContainers: []
 
   # PodAnnotations can be used to define extra broker pod annotations
   podAnnotations: {}
@@ -572,8 +579,10 @@ zeebe-gateway:
   extraVolumeMounts: []
   # ExtraVolumes can be used to define extra volumes for the gateway pods, useful for enabling tls between gateway and broker
   extraVolumes: []
-  # ExtraInitContainers can be used to set up extra init containers for the gateway pods, useful for adding interceptors
+  # (Deprecated - use `initContainers` instead) ExtraInitContainers can be used to set up extra init containers for the gateway pods, useful for adding interceptors
   extraInitContainers: []
+  # initContainers can be used to set up extra init containers for the gateway pods, useful for adding interceptors
+  initContainers: []
 
   # Service configuration for the gateway service
   service:
@@ -659,7 +668,8 @@ operate:
 
   # Sidecars can be used to attach extra containers to the operate deployment
   sidecars: []
-
+  # initContainers can be used to set up extra init containers for the operate pods, useful for additional exporters
+  initContainers: []
   # ContextPath can be used to make Operate web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain.
   # contextPath: "/operate"
 
@@ -839,7 +849,8 @@ tasklist:
 
   # Sidecars can be used to attach extra containers to the tasklist deployment
   sidecars: []
-
+  # initContainers can be used to set up extra init containers for the taskList pods, useful for additional exporters
+  initContainers: []
   # ContextPath can be used to make Tasklist web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain.
   # contextPath: "/tasklist"
 
@@ -1036,7 +1047,8 @@ optimize:
   extraVolumes: []
   # ExtraVolumeMounts can be used to mount extra volumes for the Optimize pods, useful for tls and self-signed certificates
   extraVolumeMounts: []
-
+  # initContainers can be used to set up extra init containers for the optimize pods, useful for additional exporters
+  initContainers: []
   # ServiceAccount configuration for the service account where the Optimize pods are assigned to
   serviceAccount:
     # ServiceAccount.enabled if true, enables the Optimize service account
@@ -1220,7 +1232,8 @@ identity:
 
   # Sidecars can be used to attach extra containers to the identity deployment
   sidecars: []
-
+  # initContainers can be used to set up extra init containers for the identity pods, useful for additional exporters
+  initContainers: []
   # FullURL can be used when Ingress is configured (for both multi and single domain setup).
   # Note: If the `ContextPath` is configured, then value of `ContextPath` should be included in the URL too.
   # fullURL: "https://camunda.example.com/identity"
@@ -1519,6 +1532,8 @@ webModeler:
 
     # Restapi.sidecars can be used to attach extra containers to the restapi deployment
     sidecars: []
+    # Restapi.initContainers can be used to set up extra init containers to the restapi deployment
+    initContainers: []
 
     # Restapi.externalDatabase can be used to configure a connection to an external database. This will only be applied
     # if the postgresql dependency chart is disabled (by setting postgresql.enabled to false).
@@ -1673,6 +1688,8 @@ webModeler:
 
     # Webapp.sidecars can be used to attach extra containers to the modeler webapp deployment
     sidecars: []
+    # Webapp.initContainers can be used to set up extra init containers to the modeler webapp deployment
+    initContainers: []
 
     # Webapp.podAnnotations can be used to define extra webapp pod annotations
     podAnnotations: {}
@@ -1794,6 +1811,8 @@ webModeler:
 
     # Websockets.sidecars can be used to attach extra containers to the modeler websockets deployment
     sidecars: []
+    # Websockets.initContainers can be used to set up extra init containers to the modeler websockets deployment
+    initContainers: []
 
     # Websockets.publicHost can be used to define the host on which the WebSockets server can be reached from the Web Modeler client in the browser.
     # The default value assumes that a port-forwarding to the websockets service has been created.
@@ -1999,6 +2018,8 @@ connectors:
 
   # Sidecars can be used to attach extra containers to the connectors deployment
   sidecars: []
+  # initContainers can be used to set up extra init containers to the connectors deployment
+  initContainers: []
 
   # Number of Connectors replicas
   replicas: 1


Test patch:
diff --git a/charts/camunda-platform/test/unit/connectors/deployment_test.go b/charts/camunda-platform/test/unit/connectors/deployment_test.go
index ff9d90de..66852b9c 100644
--- a/charts/camunda-platform/test/unit/connectors/deployment_test.go
+++ b/charts/camunda-platform/test/unit/connectors/deployment_test.go
@@ -826,3 +826,33 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+func (s *deploymentTemplateTest) TestContainerSetInitContainer() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"connectors.initContainers[0].name":                   "nginx",
+			"connectors.initContainers[0].image":                  "nginx:latest",
+			"connectors.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/connectors/golden/deployment.golden.yaml b/charts/camunda-platform/test/unit/connectors/golden/deployment.golden.yaml
index e5b5b10a..ac29eb23 100644
--- a/charts/camunda-platform/test/unit/connectors/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/connectors/golden/deployment.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
         - name: connectors
           image: camunda/connectors-bundle:0.23.0
diff --git a/charts/camunda-platform/test/unit/identity/deployment_test.go b/charts/camunda-platform/test/unit/identity/deployment_test.go
index 43771c99..dcc82f5f 100644
--- a/charts/camunda-platform/test/unit/identity/deployment_test.go
+++ b/charts/camunda-platform/test/unit/identity/deployment_test.go
@@ -1004,6 +1004,37 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 	s.Require().Contains(podContainers, expectedContainer)
 }
 
+func (s *deploymentTemplateTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"identity.initContainers[0].name":                   "nginx",
+			"identity.initContainers[0].image":                  "nginx:latest",
+			"identity.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
+
 func (s *deploymentTemplateTest) TestContainerShouldSetFirstUserExistingSecretValue() {
 	// given
 	options := &helm.Options{
diff --git a/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml b/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml
index 94340a07..f26a7bdf 100644
--- a/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: identity
         image: "camunda/identity:8.2.13"
diff --git a/charts/camunda-platform/test/unit/operate/deployment_test.go b/charts/camunda-platform/test/unit/operate/deployment_test.go
index fce254e7..600b3af9 100644
--- a/charts/camunda-platform/test/unit/operate/deployment_test.go
+++ b/charts/camunda-platform/test/unit/operate/deployment_test.go
@@ -814,3 +814,34 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *deploymentTemplateTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"operate.initContainers[0].name":                   "nginx",
+			"operate.initContainers[0].image":                  "nginx:latest",
+			"operate.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/operate/golden/deployment.golden.yaml b/charts/camunda-platform/test/unit/operate/golden/deployment.golden.yaml
index 62062702..2674859d 100644
--- a/charts/camunda-platform/test/unit/operate/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/operate/golden/deployment.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: operate
         image: "camunda/operate:8.2.13"
diff --git a/charts/camunda-platform/test/unit/optimize/deployment_test.go b/charts/camunda-platform/test/unit/optimize/deployment_test.go
index 8286e12a..a26520e2 100644
--- a/charts/camunda-platform/test/unit/optimize/deployment_test.go
+++ b/charts/camunda-platform/test/unit/optimize/deployment_test.go
@@ -788,3 +788,34 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *deploymentTemplateTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"optimize.initContainers[0].name":                   "nginx",
+			"optimize.initContainers[0].image":                  "nginx:latest",
+			"optimize.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/optimize/golden/deployment.golden.yaml b/charts/camunda-platform/test/unit/optimize/golden/deployment.golden.yaml
index 2830adf6..55c716c6 100644
--- a/charts/camunda-platform/test/unit/optimize/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/optimize/golden/deployment.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: optimize
         image: "camunda/optimize:3.10.5"
diff --git a/charts/camunda-platform/test/unit/tasklist/deployment_test.go b/charts/camunda-platform/test/unit/tasklist/deployment_test.go
index fe1fb395..0a75c136 100644
--- a/charts/camunda-platform/test/unit/tasklist/deployment_test.go
+++ b/charts/camunda-platform/test/unit/tasklist/deployment_test.go
@@ -834,3 +834,34 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *deploymentTemplateTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"tasklist.initContainers[0].name":                   "nginx",
+			"tasklist.initContainers[0].image":                  "nginx:latest",
+			"tasklist.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/tasklist/golden/deployment.golden.yaml b/charts/camunda-platform/test/unit/tasklist/golden/deployment.golden.yaml
index 7b37753b..35107a2d 100644
--- a/charts/camunda-platform/test/unit/tasklist/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/tasklist/golden/deployment.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: tasklist
         image: "camunda/tasklist:8.2.13"
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
index 01aa9a0f..2d8f52f6 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
@@ -355,3 +355,36 @@ func (s *restapiDeploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *restapiDeploymentTemplateTest) TestContainerSetInitContainer() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                          "true",
+			"webModeler.restapi.mail.fromAddress":                         "example@example.com",
+			"webModeler.restapi.initContainers[0].name":                   "nginx",
+			"webModeler.restapi.initContainers[0].image":                  "nginx:latest",
+			"webModeler.restapi.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
index 263b7b2b..a884afcc 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
@@ -456,3 +456,36 @@ func (s *webappDeploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *webappDeploymentTemplateTest) TestContainerSetInitContainer() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                         "true",
+			"webModeler.restapi.mail.fromAddress":                        "example@example.com",
+			"webModeler.webapp.initContainers[0].name":                   "nginx",
+			"webModeler.webapp.initContainers[0].image":                  "nginx:latest",
+			"webModeler.webapp.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_websockets_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_websockets_test.go
index d61f239b..cc7756b3 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_websockets_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_websockets_test.go
@@ -174,3 +174,36 @@ func (s *websocketsDeploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *websocketsDeploymentTemplateTest) TestContainerSetInitContainer() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                             "true",
+			"webModeler.restapi.mail.fromAddress":                            "example@example.com",
+			"webModeler.websockets.initContainers[0].name":                   "nginx",
+			"webModeler.websockets.initContainers[0].image":                  "nginx:latest",
+			"webModeler.websockets.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-restapi.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-restapi.golden.yaml
index e1e88324..d9aa2ac9 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-restapi.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-restapi.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: web-modeler-restapi
         image: "registry.camunda.cloud/web-modeler-ee/modeler-restapi:8.2.6"
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-webapp.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-webapp.golden.yaml
index d4259e60..f0661f57 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-webapp.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-webapp.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: web-modeler-webapp
         image: "registry.camunda.cloud/web-modeler-ee/modeler-webapp:8.2.6"
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-websockets.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-websockets.golden.yaml
index d26fe38d..03b915c1 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/deployment-websockets.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/deployment-websockets.golden.yaml
@@ -37,6 +37,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
       - name: web-modeler-websockets
         image: "registry.camunda.cloud/web-modeler-ee/modeler-websockets:8.2.6"
diff --git a/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go b/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go
index 8ab0c315..d2bed2d5 100644
--- a/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go
+++ b/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go
@@ -601,6 +601,37 @@ func (s *deploymentTemplateTest) TestContainerSetExtraInitContainers() {
 	s.Require().Equal([]string{"sh", "-c", "top"}, initContainer.Command)
 }
 
+func (s *deploymentTemplateTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"zeebe-gateway.initContainers[0].name":                   "nginx",
+			"zeebe-gateway.initContainers[0].image":                  "nginx:latest",
+			"zeebe-gateway.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	podContainers := deployment.Spec.Template.Spec.InitContainers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
+
 func (s *deploymentTemplateTest) TestContainerShouldOverwriteGlobalImagePullPolicy() {
 	// given
 	options := &helm.Options{
@@ -748,3 +779,23 @@ func (s *deploymentTemplateTest) TestContainerSetSidecar() {
 
 	s.Require().Contains(podContainers, expectedContainer)
 }
+
+func (s *deploymentTemplateTest) TestZeebeMultiTenancyEnabled() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"global.multitenancy.enabled": "true",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var statefulSet appsv1.StatefulSet
+	helm.UnmarshalK8SYaml(s.T(), output, &statefulSet)
+
+	// then
+	env := statefulSet.Spec.Template.Spec.Containers[0].Env
+	s.Require().Contains(env, corev1.EnvVar{Name: "ZEEBE_GATEWAY_MULTITENANCY_ENABLED", Value: "true"})
+	s.Require().Contains(env, corev1.EnvVar{Name: "ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED", Value: "true"})
+}
diff --git a/charts/camunda-platform/test/unit/zeebe-gateway/golden/gateway-deployment.golden.yaml b/charts/camunda-platform/test/unit/zeebe-gateway/golden/gateway-deployment.golden.yaml
index 4a8a66af..f8ff147a 100644
--- a/charts/camunda-platform/test/unit/zeebe-gateway/golden/gateway-deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/zeebe-gateway/golden/gateway-deployment.golden.yaml
@@ -39,6 +39,8 @@ spec:
     spec:
       imagePullSecrets:
         []
+      initContainers:
+        []
       containers:
         - name: zeebe-gateway
           image: "camunda/zeebe:8.2.13"
diff --git a/charts/camunda-platform/test/unit/zeebe/golden/statefulset.golden.yaml b/charts/camunda-platform/test/unit/zeebe/golden/statefulset.golden.yaml
index 3d06b2ac..c489e35a 100644
--- a/charts/camunda-platform/test/unit/zeebe/golden/statefulset.golden.yaml
+++ b/charts/camunda-platform/test/unit/zeebe/golden/statefulset.golden.yaml
@@ -42,6 +42,7 @@ spec:
       imagePullSecrets:
         []
       initContainers:
+        []
       containers:
       - name: zeebe
         image: "camunda/zeebe:8.2.13"
diff --git a/charts/camunda-platform/test/unit/zeebe/statefulset_test.go b/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
index 378afae9..1761542a 100644
--- a/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
+++ b/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
@@ -211,6 +211,29 @@ func (s *statefulSetTest) TestContainerSetExtraInitContainers() {
 	s.Require().Equal("/exporters/", initContainer.VolumeMounts[0].MountPath)
 }
 
+func (s *statefulSetTest) TestInitContainers() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"zeebe.initContainers[0].name":                   "nginx",
+			"zeebe.initContainers[0].image":                  "nginx:latest",
+			"zeebe.initContainers[0].ports[0].containerPort": "80",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var statefulSet appsv1.StatefulSet
+	helm.UnmarshalK8SYaml(s.T(), output, &statefulSet)
+
+	// then
+	initContainer := statefulSet.Spec.Template.Spec.InitContainers[0]
+	s.Require().Equal("nginx", initContainer.Name)
+	s.Require().Equal("nginx:latest", initContainer.Image)
+
+}
+
 func (s *statefulSetTest) TestContainerOverwriteImageTag() {
 	// given
 	options := &helm.Options{