Repository: camunda/camunda-platform-helm
Pull request #729 (2023-06-01 14:48:45)

feat: add podLabels to Identity
### Which problem does the PR fix?

Fixes: #727

### What's in this PR?

Enables podLabels in Identity as already done for Operate or Tasklist

### 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).
- [x] The main Helm chart and sub-chart are updated (if needed).
- [x] In-repo [documentation](../blob/main/CONTRIBUTING.md#documentation) are updated (if needed).

**After opening the PR:**

- [x] Did you sign our CLA (Contributor License Agreement)? It will show once you open the PR.
- [x] Did all checks/tests pass in the PR?



CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/camunda/camunda-platform-helm?pullRequest=729) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/camunda/camunda-platform-helm?pullRequest=729) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/camunda/camunda-platform-helm?pullRequest=729) it.</sub>

Patch:
diff --git a/.github/actions/failed-pods-info/action.yml b/.github/actions/failed-pods-info/action.yml
new file mode 100644
index 00000000..bf58317e
--- /dev/null
+++ b/.github/actions/failed-pods-info/action.yml
@@ -0,0 +1,16 @@
+name: Get failed Pods info
+description: In case of failure, get Pods details like name, logs, and description
+
+runs:
+  using: composite
+  steps:
+  - name: Get failed Pods info
+    shell: bash
+    # TODO: Better way to collect logs and store them as artifacts in GitHub Actions.
+    run: |
+      kubectl -n $TEST_NAMESPACE get po
+      kubectl -n $TEST_NAMESPACE get po | grep -v "Completed" | awk '/0\//{print $1}' | while read pod_name; do
+        echo -e "\n###Failed Pod: ${pod_name}###\n";
+        kubectl -n $TEST_NAMESPACE describe po ${pod_name};
+        kubectl -n $TEST_NAMESPACE logs ${pod_name};
+      done
diff --git a/.github/actions/pr-vars/action.yml b/.github/actions/pr-vars/action.yml
new file mode 100644
index 00000000..6c0e6bc2
--- /dev/null
+++ b/.github/actions/pr-vars/action.yml
@@ -0,0 +1,21 @@
+name: PR vars
+description: Set common vars for PRs 
+
+runs:
+  using: composite
+  steps:
+  - name: Set PR vars
+    shell: bash
+    run: |
+      sudo apt -qq install -y pwgen
+      GITHUB_PR_HEAD_SHA_SHORT=$(echo ${{ github.event.pull_request.head.sha }} | cut -c 1-7)
+      # NOTE: We should use the matrix job id var once it's available.
+      # https://github.com/orgs/community/discussions/40291
+      GITHUB_WORKFLOW_JOB_ID=$(pwgen 6 1 -A)
+      echo "GITHUB_PR_HEAD_SHA_SHORT=$GITHUB_PR_HEAD_SHA_SHORT" >> $GITHUB_ENV
+      echo "GITHUB_WORKFLOW_JOB_ID=$GITHUB_WORKFLOW_JOB_ID" >> $GITHUB_ENV
+      echo "GITHUB_WORKFLOW_RUN_ID=${{ github.run_id }}" >> $GITHUB_ENV
+      # Set full name for the namespace.
+      TEST_NAMESPACE_PART1="camunda-platform-pr-${{ github.event.pull_request.number }}"
+      TEST_NAMESPACE_PART2="sha-$GITHUB_PR_HEAD_SHA_SHORT-run-${{ github.run_id }}-sfx-$GITHUB_WORKFLOW_JOB_ID"
+      echo "TEST_NAMESPACE=$TEST_NAMESPACE_PART1-$TEST_NAMESPACE_PART2" >> $GITHUB_ENV
diff --git a/charts/camunda-platform/README.md b/charts/camunda-platform/README.md
index e4bca3cc..b91535ce 100644
--- a/charts/camunda-platform/README.md
+++ b/charts/camunda-platform/README.md
@@ -278,10 +278,11 @@ For more information about Zeebe, visit [Zeebe Overview](https://docs.camunda.io
 | | `image.repository` | Defines which image repository to use. | `camunda/zeebe` |
 | | `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 | `[]` |
 | | `clusterSize` | Defines the amount of brokers (=replicas), which are deployed via helm | `3` |
 | | `partitionCount` | Defines how many Zeebe partitions are set up in the cluster | `3` |
 | | `replicationFactor` | Defines how each partition is replicated, the value defines the number of nodes | `3` |
-| | `env` | Can be used to set extra environment variables in each Zeebe broker container | `- name: ZEEBE_BROKER_DATA_SNAPSHOTPERIOD` </br>`  value: "5m"`</br>`- name: ZEEBE_BROKER_EXECUTION_METRICS_EXPORTER_ENABLED`</br>`  value: "true"`</br>`- name: ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK`</br>`  value: "0.85"`</br>`- name: ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK`</br>`  value: "0.87"` |
+| | `env` | Can be used to set extra environment variables in each Zeebe broker container | `- name: ZEEBE_BROKER_DATA_SNAPSHOTPERIOD` </br>`  value: "5m"`</br>`- name: ZEEBE_BROKER_EXECUTION_METRICS_EXPORTER_ENABLED`</br>`  value: "true"`</br>`- name: ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK`</br>`  value: "0.85"`</br>`- name: ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK`</br>`  value: "0.87"`. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. |
 | | `configMap.defaultMode` | Can be used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. See [Api docs](https://github.com/kubernetes/api/blob/master/core/v1/types.go#L1615-L1623) for more details. It is useful to configure it if you want to run the helm charts in OpenShift. | [`0754`](https://chmodcommand.com/chmod-0754/) |
 | | `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/) | `[]` | 
 | | `logLevel` | Defines the log level which is used by the Zeebe brokers; must be one of: ERROR, WARN, INFO, DEBUG, TRACE | `info` |
@@ -359,12 +360,13 @@ For more information about Zeebe Gateway, visit
 | | `image.repository` | Defines which image repository to use. | `camunda/zeebe` |
 | | `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 | `[]` |
 | | `podAnnotations` | Can be used to define extra gateway pod annotations | `{ }` |
 | | `podLabels` | Can be used to define extra gateway pod labels | `{ }` |
 | | `logLevel` | Defines the log level which is used by the gateway | `info` |
 | | `log4j2` | Can be used to overwrite the log4j2 configuration of the gateway | `""` |
 | | `javaOpts` | Can be used to set the Zeebe Gateway javaOpts. This is where you should configure the jvm heap size. | `-XX:+ExitOnOutOfMemoryError` |
-| | `env` | Can be used to set extra environment variables in each gateway container | `[ ]` |
+| | `env` | Can be used to set extra environment variables in each gateway container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[ ]` |
 | | `configMap.defaultMode` | Can be used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. See [Api docs](https://github.com/kubernetes/api/blob/master/core/v1/types.go#L1615-L1623) for more details. It is useful to configure it if you want to run the helm charts in OpenShift. | [`0744`](https://chmodcommand.com/chmod-744/) |
 | | `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/) | `[]` |
 | | `podDisruptionBudget` | Configuration to configure a [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for the broker pods. | |
@@ -444,6 +446,7 @@ For more information about Operate, visit
 | | `image.repository` | Defines which image repository to use. | `camunda/operate` |
 | | `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 | `[]` |
 | | `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 | `{ }` |
@@ -453,7 +456,7 @@ For more information about Operate, visit
 | | `service.port` | Defines the port of the service, where the Operate web application will be available | `80` |
 | | `service.annotations` | Defines annotations for the Operate service | `{ }` | 
 | | `resources` | Configuration to set [request and limit configuration for the container](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) | `requests:`<br>`  cpu: 600m`<br> `  memory: 400Mi`<br>`limits:`<br> ` cpu: 2000m`<br> ` memory: 2Gi` |
-| | `env` | Can be used to set extra environment variables in each Operate container | `[ ]` |
+| | `env` | Can be used to set extra environment variables in each Operate container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[ ]` |
 | | `configMap.defaultMode` | Can be used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. See [Api docs](https://github.com/kubernetes/api/blob/master/core/v1/types.go#L1615-L1623) for more details. It is useful to configure it if you want to run the helm charts in OpenShift. | [`0744`](https://chmodcommand.com/chmod-744/) |
 | | `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/) | `[]` |
 | | `extraVolumes` | Can be used to define extra volumes for the Operate pods, useful for TLS and self-signed certificates | `[ ]` |
@@ -515,6 +518,7 @@ For more information about Tasklist, visit
 | | `image.repository` | Defines which image repository to use. | `camunda/tasklist` |
 | | `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 | `[]` |
 | | `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 | `{ }` |
@@ -563,7 +567,7 @@ For more information about Tasklist, visit
 | | `ingress.annotations` | Defines the ingress related annotations, consumed mostly by the ingress controller | `ingress.kubernetes.io/rewrite-target: "/"` <br/> `nginx.ingress.kubernetes.io/ssl-redirect: "false"` |
 | | `ingress.path` | Defines the path which is associated with the Tasklist [service and port](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules) | `/` |
 | | `ingress.host` | Can be used to define the [host of the ingress rule.](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules) If not specified the rules applies to all inbound HTTP traffic, if specified the rule applies to that host. | `""` |
-| | `env` | Can be used to set extra environment variables on each Tasklist container | `[ ]` |
+| | `env` | Can be used to set extra environment variables on each Tasklist container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[ ]` |
 
 ### Optimize
 
@@ -578,11 +582,12 @@ For more information, visit [Optimize Introduction](https://docs.camunda.io/opti
 | | `image.repository` |  Defines which image repository to use | `camunda/optimize` |
 | | `image.tag` |  Can be set to overwrite the global tag, which should be used in that chart | `3.8.0` |
 | | `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 | `[]` |
 | | `contextPath` |  Can be used to make Optimize 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 Optimize pod annotations | `{ }` |
 | | `podLabels` |  Can be used to define extra Optimize pod labels | `{ }` |
 | | `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 | `[]` |
+| | `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/) | `[]` |
 | | `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 | `[]` |
@@ -644,19 +649,23 @@ For more information, visit [Identity Overview](https://docs.camunda.io/docs/sel
 | | `enabled` |  If true, the Identity deployment and its related resources are deployed via a helm release. <br/> Note: Identity is required by Optimize and Web Modeler. If Identity is disabled, both Optimize and Web Modeler will be unusable. If you need neither Optimize nor Web Modeler, make sure to disable both the Identity authentication and the applications by setting:<br/>`global.identity.auth.enabled: false`<br/>`optimize.enabled: false`<br/>`webModeler.enabled: false` | `true` |
 | | `fullnameOverride` | Can be used to override the full name of the Identity resources | |
 | | `nameOverride` | Can be used to partly override the name of the Identity resources (names will still be prefixed with the release name) | |
+| | `firstUser.enabled` | If true, Identity will seed the first user in Keycloak | `true` |
 | | `firstUser.username` | Defines the username of the first user, needed to log in into the web applications | `demo` |
 | | `firstUser.password` | Defines the password of the first user, needed to log in into the web applications | `demo` |
 | | `firstUser.email` | Defines the email address of the first user; a valid email address is required to use Web Modeler | `demo@example.org` |
 | | `firstUser.firstName` | Defines the first name of the first user; a name is required to use Web Modeler | `Demo` |
 | | `firstUser.lastName` | Defines the last name of the first user; a name is required to use Web Modeler | `User` |
+| | `firstUser.existingSecret` | Can be used to use an own existing secret for Identity first user. Currently, only password field is supported via "identity-firstuser-password" key in the secret resource | `""` |
 | | `image` |  Configuration to configure the Identity image specifics | |
 | | `image.registry` | Can be used to set container image registry. | `""` |
 | | `image.repository` |  Defines which image repository to use | `camunda/identity` |
 | | `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 | `[]` |
 | | `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 | `{ }` |
+| | `podLabels` |  Can be used to define extra Identity pod labels | `{ }` |
 | | `service` |  Configuration to configure the Identity service. | |
 | | `service.type` | Defines the [type of the service](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | `ClusterIP` |
 | | `service.annotations` |  Can be used to define annotations, which will be applied to the Identity service | `{}` |
@@ -667,7 +676,7 @@ For more information, visit [Identity Overview](https://docs.camunda.io/docs/sel
 | | `nodeSelector` |  Can be used to define on which nodes the Identity pods should run | `{ }` |
 | | `tolerations` |  Can be used to define [pod toleration's](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | `[ ] ` |
 | | `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) | `{ }` |
-| | `env` |  Can be used to set extra environment variables in each Identity container. See the [documentation](https://docs.camunda.io/docs/self-managed/identity/deployment/configuration-variables/) for more details. | `[]` |
+| | `env` |  Can be used to set extra environment variables in each Identity container. See the [documentation](https://docs.camunda.io/docs/self-managed/identity/deployment/configuration-variables/) for more details. 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. See [override the default command provided by the container image](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) | |
 | | `extraVolumes` |  Can be used to define extra volumes for the Identity pods, useful for tls and self-signed certificates | `[]` |
 | | `extraVolumeMounts` |  Can be used to mount extra volumes for the Identity pods, useful for tls and self-signed certificates | `[]` |
@@ -756,6 +765,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.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 | |
 | | `restapi.externalDatabase.port` | Defines the port number of the database instance | `5432` |
@@ -772,7 +782,7 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `restapi.mail.fromName` | Defines the name that will be displayed as the sender of emails sent by Web Modeler | Camunda Platform |
 | | `restapi.podAnnotations` | Can be used to define extra restapi pod annotations | `{}` |
 | | `restapi.podLabels` | Can be used to define extra restapi pod labels | `{}` |
-| | `restapi.env` | Can be used to set extra environment variables in each restapi container | `[]` |
+| | `restapi.env` | Can be used to set extra environment variables in each restapi container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[]` |
 | | `restapi.command` | Can be used to [override the default command](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) provided by the container image | `[]` |
 | | `restapi.extraVolumes` | Can be used to define extra volumes for the restapi pods, useful for TLS and self-signed certificates | `[]` |
 | | `restapi.extraVolumeMounts` | Can be used to mount extra volumes for the restapi pods, useful for TLS and self-signed certificates | `[]` |
@@ -814,9 +824,10 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `webapp` | Configuration of the Web Modeler webapp component | |
 | | `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.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 | `[]` |
+| | `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. | `[]` |
 | | `webapp.command` | Can be used to [override the default command](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) provided by the container image | `[]` |
 | | `webapp.extraVolumes` | Can be used to define extra volumes for the webapp pods, useful for TLS and self-signed certificates | `[]` |
 | | `webapp.extraVolumeMounts` | Can be used to mount extra volumes for the webapp pods, useful for TLS and self-signed certificates | `[]` |
@@ -857,11 +868,12 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `websockets` | Configuration of the Web Modeler websockets component | |
 | | `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.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 | `{}` |
 | | `websockets.podLabels` | Can be used to define extra websockets pod labels | `{}` |
-| | `websockets.env` | Can be used to set extra environment variables in each websockets container | `[]` |
+| | `websockets.env` | Can be used to set extra environment variables in each websockets container. Environment variables listed here may appear twice in `kubectl describe` but the variable listed in this option will have precedence. | `[]` |
 | | `websockets.command` | Can be used to [override the default command](ttps://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) provided by the container image | `[]` |
 | | `websockets.extraVolumes` | Can be used to define extra volumes for the websockets pod; useful for logging to a file | `[]` |
 | | `websockets.extraVolumeMounts` | Can be used to mount extra volumes for the websockets pod; useful for logging to a file | `[]` |
@@ -944,11 +956,12 @@ For more information, visit [Introduction to Connectors](https://docs.camunda.io
 |              | `image.repository`                   | Defines which image repository to use                                                                                                                                                                                                             | `camunda/connectors-bundle`                                                                           |
 |              | `image.tag`                          | Can be set to overwrite the global tag, which should be used in that chart                                                                                                                                                                        | `0.18.2`                                                                                              |
 |              | `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                                                                                                                                                                                             | `[]`                                                                                                  |
 |              | `replicas`                           | Number of replicas                                                                                                                                                                                                                                | `1`                                                                                                   |
 |              | `podAnnotations`                     | Can be used to define extra Connectors pod annotations                                                                                                                                                                                            | `{ }`                                                                                                 |
 |              | `podLabels`                          | Can be used to define extra Connectors pod labels                                                                                                                                                                                                 | `{ }`                                                                                                 |
 |              | `logging.level`                      | Allows to fine tune logging output for Connectors                                                                                                                                                                                                 | `io.camunda.connector: ERROR`                                                                         |
-|              | `env`                                | Can be used to set extra environment variables in each Connectors container                                                                                                                                                                       | `[]`                                                                                                  |
+|              | `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                                                                                                                                           | `[]`                                                                                                  |
 |              | `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/)                                                                        | `[]`                                                                                                  |
@@ -1001,6 +1014,13 @@ For more information, visit [Introduction to Connectors](https://docs.camunda.io
 |              | `livenessProbe.failureThreshold`     | Defines when the probe is considered as failed so the container will be restarted                                                                                                                                                                 | `5`                                                                                                   |
 |              | `livenessProbe.timeoutSeconds`       | Defines the seconds after the probe times out                                                                                                                                                                                                     | `1`                                                                                                   |
 
+#### Updating Environment Variables
+When configuring the `env` options in the settings listed above, the environment variables you specify in values.yaml may show up twice when running `kubectl describe deployment <deployment>`. However, the environment variable specified in values.yaml will have precedence when the pod actually runs. To verify this, you can check the output from the following command:
+
+```bash
+kubectl exec pod/<podName> -- env
+```
+
 #### Outbound Connectors
 
 To learn more about outbound connectors, visit [related documentation article](https://docs.camunda.io/docs/components/connectors/use-connectors/#outbound-connector).
diff --git a/charts/camunda-platform/charts/identity/templates/deployment.yaml b/charts/camunda-platform/charts/identity/templates/deployment.yaml
index 2543bb29..a55ad402 100644
--- a/charts/camunda-platform/charts/identity/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/identity/templates/deployment.yaml
@@ -10,7 +10,11 @@ spec:
     matchLabels: {{- include "identity.matchLabels" . | nindent 6 }}
   template:
     metadata:
-      labels: {{- include "identity.labels" . | nindent 8 }}
+      labels:
+        {{- include "identity.labels" . | nindent 8 }}
+        {{- if .Values.podLabels }}
+        {{- toYaml .Values.podLabels | nindent 8 }}
+        {{- end }}
       {{- if .Values.podAnnotations }}
       annotations:
         {{- toYaml  .Values.podAnnotations | nindent 8 }}
@@ -34,21 +38,7 @@ spec:
           - name: IDENTITY_BASE_PATH
             value: {{ .Values.contextPath | quote }}
           {{- end }}
-          - name: KEYCLOAK_USERS_0_USERNAME
-            value: {{ .Values.firstUser.username | quote }}
-          - name: KEYCLOAK_USERS_0_PASSWORD
-            value: {{ .Values.firstUser.password | quote }}
-          - name: KEYCLOAK_USERS_0_EMAIL
-            value: {{ .Values.firstUser.email | quote }}
-          - name: KEYCLOAK_USERS_0_FIRST_NAME
-            value: {{ .Values.firstUser.firstName | quote }}
-          - name: KEYCLOAK_USERS_0_LAST_NAME
-            value: {{ .Values.firstUser.lastName | quote }}
-          - name: KEYCLOAK_USERS_0_ROLES_0
-            value: "Identity"
           {{- if .Values.global.identity.auth.enabled }}
-          - name: KEYCLOAK_USERS_0_ROLES_1
-            value: "Operate"
           - name: KEYCLOAK_INIT_OPERATE_SECRET
             {{- if and .Values.global.identity.auth.operate.existingSecret (not (typeIs "string" .Values.global.identity.auth.operate.existingSecret)) }}
             valueFrom:
@@ -68,8 +58,6 @@ spec:
             {{- end }}
           - name: KEYCLOAK_INIT_OPERATE_ROOT_URL
             value: {{ tpl .Values.global.identity.auth.operate.redirectUrl $ | quote }}
-          - name: KEYCLOAK_USERS_0_ROLES_2
-            value: "Tasklist"
           - name: KEYCLOAK_INIT_TASKLIST_SECRET
             {{- if and .Values.global.identity.auth.tasklist.existingSecret (not (typeIs "string" .Values.global.identity.auth.tasklist.existingSecret)) }}
             valueFrom:
@@ -89,8 +77,6 @@ spec:
             {{- end }}
           - name: KEYCLOAK_INIT_TASKLIST_ROOT_URL
             value: {{ tpl .Values.global.identity.auth.tasklist.redirectUrl $ | quote }}
-          - name: KEYCLOAK_USERS_0_ROLES_3
-            value: "Optimize"
           - name: KEYCLOAK_INIT_OPTIMIZE_SECRET
             {{- if and .Values.global.identity.auth.optimize.existingSecret (not (typeIs "string" .Values.global.identity.auth.optimize.existingSecret)) }}
             valueFrom:
@@ -110,8 +96,6 @@ spec:
             {{- end }}
           - name: KEYCLOAK_INIT_OPTIMIZE_ROOT_URL
             value: {{ tpl .Values.global.identity.auth.optimize.redirectUrl $ | quote }}
-          - name: KEYCLOAK_USERS_0_ROLES_4
-            value: "Web Modeler"
           - name: KEYCLOAK_INIT_WEBMODELER_ROOT_URL
             value: {{ tpl .Values.global.identity.auth.webModeler.redirectUrl $ | quote }}
           - name: KEYCLOAK_INIT_ZEEBE_NAME
@@ -190,6 +174,38 @@ spec:
               secretKeyRef:
                 name: {{ include "identity.keycloak.authExistingSecret" . }}
                 key: {{ include "identity.keycloak.authExistingSecretKey" . }}
+        {{- if .Values.firstUser.enabled }}
+          - name: KEYCLOAK_USERS_0_USERNAME
+            value: {{ .Values.firstUser.username | quote }}
+        {{- if .Values.firstUser.existingSecret }}
+          - name: KEYCLOAK_USERS_0_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: {{ .Values.firstUser.existingSecret }}
+                key: "identity-firstuser-password"
+        {{- else }}
+          - name: KEYCLOAK_USERS_0_PASSWORD
+            value: {{ .Values.firstUser.password | quote }}
+        {{- end }}
+          - name: KEYCLOAK_USERS_0_EMAIL
+            value: {{ .Values.firstUser.email | quote }}
+          - name: KEYCLOAK_USERS_0_FIRST_NAME
+            value: {{ .Values.firstUser.firstName | quote }}
+          - name: KEYCLOAK_USERS_0_LAST_NAME
+            value: {{ .Values.firstUser.lastName | quote }}
+          - name: KEYCLOAK_USERS_0_ROLES_0
+            value: "Identity"
+        {{- if .Values.global.identity.auth.enabled }}
+          - name: KEYCLOAK_USERS_0_ROLES_1
+            value: "Operate"
+          - name: KEYCLOAK_USERS_0_ROLES_2
+            value: "Tasklist"
+          - name: KEYCLOAK_USERS_0_ROLES_3
+            value: "Optimize"
+          - name: KEYCLOAK_USERS_0_ROLES_4
+            value: "Web Modeler"
+        {{- end }}
+        {{- end }}
         {{- with .Values.env }}
             {{- tpl (toYaml .) $ | nindent 10 }}
         {{- end }}
@@ -248,6 +264,10 @@ spec:
         volumeMounts:
         {{- .Values.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 6 }}
+      {{- end }}
+
       {{- if .Values.extraVolumes}}
       volumes:
       {{- .Values.extraVolumes | toYaml | nindent 6 }}
diff --git a/charts/camunda-platform/charts/operate/templates/deployment.yaml b/charts/camunda-platform/charts/operate/templates/deployment.yaml
index e5caadb9..2b513a53 100644
--- a/charts/camunda-platform/charts/operate/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/operate/templates/deployment.yaml
@@ -154,6 +154,9 @@ spec:
         {{- if .Values.extraVolumeMounts}}
         {{- .Values.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       volumes:
       - name: config
         configMap:
diff --git a/charts/camunda-platform/charts/optimize/templates/deployment.yaml b/charts/camunda-platform/charts/optimize/templates/deployment.yaml
index 3a84b182..18806950 100644
--- a/charts/camunda-platform/charts/optimize/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/optimize/templates/deployment.yaml
@@ -139,6 +139,9 @@ spec:
         {{- if .Values.extraVolumeMounts}}
           {{- .Values.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       volumes:
       {{- if .Values.extraVolumes}}
       {{- .Values.extraVolumes | toYaml | nindent 6 }}
diff --git a/charts/camunda-platform/charts/tasklist/templates/deployment.yaml b/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
index 937eeb4a..4bbc8260 100644
--- a/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
+++ b/charts/camunda-platform/charts/tasklist/templates/deployment.yaml
@@ -154,6 +154,9 @@ spec:
         {{- if .Values.extraVolumeMounts}}
         {{- .Values.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       volumes:
       - name: config
         configMap:
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 bc3bd872..a9c79569 100644
--- a/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml
+++ b/charts/camunda-platform/charts/zeebe-gateway/templates/gateway-deployment.yaml
@@ -139,6 +139,9 @@ spec:
           resources:
             {{- toYaml .Values.resources | nindent 12 }}
           {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 8 }}
+      {{- end }}
       volumes:
         - name: config
           configMap:
diff --git a/charts/camunda-platform/charts/zeebe-gateway/templates/ingress.yaml b/charts/camunda-platform/charts/zeebe-gateway/templates/ingress.yaml
index 704771e5..8ad40afa 100644
--- a/charts/camunda-platform/charts/zeebe-gateway/templates/ingress.yaml
+++ b/charts/camunda-platform/charts/zeebe-gateway/templates/ingress.yaml
@@ -11,7 +11,7 @@ spec:
   ingressClassName: {{ .Values.ingress.className }}
   rules:
     {{- if .Values.ingress.host }}
-    - host: {{ .Values.ingress.host }}
+    - host: {{ tpl .Values.ingress.host $ }}
       http:
     {{- else }}
     - http:
@@ -27,7 +27,7 @@ spec:
   {{- if .Values.ingress.tls.enabled }}
   tls:
     - hosts:
-        - {{ .Values.ingress.host }}
+        - {{ tpl .Values.ingress.host $ }}
       {{- if .Values.ingress.tls.secretName }}
       secretName: {{ .Values.ingress.tls.secretName }}
       {{- end }}
diff --git a/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml b/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
index 959f7adc..ad757f80 100644
--- a/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
+++ b/charts/camunda-platform/charts/zeebe/templates/statefulset.yaml
@@ -169,6 +169,9 @@ spec:
         {{- if .Values.extraVolumeMounts}}
         {{ .Values.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.sidecars }}
+      {{- .Values.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       volumes:
         {{- if eq .Values.persistenceType "memory" }}
         - name: data
diff --git a/charts/camunda-platform/templates/NOTES.txt b/charts/camunda-platform/templates/NOTES.txt
index 0f9ff67e..66250d01 100644
--- a/charts/camunda-platform/templates/NOTES.txt
+++ b/charts/camunda-platform/templates/NOTES.txt
@@ -94,27 +94,32 @@ In order to deploy the ingress manifest, set `<service>.ingress.enabled` to `tru
 If you don't have an ingress controller you can use `kubectl port-forward` to access the deployed web application from outside the cluster:
 
 {{ if .Values.identity.enabled -}}
-Identity: kubectl port-forward svc/{{ .Release.Name }}-identity 8080:80
+Identity:
+> kubectl port-forward svc/{{ .Release.Name }}-identity 8080:80
 {{- end }}
 {{ if .Values.operate.enabled -}}
-Operate:  kubectl port-forward svc/{{ .Release.Name }}-operate  8081:80
+Operate:
+> kubectl port-forward svc/{{ .Release.Name }}-operate  8081:80
 {{- end }}
 {{ if .Values.tasklist.enabled -}}
-Tasklist: kubectl port-forward svc/{{ .Release.Name }}-tasklist 8082:80
+Tasklist:
+> kubectl port-forward svc/{{ .Release.Name }}-tasklist 8082:80
 {{- end }}
 {{ if .Values.optimize.enabled -}}
-Optimize: kubectl port-forward svc/{{ .Release.Name }}-optimize 8083:80
-{{- end }}
-{{ if .Values.webModeler.enabled }}
-Web Modeler:
-kubectl port-forward svc/{{ include "webModeler.webapp.fullname" . }} 8084:80
-kubectl port-forward svc/{{ include "webModeler.websockets.fullname" . }} 8085:80
+Optimize:
+> kubectl port-forward svc/{{ .Release.Name }}-optimize 8083:80
 {{- end }}
 {{ if .Values.connectors.enabled -}}
-Connectors: kubectl port-forward svc/{{ .Release.Name }}-connectors 8088:8080
+Connectors:
+> kubectl port-forward svc/{{ .Release.Name }}-connectors 8088:8080
+{{- end }}
+{{ if .Values.webModeler.enabled -}}
+Web Modeler:
+> kubectl port-forward svc/{{ include "webModeler.webapp.fullname" . }} 8084:80
+> kubectl port-forward svc/{{ include "webModeler.websockets.fullname" . }} 8085:80
 {{- end }}
 
-    {{- if and .Values.global.identity.auth.enabled .Values.identity.enabled }}
+{{- if and .Values.global.identity.auth.enabled .Values.identity.enabled }}
 
 If you want to use different ports for the services, please adjust the related configs in the values file since these ports are used as redirect URLs for Keycloak.
 
@@ -124,10 +129,16 @@ as well, otherwise, a login will not be possible. Make sure you use `18080` as a
 {{ if .Values.identity.keycloak.enabled -}}
 > kubectl port-forward svc/{{ include "common.names.dependency.fullname" (dict "chartName" "keycloak" "chartValues" .Values.identity.keycloak "context" $) | trunc 20 | trimSuffix "-" }} 18080:80
 {{- end }}
-    {{- end }}
+{{- end }}
 
 Now you can point your browser to one of the service's login pages. Example: http://localhost:8081 for Operate.
-
-Default user and password: "demo/demo"
+{{ if .Values.identity.firstUser.enabled }}
+{{- if .Values.identity.firstUser.existingSecret }}
+Default user: "{{ .Values.identity.firstUser.username }}", and for password, run:
+> kubectl get secret {{ .Values.identity.firstUser.existingSecret }} -o jsonpath='{.data.identity-firstuser-password}' | base64 -d
+{{- else }}
+Default user and password: "{{ .Values.identity.firstUser.username -}}/{{ .Values.identity.firstUser.password }}"
+{{- end }}
+{{ end }}
 
 {{- end }}
diff --git a/charts/camunda-platform/templates/connectors/deployment.yaml b/charts/camunda-platform/templates/connectors/deployment.yaml
index 77b494db..163b16fb 100644
--- a/charts/camunda-platform/templates/connectors/deployment.yaml
+++ b/charts/camunda-platform/templates/connectors/deployment.yaml
@@ -149,6 +149,9 @@ spec:
           {{- if .Values.connectors.extraVolumeMounts }}
           volumeMounts: {{- .Values.connectors.extraVolumeMounts | toYaml | nindent 12 }}
           {{- end }}
+        {{- if .Values.connectors.sidecars }}
+        {{- .Values.connectors.sidecars | toYaml | nindent 8 }}
+        {{- end }}
       {{- if .Values.connectors.extraVolumes }}
       volumes:
         {{- .Values.connectors.extraVolumes | toYaml | nindent 8 }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
index 38e6b1cf..4b8ebfad 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
@@ -145,6 +145,9 @@ spec:
         volumeMounts:
         {{- .Values.webModeler.restapi.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.webModeler.restapi.sidecars }}
+      {{- .Values.webModeler.restapi.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       {{- if .Values.webModeler.restapi.extraVolumes }}
       volumes:
       {{- .Values.webModeler.restapi.extraVolumes | toYaml | nindent 6 }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml b/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
index 6d6c264b..82811a64 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-webapp.yaml
@@ -151,6 +151,9 @@ spec:
         volumeMounts:
         {{- .Values.webModeler.webapp.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.webModeler.webapp.sidecars }}
+      {{- .Values.webModeler.webapp.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       {{- if .Values.webModeler.webapp.extraVolumes }}
       volumes:
       {{- .Values.webModeler.webapp.extraVolumes | toYaml | nindent 6 }}
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
index 24717731..b9a7d371 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
@@ -99,6 +99,9 @@ spec:
         volumeMounts:
         {{- .Values.webModeler.websockets.extraVolumeMounts | toYaml | nindent 8 }}
         {{- end }}
+      {{- if .Values.webModeler.websockets.sidecars }}
+      {{- .Values.webModeler.websockets.sidecars | toYaml | nindent 6 }}
+      {{- end }}
       {{- if .Values.webModeler.websockets.extraVolumes }}
       volumes:
       {{- .Values.webModeler.websockets.extraVolumes | toYaml | nindent 6 }}
diff --git a/charts/camunda-platform/values.yaml b/charts/camunda-platform/values.yaml
index ee0fed14..4d52c154 100644
--- a/charts/camunda-platform/values.yaml
+++ b/charts/camunda-platform/values.yaml
@@ -191,6 +191,9 @@ zeebe:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the zeebe deployment
+  sidecars: []
+
   # ClusterSize defines the amount of brokers (=replicas), which are deployed via helm
   clusterSize: "3"
   # PartitionCount defines how many zeebe partitions are set up in the cluster
@@ -402,6 +405,10 @@ zeebe-gateway:
     tag:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
+
+  # Sidecars can be used to attach extra containers to the zeebe gateway deployment
+  sidecars: []
+
   # PodAnnotations can be used to define extra gateway pod annotations
   podAnnotations: {}
   # PodLabels can be used to define extra gateway pod labels
@@ -608,6 +615,9 @@ operate:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the operate deployment
+  sidecars: []
+
   # 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"
 
@@ -774,6 +784,9 @@ tasklist:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the tasklist deployment
+  sidecars: []
+
   # 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"
 
@@ -929,6 +942,9 @@ optimize:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the optimize deployment
+  sidecars: []
+
   # ContextPath can be used to make Optimize web application works on a custom sub-path. This is mainly used to run Camunda Platform web applications under a single domain.
   # contextPath: "/optimize"
 
@@ -1130,6 +1146,8 @@ identity:
   # FirstUser configuration to configure properties of the first Identity user, which can be used to access all
   # web applications
   firstUser:
+    # FirstUser.enabled if true, Identity will seed the first user in Keycloak.
+    enabled: true
     # FirstUser.username defines the username of the first user, needed to log in into the web applications
     username: demo
     # FirstUser.password defines the password of the first user, needed to log in into the web applications
@@ -1140,6 +1158,9 @@ identity:
     firstName: Demo
     # FirstUser.lastName defines the last name of the first user; a name is required to use Web Modeler
     lastName: User
+    # FirstUser.existingSecret can be used to use an own existing secret for Identity first user.
+    # Currently, only password field is supported via "identity-firstuser-password" key in the secret resource.
+    existingSecret: ""
 
   # Image configuration to configure the identity image specifics
   image:
@@ -1152,6 +1173,9 @@ identity:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the identity deployment
+  sidecars: []
+
   # 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"
@@ -1165,6 +1189,8 @@ identity:
 
   # PodAnnotations can be used to define extra Identity pod annotations
   podAnnotations: {}
+  # PodLabels can be used to define extra Identity pod labels
+  podLabels: {}
 
   # Service configuration to configure the identity service.
   service:
@@ -1406,7 +1432,7 @@ webModeler:
     registry: registry.camunda.cloud
     # Image.tag can be used to set the Docker image tag for the Web Modeler images (overwrites global.image.tag)
     # renovate: datasource=docker depName=camunda/web-modeler lookupName=registry.camunda.cloud/web-modeler-ee/modeler-restapi
-    tag: 8.2.3
+    tag: 8.2.4
     # Image.pullSecrets can be used to configure image pull secrets, see https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     # Note: A secret will be required, if the Web Modeler images are pulled directly from Camunda's private registry.
     #
@@ -1427,6 +1453,9 @@ webModeler:
       # Restapi.image.repository defines which image repository to use for the restapi Docker image
       repository: web-modeler-ee/modeler-restapi
 
+    # Restapi.sidecars can be used to attach extra containers to the restapi deployment
+    sidecars: []
+
     # 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).
     # Note: Currently, the only supported database system is PostgreSQL.
@@ -1570,6 +1599,9 @@ webModeler:
       # Webapp.image.repository defines which image repository to use for the webapp Docker image
       repository: web-modeler-ee/modeler-webapp
 
+    # Webapp.sidecars can be used to attach extra containers to the modeler webapp deployment
+    sidecars: []
+
     # Webapp.podAnnotations can be used to define extra webapp pod annotations
     podAnnotations: {}
     # Webapp.podLabels can be used to define extra webapp pod labels
@@ -1680,6 +1712,9 @@ webModeler:
       # Websockets.image.repository defines which image repository to use for the websockets Docker image
       repository: web-modeler-ee/modeler-websockets
 
+    # Websockets.sidecars can be used to attach extra containers to the modeler websockets deployment
+    sidecars: []
+
     # 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.
     # Note: The host will only be used if the Ingress resource for Web Modeler is disabled.
@@ -1864,6 +1899,9 @@ connectors:
     # Image.pullSecrets can be used to configure image pull secrets https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
     pullSecrets: []
 
+  # Sidecars can be used to attach extra containers to the connectors deployment
+  sidecars: []
+
   # Number of Connectors replicas
   replicas: 1
 
diff --git a/charts/camunda-platform/values/values-v8.0.yaml b/charts/camunda-platform/values/values-v8.0.yaml
index 108eb28d..42cafb40 100644
--- a/charts/camunda-platform/values/values-v8.0.yaml
+++ b/charts/camunda-platform/values/values-v8.0.yaml
@@ -7,7 +7,7 @@ global:
   # https://hub.docker.com/u/camunda
   image:
     # renovate: datasource=github-releases depName=camunda/camunda-platform
-    tag: 8.0.14
+    tag: 8.0.15
 
 identity:
   keycloak:


Test patch:
diff --git a/.github/workflows/test-integration-kubernetes.yaml b/.github/workflows/test-integration-kubernetes.yaml
index 92a40b5c..97852a1f 100644
--- a/.github/workflows/test-integration-kubernetes.yaml
+++ b/.github/workflows/test-integration-kubernetes.yaml
@@ -4,11 +4,15 @@ name: "Test - Integration - Kubernetes"
 
 on:
   pull_request:
-    paths:
-    - '.github/workflows/*integration*.yaml'
-    - '.tool-versions'
-    - 'charts/**'
-  workflow_dispatch: { }
+    types:
+    - labeled
+  workflow_dispatch:
+    inputs:
+      trigger:
+        description: 'Trigger release manually'
+        required: false
+        default: false
+        type: boolean
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -32,7 +36,7 @@ env:
 jobs:
   test:
     name: ${{ matrix.test.title }}
-    if: github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == github.repository
+    if: ${{ contains(github.event.*.labels.*.name, 'test-integration-extra') || github.event.inputs.trigger }}
     runs-on: ubuntu-latest
     permissions:
       contents: 'read'
@@ -62,19 +66,8 @@ jobs:
         cluster-location: ${{ secrets.GKE_ZONE }}
         workload-identity-provider: ${{ secrets.GCP_AUTH_WORKLOAD_IDENTITY_PROVIDER }}
         service-account: ${{ secrets.GCP_AUTH_SERVICE_ACCOUNT }}
-    - name: Set test vars
-      id: vars
-      run: |
-        sudo apt install -y pwgen
-        GITHUB_PR_HEAD_SHA_SHORT=$(echo $GITHUB_PR_HEAD_SHA | cut -c 1-7)
-        # NOTE: We should use the matrix job id var once it's available.
-        # https://github.com/orgs/community/discussions/40291
-        GITHUB_WORKFLOW_JOB_ID=$(pwgen 6 1 -A)
-        echo "GITHUB_WORKFLOW_JOB_ID=$GITHUB_WORKFLOW_JOB_ID" >> $GITHUB_ENV
-        # Set full name for the namespace.
-        TEST_NAMESPACE_PART1="camunda-platform-pr-$GITHUB_PR_NUMBER"
-        TEST_NAMESPACE_PART2="sha-$GITHUB_PR_HEAD_SHA_SHORT-run-$GITHUB_WORKFLOW_RUN_ID-sfx-$GITHUB_WORKFLOW_JOB_ID"
-        echo "TEST_NAMESPACE=$TEST_NAMESPACE_PART1-$TEST_NAMESPACE_PART2" >> $GITHUB_ENV
+    - name: Set PR vars
+      uses: ./.github/actions/pr-vars
     - name: Install env dependencies
       uses: asdf-vm/actions/install@v2
     - name: Add Helm repos and dependencies
@@ -105,16 +98,9 @@ jobs:
       timeout-minutes: 20
       run: |
         task -d $TEST_SCENARIOS_DIR/${{ matrix.test.dir }} test.core
-    - name: Get Pods info on failure
+    - name: Get failed Pods info
       if: failure()
-      # TODO: Better way to collect logs and store them as artifacts in GitHub Actions.
-      run: |
-        kubectl -n $TEST_NAMESPACE get po
-        kubectl -n $TEST_NAMESPACE get po | grep -v "Completed" | awk '/0\//{print $1}' | while read pod_name; do
-          echo -e "\n###Failed Pod: ${pod_name}###\n";
-          kubectl -n $TEST_NAMESPACE describe po ${pod_name};
-          kubectl -n $TEST_NAMESPACE logs ${pod_name};
-        done
+      uses: ./.github/actions/failed-pods-info
     - name: Cleanup test namespace
       if: always() && env.CAMUNDA_DISTRO_TEST_DELETE_NAMESPACE != 'false'
       run: |
diff --git a/.github/workflows/test-integration-main.yaml b/.github/workflows/test-integration-main.yaml
new file mode 100644
index 00000000..d29e748e
--- /dev/null
+++ b/.github/workflows/test-integration-main.yaml
@@ -0,0 +1,163 @@
+name: "Test - Integration - Main"
+
+on:
+  pull_request:
+    paths:
+    - '.github/workflows/test-integration-main.yaml'
+    - '.tool-versions'
+    - 'charts/**'
+  workflow_dispatch: { }
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+  cancel-in-progress: true
+
+env:
+  CAMUNDA_DISTRO_TEST_DELETE_NAMESPACE: ${{ !secrets.ACTIONS_STEP_DEBUG }}
+  KUBECONFIG: .github/config/kubeconfig
+  TEST_SCENARIOS_DIR: charts/camunda-platform/test/integration/scenarios
+  # Docker Hub auth to avoid image pull rate limit.
+  TEST_CREATE_DOCKER_LOGIN_SECRET: "TRUE"
+  TEST_DOCKER_USERNAME: ${{ secrets.TEST_DOCKER_USERNAME }}
+  TEST_DOCKER_PASSWORD: ${{ secrets.TEST_DOCKER_PASSWORD }}
+  # Camunda registry auth to access WebModeler Docker image since it's not public.
+  TEST_DOCKER_USERNAME_CAMUNDA_CLOUD: ${{ secrets.CAMUNDA_REGISTRY_USER }}
+  TEST_DOCKER_PASSWORD_CAMUNDA_CLOUD: ${{ secrets.CAMUNDA_REGISTRY_PASSWORD }}
+
+jobs:
+  test:
+    name: Chart full setup - ${{ matrix.test.name }}
+    if: github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == github.repository
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      id-token: write
+      deployments: write
+    strategy:
+      fail-fast: false
+      matrix:
+        test:
+        - name: Kubernetes 1.24
+          type: kubernetes
+          platform: gke
+          secret:
+            cluster-name: GKE_CLUSTER
+            cluster-location: GKE_ZONE
+            workload-identity-provider: GCP_AUTH_WORKLOAD_IDENTITY_PROVIDER
+            service-account: GCP_AUTH_SERVICE_ACCOUNT
+        - name: OpenShift 4.10
+          type: openshift
+          platform: rosa
+          secret:
+            server: OPENSHIFT_URL_410
+            token: OPENSHIFT_TOKEN_410
+    env:
+      TEST_CLUSTER_TYPE: "${{ matrix.test.type }}"
+    steps:
+    - uses: actions/checkout@v3
+    # TODO: Later, find a way to abstract the auth to different platforms.
+    - name: Authenticate to GKE
+      if: matrix.test.platform == 'gke'
+      uses: ./.github/actions/gke-login
+      with:
+        cluster-name: ${{ secrets[matrix.test.secret.cluster-name] }}
+        cluster-location: ${{ secrets[matrix.test.secret.cluster-location] }}
+        workload-identity-provider: ${{ secrets[matrix.test.secret.workload-identity-provider] }}
+        service-account: ${{ secrets[matrix.test.secret.service-account] }}
+    - name: Authenticate to OpenShift
+      if: matrix.test.platform == 'rosa'
+      uses: redhat-actions/oc-login@v1
+      with:
+        openshift_server_url: ${{ secrets[matrix.test.secret.server] }}
+        openshift_token: ${{ secrets[matrix.test.secret.token] }}
+    - name: Set PR vars
+      uses: ./.github/actions/pr-vars
+    - name: Install env dependencies
+      uses: asdf-vm/actions/install@v2
+    - name: Add Helm repos and dependencies
+      run: |
+        make helm.repos-add
+        make helm.dependency-update
+    - name: Create test namespace
+      run: |
+        echo $TEST_NAMESPACE
+        kubectl create ns $TEST_NAMESPACE
+        kubectl label ns $TEST_NAMESPACE github-run-id=$GITHUB_WORKFLOW_RUN_ID
+        kubectl label ns $TEST_NAMESPACE github-job-id=$GITHUB_WORKFLOW_JOB_ID
+    - name: Copy PRs wildcard certificate
+      # TODO: Use a declarative approach to copy/replicate PRs wildcard certificate.
+      run: |
+        kubectl get secret -n distribution-team pr-distro-ultrawombat-com -o yaml |
+          yq '.metadata.name = "camunda-platform", .metadata.namespace = strenv(TEST_NAMESPACE)' |
+          kubectl apply -f -
+        kubectl get secret -n distribution-team pr-distro-ultrawombat-com -o yaml |
+          yq '.metadata.name = "camunda-platform-zeebe-gateway", .metadata.namespace = strenv(TEST_NAMESPACE)' |
+          kubectl apply -f -
+    - name: Export Ingress hostname
+      env:
+        GITHUB_DEPLOYMENT_HOST_BASE: "${{ matrix.test.platform }}-${{ github.event.pull_request.number }}.pr.distro.ultrawombat.com"
+      id: ingress
+      run: |
+        echo "host=${{ env.GITHUB_PR_HEAD_SHA_SHORT }}-${{ env.GITHUB_DEPLOYMENT_HOST_BASE }}" >> $GITHUB_OUTPUT
+    - name: Start GitHub deployment
+      uses: bobheadxi/deployments@v1
+      id: deployment
+      with:
+        step: start
+        token: ${{ secrets.GITHUB_TOKEN }}
+        env: "pr-${{ github.event.pull_request.number }}-${{ matrix.test.platform }}"
+        ref: ${{ github.event.pull_request.head.sha }}
+    - name: Pre setup
+      timeout-minutes: 5
+      env:
+        TEST_INGRESS_HOST: ${{ steps.ingress.outputs.host }}
+      run: |
+        task -d $TEST_SCENARIOS_DIR/chart-full-setup setup.pre
+    - name: Setup Camunda Platform
+      env:
+        TEST_HELM_EXTRA_ARGS: "--set global.ingress.host=${{ steps.ingress.outputs.host }}"
+      run: |
+        task -d $TEST_SCENARIOS_DIR/chart-full-setup setup.exec
+    - name: Post setup
+      timeout-minutes: 5
+      run: |
+        task -d $TEST_SCENARIOS_DIR/chart-full-setup setup.post
+    - name: Update GitHub deployment status
+      uses: bobheadxi/deployments@v1
+      with:
+        step: finish
+        token: ${{ secrets.GITHUB_TOKEN }}
+        status: ${{ job.status }}
+        env_url: https://${{ steps.ingress.outputs.host }}
+        deployment_id: ${{ steps.deployment.outputs.deployment_id }}
+        env: ${{ steps.deployment.outputs.env }}
+        ref: ${{ github.event.pull_request.head.sha }}
+    - name: ⭐️ Run Preflight TestSuite ⭐️
+      timeout-minutes: 10
+      run: |
+        task -d $TEST_SCENARIOS_DIR/chart-full-setup test.preflight
+    - name: ⭐️ Run Core TestSuite ⭐️
+      timeout-minutes: 20
+      run: |
+        task -d $TEST_SCENARIOS_DIR/chart-full-setup test.core
+    - name: Get failed Pods info
+      if: failure()
+      uses: ./.github/actions/failed-pods-info
+    # TODO: Use "step: delete-env" to delete the env when the permission issue is fixed.
+    # Even using GH app token with deployment write access doesn't work.
+    # https://github.com/bobheadxi/deployments/issues/145
+    - name: Cleanup GitHub deployment
+      if: always() && env.CAMUNDA_DISTRO_TEST_DELETE_NAMESPACE != 'false'
+      uses: bobheadxi/deployments@v1
+      with:
+        step: deactivate-env
+        token: ${{ secrets.GITHUB_TOKEN }}
+        env: ${{ steps.deployment.outputs.env }}
+        ref: ${{ github.event.pull_request.head.sha }}
+    - name: Cleanup test namespace
+      if: always() && env.CAMUNDA_DISTRO_TEST_DELETE_NAMESPACE != 'false'
+      run: |
+        kubectl delete ns \
+          --ignore-not-found=true \
+          -l github-run-id=$GITHUB_WORKFLOW_RUN_ID \
+          -l github-job-id=$GITHUB_WORKFLOW_JOB_ID
diff --git a/.github/workflows/test-integration-openshift.yaml b/.github/workflows/test-integration-openshift.yaml
index d2e163a5..60776778 100644
--- a/.github/workflows/test-integration-openshift.yaml
+++ b/.github/workflows/test-integration-openshift.yaml
@@ -2,11 +2,15 @@ name: "Test - Integration - OpenShift"
 
 on:
   pull_request:
-    paths:
-    - '.github/workflows/*integration*.yaml'
-    - '.tool-versions'
-    - 'charts/**'
-  workflow_dispatch: { }
+    types:
+    - labeled
+  workflow_dispatch:
+    inputs:
+      trigger:
+        description: 'Trigger release manually'
+        required: false
+        default: false
+        type: boolean
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -30,7 +34,7 @@ env:
 jobs:
   test:
     name: v${{ matrix.openshift.version }} - ${{ matrix.test.title }}
-    if: github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == github.repository
+    if: ${{ contains(github.event.*.labels.*.name, 'test-integration-extra') || github.event.inputs.trigger }}
     runs-on: ubuntu-latest
     permissions:
       contents: 'read'
@@ -56,19 +60,8 @@ jobs:
       with:
         openshift_server_url: ${{ secrets[matrix.openshift.server] }}
         openshift_token: ${{ secrets[matrix.openshift.token] }}
-    - name: Set test vars
-      id: vars
-      run: |
-        sudo apt install -y pwgen
-        GITHUB_PR_HEAD_SHA_SHORT=$(echo $GITHUB_PR_HEAD_SHA | cut -c 1-7)
-        # NOTE: We should use the matrix job id var once it's available.
-        # https://github.com/orgs/community/discussions/40291
-        GITHUB_WORKFLOW_JOB_ID=$(pwgen 6 1 -A)
-        echo "GITHUB_WORKFLOW_JOB_ID=$GITHUB_WORKFLOW_JOB_ID" >> $GITHUB_ENV
-        # Set full name for the namespace.
-        TEST_NAMESPACE_PART1="camunda-platform-pr-$GITHUB_PR_NUMBER"
-        TEST_NAMESPACE_PART2="sha-$GITHUB_PR_HEAD_SHA_SHORT-run-$GITHUB_WORKFLOW_RUN_ID-sfx-$GITHUB_WORKFLOW_JOB_ID"
-        echo "TEST_NAMESPACE=$TEST_NAMESPACE_PART1-$TEST_NAMESPACE_PART2" >> $GITHUB_ENV
+    - name: Set PR vars
+      uses: ./.github/actions/pr-vars
     - name: Install env dependencies
       uses: asdf-vm/actions/install@v2
     - name: Add Helm repos and dependencies
@@ -99,16 +92,9 @@ jobs:
       timeout-minutes: 20
       run: |
         task -d $TEST_SCENARIOS_DIR/${{ matrix.test.dir }} test.core
-    - name: Get Pods info on failure
+    - name: Get failed Pods info
       if: failure()
-      # TODO: Better way to collect logs and store them as artifacts in GitHub Actions.
-      run: |
-        kubectl -n $TEST_NAMESPACE get po
-        kubectl -n $TEST_NAMESPACE get po | grep -v "Completed" | awk '/0\//{print $1}' | while read pod_name; do
-          echo -e "\n###Failed Pod: ${pod_name}###\n";
-          kubectl -n $TEST_NAMESPACE describe po ${pod_name};
-          kubectl -n $TEST_NAMESPACE logs ${pod_name};
-        done
+      uses: ./.github/actions/failed-pods-info
     - name: Cleanup test namespace
       if: always() && env.CAMUNDA_DISTRO_TEST_DELETE_NAMESPACE != 'false'
       run: |
diff --git a/.github/workflows/test-regression.yaml b/.github/workflows/test-regression.yaml
index 48161471..4e501475 100644
--- a/.github/workflows/test-regression.yaml
+++ b/.github/workflows/test-regression.yaml
@@ -4,10 +4,10 @@ name: "Test - Regression"
 on:
   push:
     paths:
-    - 'charts/camunda-platform/values'
+    - 'charts/camunda-platform/values/*'
   pull_request:
     paths:
-    - 'charts/camunda-platform/values'
+    - 'charts/camunda-platform/values/*'
   workflow_dispatch: { }
 
 concurrency:
@@ -24,7 +24,7 @@ env:
 jobs:
   test:
     name: Previous chart v${{ matrix.camundaChart }}.x
-    if: github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == github.repository
+    if: ${{ contains(github.event.*.labels.*.name, 'test-regression') || github.event.pull_request.head.repo.full_name == github.repository }}
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
diff --git a/charts/camunda-platform/templates/tests/integration-test-secret.yaml b/charts/camunda-platform/templates/tests/integration-test-secret.yaml
index 9115fc27..22033dc5 100644
--- a/charts/camunda-platform/templates/tests/integration-test-secret.yaml
+++ b/charts/camunda-platform/templates/tests/integration-test-secret.yaml
@@ -8,4 +8,5 @@ metadata:
 type: Opaque
 data:
   client-secret: {{ include "common.secrets.passwords.manage" (dict "secret" "integration-test" "key" "client-secret" "length" 16 "providedValues" (list "test.existingSecret") "context" $) }}
+  identity-firstuser-password: {{ include "common.secrets.passwords.manage" (dict "secret" "integration-test" "key" "identity-firstuser-password" "length" 16 "providedValues" (list "") "context" $) }}
 {{- end }}
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-full-setup/Taskfile.yaml b/charts/camunda-platform/test/integration/scenarios/chart-full-setup/Taskfile.yaml
new file mode 100644
index 00000000..c6d8e24c
--- /dev/null
+++ b/charts/camunda-platform/test/integration/scenarios/chart-full-setup/Taskfile.yaml
@@ -0,0 +1,63 @@
+version: '3'
+
+vars:
+  TEST_NAMESPACE: '{{ env "TEST_NAMESPACE" | default "camunda-platform" }}'
+  TEST_CLUSTER_TYPE: '{{ env "TEST_CLUSTER_TYPE" | default "kubernetes" }}'
+  TEST_HELM_EXTRA_ARGS: '{{ env "TEST_HELM_EXTRA_ARGS" }} {{ .TEST_OPENSHIFT_ARGS }}'
+
+dotenv:
+- ../vars/common.env
+- ../vars/{{ .TEST_CLUSTER_TYPE }}.env
+
+includes:
+  init.seed: ../lib/init-seed-taskfile.yaml
+  test.preflight:
+    taskfile: ../lib/testsuite-deploy-taskfile.yaml
+    vars:
+      testID: preflight
+  test.core:
+    taskfile: ../lib/testsuite-deploy-taskfile.yaml
+    vars:
+      testID: core
+
+tasks:
+  setup.pre:
+    preconditions:
+    - test -n "${TEST_DOCKER_USERNAME_CAMUNDA_CLOUD}"
+    - test -n "${TEST_DOCKER_PASSWORD_CAMUNDA_CLOUD}"
+    cmds:
+    # This is needed to access WebModeler Docker image since it's not public.
+    - kubectl create secret docker-registry registry-camunda-cloud
+        --namespace {{ .TEST_NAMESPACE }}
+        --docker-server "registry.camunda.cloud"
+        --docker-username "${TEST_DOCKER_USERNAME_CAMUNDA_CLOUD}"
+        --docker-password "${TEST_DOCKER_PASSWORD_CAMUNDA_CLOUD}"
+    - echo "VENOM_VAR_SKIP_TEST_INGRESS=false" >> ../../testsuites/base/files/variables.env
+    - echo "VENOM_VAR_TEST_INGRESS_HOST={{ env "TEST_INGRESS_HOST" }}" >> ../../testsuites/base/files/variables.env
+    - echo "VENOM_VAR_SKIP_TEST_WEBMODELER=false" >> ../../testsuites/base/files/variables.env
+    - echo "VENOM_EXTRA_ARGS=--var-from-file=./vars/variables-ingress-combined.yaml" >>
+      ../../testsuites/base/files/variables.env
+
+  setup.exec:
+    deps: [init.seed]
+    cmds:
+    - helm install integration {{ .CHART_DIR }}
+        --namespace {{ .TEST_NAMESPACE }}
+        --values {{ .FIXTURES_DIR }}/values-integration-test.yaml
+        --values ./values-integration-test-ingress.yaml
+        --timeout 20m0s
+        --wait
+        {{ .TEST_HELM_EXTRA_ARGS }}
+
+  setup.post:
+    cmds:
+    - echo "No post task for this test."
+
+  all:
+    cmds:
+    - task: init.seed
+    - task: setup.pre
+    - task: setup.exec
+    - task: setup.post
+    - task: test.preflight
+    - task: test.core
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-full-setup/values-integration-test-ingress.yaml b/charts/camunda-platform/test/integration/scenarios/chart-full-setup/values-integration-test-ingress.yaml
new file mode 100644
index 00000000..cf3bc9dd
--- /dev/null
+++ b/charts/camunda-platform/test/integration/scenarios/chart-full-setup/values-integration-test-ingress.yaml
@@ -0,0 +1,70 @@
+global:
+  ingress:
+    enabled: true
+    className: nginx
+    # The Ingress host will be added via CLI.
+    host: ""
+    tls:
+      enabled: true
+      # A wildcard certificate will be used.
+      secretName: camunda-platform
+    annotations:
+      external-dns.alpha.kubernetes.io/hostname: "{{ .Values.global.ingress.host }}"
+      external-dns.alpha.kubernetes.io/ttl: "60"
+
+  identity:
+    auth:
+      publicIssuerUrl: "https://{{ .Values.global.ingress.host }}/auth/realms/camunda-platform"
+      operate:
+        redirectUrl: "https://{{ .Values.global.ingress.host }}/operate"
+      tasklist:
+        redirectUrl: "https://{{ .Values.global.ingress.host }}/tasklist"
+      optimize:
+        redirectUrl: "https://{{ .Values.global.ingress.host }}/optimize"
+      webModeler:
+        redirectUrl: "https://{{ .Values.global.ingress.host }}/modeler"
+
+identity:
+  contextPath: "/identity"
+  fullURL: "https://{{ .Values.global.ingress.host }}/identity"
+
+operate:
+  contextPath: "/operate"
+
+optimize:
+  contextPath: "/optimize"
+
+tasklist:
+  contextPath: "/tasklist"
+
+connectors:
+  contextPath: "/connectors"
+
+webModeler:
+  enabled: true
+  contextPath: "/modeler"
+  image:
+    pullSecrets:
+    - name: index-docker-io
+    - name: registry-camunda-cloud
+  restapi:
+    mail:
+      # This value is required, otherwise the restapi pod wouldn't start.
+      fromAddress: noreply@example.com
+
+# database used by Web Modeler
+postgresql:
+  enabled: true
+
+zeebe-gateway:
+  ingress:
+    enabled: true
+    className: nginx
+    host: "zeebe-{{ .Values.global.ingress.host }}"
+    tls:
+      enabled: true
+      # A wildcard certificate will be used.
+      secretName: camunda-platform-zeebe-gateway
+    annotations:
+      external-dns.alpha.kubernetes.io/hostname: "zeebe-{{ .Values.global.ingress.host }}"
+      external-dns.alpha.kubernetes.io/ttl: "60"
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-upgrade/Taskfile.yaml b/charts/camunda-platform/test/integration/scenarios/chart-upgrade/Taskfile.yaml
index 9cd0dc88..32721ab2 100644
--- a/charts/camunda-platform/test/integration/scenarios/chart-upgrade/Taskfile.yaml
+++ b/charts/camunda-platform/test/integration/scenarios/chart-upgrade/Taskfile.yaml
@@ -3,7 +3,7 @@ version: '3'
 vars:
   TEST_NAMESPACE: '{{ env "TEST_NAMESPACE" | default "camunda-platform" }}'
   TEST_CLUSTER_TYPE: '{{ env "TEST_CLUSTER_TYPE" | default "kubernetes" }}'
-  HELM_EXTRA_ARGS: '{{ env "HELM_EXTRA_ARGS" }} {{ .OPENSHIFT_ARGS }}'
+  TEST_HELM_EXTRA_ARGS: '{{ env "TEST_HELM_EXTRA_ARGS" }} {{ .TEST_OPENSHIFT_ARGS }}'
 
 dotenv:
 - ../vars/common.env
@@ -32,7 +32,7 @@ tasks:
     - helm install integration {{ .CHART_DIR }}
         --namespace {{ .TEST_NAMESPACE }}
         --values {{ .FIXTURES_DIR }}/values-integration-test.yaml
-        {{ .HELM_EXTRA_ARGS }}
+        {{ .TEST_HELM_EXTRA_ARGS }}
     - |
       export TEST_SECRET=$(kubectl get secret "integration-test" \
         -n $TEST_NAMESPACE -o jsonpath="{.data.client-secret}" | base64 --decode)
@@ -63,7 +63,7 @@ tasks:
         --set identity.keycloak.auth.adminPassword=$KEYCLOAK_ADMIN_SECRET \
         --set identity.keycloak.postgresql.auth.password=$POSTGRESQL_SECRET \
         --timeout 20m0s \
-        --wait {{ .HELM_EXTRA_ARGS }}
+        --wait {{ .TEST_HELM_EXTRA_ARGS }}
 
   setup.post:
     cmds:
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-with-custom-values/Taskfile.yaml b/charts/camunda-platform/test/integration/scenarios/chart-with-custom-values/Taskfile.yaml
index 94987138..816f4446 100644
--- a/charts/camunda-platform/test/integration/scenarios/chart-with-custom-values/Taskfile.yaml
+++ b/charts/camunda-platform/test/integration/scenarios/chart-with-custom-values/Taskfile.yaml
@@ -3,7 +3,7 @@ version: '3'
 vars:
   TEST_NAMESPACE: '{{ env "TEST_NAMESPACE" | default "camunda-platform" }}'
   TEST_CLUSTER_TYPE: '{{ env "TEST_CLUSTER_TYPE" | default "kubernetes" }}'
-  HELM_EXTRA_ARGS: '{{ env "HELM_EXTRA_ARGS" }} {{ .OPENSHIFT_ARGS }}'
+  TEST_HELM_EXTRA_ARGS: '{{ env "TEST_HELM_EXTRA_ARGS" }} {{ .TEST_OPENSHIFT_ARGS }}'
 
 dotenv:
 - ../vars/common.env
@@ -34,7 +34,7 @@ tasks:
         --values ./values-custom.yaml
         --timeout 20m0s
         --wait
-        {{ .HELM_EXTRA_ARGS }}
+        {{ .TEST_HELM_EXTRA_ARGS }}
 
   setup.post:
     cmds:
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-with-default-values/Taskfile.yaml b/charts/camunda-platform/test/integration/scenarios/chart-with-default-values/Taskfile.yaml
index b8c31a95..561272e1 100644
--- a/charts/camunda-platform/test/integration/scenarios/chart-with-default-values/Taskfile.yaml
+++ b/charts/camunda-platform/test/integration/scenarios/chart-with-default-values/Taskfile.yaml
@@ -3,7 +3,7 @@ version: '3'
 vars:
   TEST_NAMESPACE: '{{ env "TEST_NAMESPACE" | default "camunda-platform" }}'
   TEST_CLUSTER_TYPE: '{{ env "TEST_CLUSTER_TYPE" | default "kubernetes" }}'
-  HELM_EXTRA_ARGS: '{{ env "HELM_EXTRA_ARGS" }} {{ .OPENSHIFT_ARGS }}'
+  TEST_HELM_EXTRA_ARGS: '{{ env "TEST_HELM_EXTRA_ARGS" }} {{ .TEST_OPENSHIFT_ARGS }}'
 
 dotenv:
 - ../vars/common.env
@@ -33,7 +33,7 @@ tasks:
         --values {{ .FIXTURES_DIR }}/values-integration-test.yaml
         --timeout 20m0s
         --wait
-        {{ .HELM_EXTRA_ARGS }}
+        {{ .TEST_HELM_EXTRA_ARGS }}
 
 
   setup.post:
diff --git a/charts/camunda-platform/test/integration/scenarios/chart-with-web-modeler/Taskfile.yaml b/charts/camunda-platform/test/integration/scenarios/chart-with-web-modeler/Taskfile.yaml
index e22dce20..46ee501a 100644
--- a/charts/camunda-platform/test/integration/scenarios/chart-with-web-modeler/Taskfile.yaml
+++ b/charts/camunda-platform/test/integration/scenarios/chart-with-web-modeler/Taskfile.yaml
@@ -3,7 +3,7 @@ version: '3'
 vars:
   TEST_NAMESPACE: '{{ env "TEST_NAMESPACE" | default "camunda-platform" }}'
   TEST_CLUSTER_TYPE: '{{ env "TEST_CLUSTER_TYPE" | default "kubernetes" }}'
-  HELM_EXTRA_ARGS: '{{ env "HELM_EXTRA_ARGS" }} {{ .OPENSHIFT_ARGS }}'
+  TEST_HELM_EXTRA_ARGS: '{{ env "TEST_HELM_EXTRA_ARGS" }} {{ .TEST_OPENSHIFT_ARGS }}'
 
 dotenv:
 - ../vars/common.env
@@ -32,7 +32,7 @@ tasks:
         --docker-server "registry.camunda.cloud"
         --docker-username "${TEST_DOCKER_USERNAME_CAMUNDA_CLOUD}"
         --docker-password "${TEST_DOCKER_PASSWORD_CAMUNDA_CLOUD}"
-    - echo "VENOM_VAR_SKIP_TEST_WEBMODELER=false" >> ../../testsuites/base/files/vars.env
+    - echo "VENOM_VAR_SKIP_TEST_WEBMODELER=false" >> ../../testsuites/base/files/variables.env
 
   setup.exec:
     deps: [init.seed]
@@ -43,7 +43,7 @@ tasks:
         --values ./values-web-modeler-enabled.yaml
         --timeout 20m0s
         --wait
-        {{ .HELM_EXTRA_ARGS }}
+        {{ .TEST_HELM_EXTRA_ARGS }}
 
   setup.post:
     cmds:
diff --git a/charts/camunda-platform/test/integration/scenarios/vars/openshift.env b/charts/camunda-platform/test/integration/scenarios/vars/openshift.env
index 354f4792..fd423f04 100644
--- a/charts/camunda-platform/test/integration/scenarios/vars/openshift.env
+++ b/charts/camunda-platform/test/integration/scenarios/vars/openshift.env
@@ -1,1 +1,1 @@
-OPENSHIFT_ARGS=--values {{ .CHART_DIR }}/openshift/values.yaml --values {{ .CHART_DIR }}/openshift/values-patch.yaml --post-renderer {{ .CHART_DIR }}/openshift/patch.sh
+TEST_OPENSHIFT_ARGS=--values {{ .CHART_DIR }}/openshift/values.yaml --values {{ .CHART_DIR }}/openshift/values-patch.yaml --post-renderer {{ .CHART_DIR }}/openshift/patch.sh
diff --git a/charts/camunda-platform/test/integration/testsuites/base/files/variables-default.yaml b/charts/camunda-platform/test/integration/testsuites/base/files/variables-default.yaml
new file mode 100644
index 00000000..82520415
--- /dev/null
+++ b/charts/camunda-platform/test/integration/testsuites/base/files/variables-default.yaml
@@ -0,0 +1,26 @@
+preflightVars:
+  baseURLs:
+    elasticsearch: http://elasticsearch-master:9200
+    keycloak: http://integration-keycloak
+    identity: http://integration-identity:82
+    optimize: http://integration-optimize
+    operate: http://integration-operate
+    tasklist: http://integration-tasklist
+    connectors: http://integration-connectors:8080
+    zeebeGateway: http://integration-zeebe-gateway:9600
+    webModelerRestapi: http://integration-web-modeler-restapi:8091
+    webModelerWebapp: http://integration-web-modeler-webapp:8071
+
+coreVars:
+  authURL: "http://integration-keycloak/auth/realms/camunda-platform/protocol/openid-connect/token"
+  baseURLs:
+    keycloak: http://integration-keycloak
+    identity: http://integration-identity
+    optimize: http://integration-optimize
+    operate: http://integration-operate
+    tasklist: http://integration-tasklist
+    connectors: http://integration-connectors:8080/inbound
+    webModelerRestapi: http://integration-web-modeler-restapi
+    zeebeGateway: integration-zeebe-gateway:26500
+  zbctl:
+    extraArgs: "--insecure"
diff --git a/charts/camunda-platform/test/integration/testsuites/base/files/variables-ingress-combined.yaml b/charts/camunda-platform/test/integration/testsuites/base/files/variables-ingress-combined.yaml
new file mode 100644
index 00000000..5db776cc
--- /dev/null
+++ b/charts/camunda-platform/test/integration/testsuites/base/files/variables-ingress-combined.yaml
@@ -0,0 +1,27 @@
+preflightVars:
+  baseURLs:
+    elasticsearch: http://elasticsearch-master:9200
+    keycloak: http://integration-keycloak
+    identity: http://integration-identity:82
+    optimize: http://integration-optimize/optimize
+    operate: http://integration-operate/operate
+    tasklist: http://integration-tasklist/tasklist
+    connectors: http://integration-connectors:8080/connectors
+    zeebeGateway: http://integration-zeebe-gateway:9600
+    webModelerRestapi: http://integration-web-modeler-restapi:8091
+    webModelerWebapp: http://integration-web-modeler-webapp:8071
+
+coreVars:
+  authURL: "https://{{ .TEST_INGRESS_HOST }}/auth/realms/camunda-platform/protocol/openid-connect/token"
+  baseURLs:
+    keycloak: "https://{{ .TEST_INGRESS_HOST }}/auth"
+    identity: "https://{{ .TEST_INGRESS_HOST }}/identity"
+    operate: "https://{{ .TEST_INGRESS_HOST }}/operate"
+    optimize: "https://{{ .TEST_INGRESS_HOST }}/optimize"
+    tasklist: "https://{{ .TEST_INGRESS_HOST }}/tasklist"
+    connectors: "https://{{ .TEST_INGRESS_HOST }}/connectors/inbound"
+    webModeler: "https://{{ .TEST_INGRESS_HOST }}/modeler"
+    webModelerRestapi: http://integration-web-modeler-restapi
+    zeebeGateway: "zeebe-{{ .TEST_INGRESS_HOST }}:443"
+  zbctl:
+    extraArgs: ""
diff --git a/charts/camunda-platform/test/integration/testsuites/base/files/vars.env b/charts/camunda-platform/test/integration/testsuites/base/files/variables.env
similarity index 100%
rename from charts/camunda-platform/test/integration/testsuites/base/files/vars.env
rename to charts/camunda-platform/test/integration/testsuites/base/files/variables.env
diff --git a/charts/camunda-platform/test/integration/testsuites/base/job.yaml b/charts/camunda-platform/test/integration/testsuites/base/job.yaml
index 5d9a69a5..d806579f 100644
--- a/charts/camunda-platform/test/integration/testsuites/base/job.yaml
+++ b/charts/camunda-platform/test/integration/testsuites/base/job.yaml
@@ -35,9 +35,6 @@ spec:
         - sh
         - -c
         - |
-          # TODO: Debug why envs from "envFrom" are not exported by default.
-          export $(env | grep VENOM_VAR_);
-
           # NOTE: That loop will be replaced once we use Testkube.
           try=0
           limit=3
@@ -46,7 +43,8 @@ spec:
           until [ ${try} -ge ${limit} ]; do
             try=$((try + 1))
             echo "[INFO] Venom exec no. ${try}..."
-            /usr/local/venom run ./tests/${VENOM_RUN_ARGS:-*.y*ml}
+            /usr/local/venom run ./tests/${VENOM_TESTSUITE_FILES:-*.yaml} \
+              ${VENOM_EXTRA_ARGS:- --var-from-file=./vars/variables-default.yaml}
             exit_code=$?
             test ${exit_code} == 0 && break
             sleep ${delay}
@@ -57,13 +55,15 @@ spec:
             exit 1
           fi
         env:
+        - name: IS_TTY
+          value: "true"
         # Used to access get token from Keycloak to access Camunda APIs.
         - name: VENOM_VAR_TEST_CLIENT_SECRET
           valueFrom:
             secretKeyRef:
               name: integration-test
               key: client-secret
-              # Making it optional for debugging Venom where is no Camunda Platform os deployed.
+              # Making it optional for debugging Venom where is no Camunda Platform is deployed.
               optional: true
         envFrom:
         - configMapRef:
@@ -74,6 +74,8 @@ spec:
           subPath: zbctl
         - name: venom-tests
           mountPath: /workdir/tests
+        - name: venom-vars
+          mountPath: /workdir/vars
         - name: venom-fixtures
           mountPath: /mnt/fixtures
       volumes:
@@ -82,6 +84,9 @@ spec:
       - name: venom-tests
         configMap:
           name: venom-tests
+      - name: venom-vars
+        configMap:
+          name: venom-vars
       - name: venom-fixtures
         configMap:
           name: venom-fixtures
diff --git a/charts/camunda-platform/test/integration/testsuites/base/kustomization.yaml b/charts/camunda-platform/test/integration/testsuites/base/kustomization.yaml
index 49c494b0..6b67309c 100644
--- a/charts/camunda-platform/test/integration/testsuites/base/kustomization.yaml
+++ b/charts/camunda-platform/test/integration/testsuites/base/kustomization.yaml
@@ -10,11 +10,17 @@ configMapGenerator:
     disableNameSuffixHash: true
   files:
   - testsuites/00-info.yaml
-- name: venom-env-vars
+- name: venom-vars
   options:
     disableNameSuffixHash: true
   files:
-  - files/vars.env
+  - files/variables-default.yaml
+  - files/variables-ingress-combined.yaml
+- name: venom-env-vars
+  options:
+    disableNameSuffixHash: true
+  envs:
+  - files/variables.env
 - name: venom-fixtures
   options:
     disableNameSuffixHash: true
diff --git a/charts/camunda-platform/test/integration/testsuites/base/testsuites/00-info.yaml b/charts/camunda-platform/test/integration/testsuites/base/testsuites/00-info.yaml
index 53a6449b..8749d9ea 100644
--- a/charts/camunda-platform/test/integration/testsuites/base/testsuites/00-info.yaml
+++ b/charts/camunda-platform/test/integration/testsuites/base/testsuites/00-info.yaml
@@ -2,14 +2,14 @@ name: Print basic info
 
 testcases:
 
-- name: Info
+- name: Venom Info
   steps:
   - type: exec
     script: |
       cat << EOF
-        - Timestamp: {{.venom.timestamp}}
-        - Datetime: {{.venom.datetime}}
-        - Output dir: {{.venom.outputdir}}
+        - Timestamp: {{ .venom.timestamp }}
+        - Datetime: {{ .venom.datetime }}
+        - Output dir: {{ .venom.outputdir }}
         - Test files:
       $(printf "    - %s\n" $(ls))
       EOF
@@ -17,3 +17,16 @@ testcases:
       ###
       {{ .result.systemout }}
       ###
+
+- name: Tests Info
+  steps:
+  - type: exec
+    script: |
+      echo -e "\npreflightVars:"
+      echo "{{ .preflightVars | toPrettyJSON }}"
+      echo "coreVars:"
+      echo "{{ .coreVars | toPrettyJSON }}"
+    info: |
+      = systemout: {{ .result.systemout }}
+      = systemerr: {{ .result.systemerr }}
+      = err: {{ .result.err }}
diff --git a/charts/camunda-platform/test/integration/testsuites/core/testsuites/core.yaml b/charts/camunda-platform/test/integration/testsuites/core/testsuites/core.yaml
index e55d3524..99749c6b 100644
--- a/charts/camunda-platform/test/integration/testsuites/core/testsuites/core.yaml
+++ b/charts/camunda-platform/test/integration/testsuites/core/testsuites/core.yaml
@@ -2,12 +2,12 @@
 # https://github.com/ovh/venom/issues/651
 name: Test core functionality of Camunda Platform
 
+# Vars without defaults are passed as a Venom var, e.g. "VENOM_VAR_TEST_CLIENT_SECRET".
 vars:
-  releaseName: '{{ .RELEASE_NAME | default "integration" }}'
-  authURL: 'http://{{ .RELEASE_NAME | default "integration" }}-keycloak/auth/realms/camunda-platform/protocol/openid-connect/token'
+  releaseName: integration
   venomClientID: '{{ .TEST_CLIENT_ID | default "venom" }}'
-  # Passed as a Venom var, e.g. "VENOM_VAR_TEST_CLIENT_SECRET".
-  venomClientSecret: "{{ .TEST_CLIENT_SECRET }}"
+  venomClientSecret: '{{ .TEST_CLIENT_SECRET }}'
+  skipTestIngress: '{{ .SKIP_TEST_INGRESS }}'
   skipTestWebModeler: '{{ .SKIP_TEST_WEBMODELER }}'
 
 testcases:
@@ -31,14 +31,14 @@ testcases:
       clientID: connectors
       clientSecret: "{{ .CONNECTORS_CLIENT_SECRET }}"
     method: POST
-    url: "{{ .authURL }}"
+    url: "{{ .coreVars.authURL }}"
     headers:
       Content-Type: application/x-www-form-urlencoded
     body: |-
       client_id={{ .value.clientID }}&client_secret={{ .value.clientSecret }}&grant_type=client_credentials
     # info: |
     #   Component: {{ .value.component }}
-    #   - Response Body: {{ .result.body }}
+    #   = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
 
@@ -48,36 +48,72 @@ testcases:
   - name: Get Venom token
     type: http
     method: POST
-    url: "{{ .authURL }}"
+    url: "{{ .coreVars.authURL }}"
     headers:
       Content-Type: application/x-www-form-urlencoded
     body: "client_id={{ .venomClientID }}&client_secret={{ .venomClientSecret }}&grant_type=client_credentials"
     # info: |
-    #   - Response Body: {{ .result.body }}
+    #   = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
     vars:
       jwt:
         from: result.bodyjson.access_token
 
+# TODO: Use Venom "web" module to test actual login. It's easy but requires "PhantomJS"
+# which is not available on Alpine, so it needs to be installed first.
+- name: TEST - Interacting with Camunda Platform login page
+  steps:
+  - name: "{{ .value.component }}"
+    skip:
+    - skiptestingress ShouldBeFalse
+    type: http
+    range:
+    - component: Keycloak
+      url: "{{ .coreVars.baseURLs.keycloak }}"
+    - component: Identity
+      url: "{{ .coreVars.baseURLs.identity }}"
+    - component: Operate
+      url: "{{ .coreVars.baseURLs.operate }}"
+    - component: Optimize
+      url: "{{ .coreVars.baseURLs.optimize }}"
+    - component: Tasklist
+      url: "{{ .coreVars.baseURLs.tasklist }}"
+    - component: Connectors
+      url: "{{ .coreVars.baseURLs.connectors }}"
+    - component: WebModeler
+      url: "{{ .coreVars.baseURLs.webModeler }}"
+    method: GET
+    url: "{{ .value.url }}"
+    retry: 3
+    delay: 15
+    # info: |
+    #   Component: {{ .value.component }}
+    #   = Request Method: {{ .value.method }}
+    #   = Request Body: {{ .result.request.body }}
+    #   = Response Body: {{ .result.body }}
+    assertions:
+    - result.statuscode ShouldEqual 200
+    - result.body ShouldNotContainSubstring error
+
 # TODO: Add Optimize.
-- name: TEST - Interacting with components web API
+- name: TEST - Interacting with Camunda Platform web API
   steps:
   - name: "{{ .value.component }}"
     type: http
     range:
     - component: Identity
-      url: "http://{{ .releaseName }}-identity/api/users"
+      url: "{{ .coreVars.baseURLs.identity }}/api/users"
       method: GET
       body: ''
     - component: Operate
       docs: https://docs.camunda.io/docs/self-managed/operate-deployment/operate-authentication/
-      url: "http://{{ .releaseName }}-operate/v1/process-definitions/search"
+      url: "{{ .coreVars.baseURLs.operate }}/v1/process-definitions/search"
       method: POST
       body: '{}'
     - component: Tasklist
       docs: https://docs.camunda.io/docs/self-managed/tasklist-deployment/tasklist-authentication/
-      url: "http://{{ .releaseName }}-tasklist/graphql"
+      url: "{{ .coreVars.baseURLs.tasklist }}/graphql"
       method: POST
       body: '{"query": "{tasks(query:{}){id name}}"}'
     method: "{{ .value.method }}"
@@ -88,37 +124,64 @@ testcases:
     body: "{{ .value.body }}"
     # info: |
     #   Component: {{ .value.component }}
-    #   - Request Method: {{ .value.method }}
-    #   - Request Body: {{ .result.request.body }}
-    #   - Response Body: {{ .result.body }}
+    #   = Request Method: {{ .value.method }}
+    #   = Request Body: {{ .result.request.body }}
+    #   = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
 
-  - name: WebModeler
+# Unlike other apps, WebModeler by default expects the JWT token to be acquired from external Keycloak URL.
+# Hence, this test is added in the extra tests when Ingress is enabled.
+- name: TEST - Interacting with WebModeler
+  steps:
+  - name: Check WebModeler internal API
     skip:
     - skiptestwebmodeler ShouldBeFalse
     type: http
     method: GET
-    url: "http://{{ .releaseName }}-web-modeler-restapi/api/beta/info"
+    url: "{{ .coreVars.baseURLs.webModelerRestapi }}/api/beta/info"
     headers:
       Content-Type: application/json
       Authorization: "Bearer {{ .helperVenomToken.jwt }}"
     # info: |
-    #   - Request Body: {{ .result.request.body }}
-    #   - Response Body: {{ .result.body }}
+    #   = Request Body: {{ .result.request.body }}
+    #   = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
     - result.bodyjson.version ShouldNotBeEmpty
+  - name: Check WebModeler login page
+    skip:
+    - skiptestingress ShouldBeFalse
+    - skiptestwebmodeler ShouldBeFalse
+    type: http
+    method: GET
+    url: "{{ .coreVars.baseURLs.webModeler }}"
+    retry: 3
+    delay: 15
+    # info: |
+    #   Component: {{ .value.component }}
+    #   = Request Method: {{ .value.method }}
+    #   = Request Body: {{ .result.request.body }}
+    #   = Response Body: {{ .result.body }}
+    assertions:
+    - result.statuscode ShouldEqual 200
+    - result.body ShouldNotContainSubstring error
 
 - name: TEST - Interacting with Zeebe Gateway
   steps:
   - name: Check Zeebe Gateway status
     type: exec
     script: |
-      zbctl --insecure --clientCache=/tmp/zeebe \
+      zbctl --clientCache=/tmp/zeebe \
           --clientId {{ .venomClientID }} --clientSecret {{ .venomClientSecret }} \
-          --authzUrl "{{ .authURL }}" --address "{{ .releaseName }}-zeebe-gateway:26500" \
+          --authzUrl "{{ .coreVars.authURL }}" --address "{{ .coreVars.baseURLs.zeebeGateway }}" \
+          {{ .coreVars.zbctl.extraArgs }} \
           status
+    retry: 2
+    delay: 10
+    # info: |
+    #   = systemerr: {{ .result.systemerr }}
+    #   = err: {{ .result.err }}
     assertions:
     - result.code ShouldEqual 0
     - result.systemout ShouldContainSubstring "Leader, Healthy"
@@ -135,10 +198,14 @@ testcases:
     - name: Inbound Connector
       file: test-inbound-process.bpmn
     script: |
-      zbctl --insecure --clientCache=/tmp/zeebe \
+      zbctl --clientCache=/tmp/zeebe \
           --clientId {{ .venomClientID }} --clientSecret {{ .venomClientSecret }} \
-          --authzUrl "{{ .authURL }}" --address "{{ .releaseName }}-zeebe-gateway:26500" \
+          --authzUrl "{{ .coreVars.authURL }}" --address "{{ .coreVars.baseURLs.zeebeGateway }}" \
+          {{ .coreVars.zbctl.extraArgs }} \
           deploy /mnt/fixtures/{{ .value.file }}
+    # info: |
+    #   = systemerr: {{ .result.systemerr }}
+    #   = err: {{ .result.err }}
     assertions:
     - result.code ShouldEqual 0
 
@@ -152,17 +219,17 @@ testcases:
     - name: Inbound Connector
       id: test-inbound-process
     method: POST
-    url: "http://{{ .releaseName }}-operate/v1/process-definitions/search"
+    url: "{{ .coreVars.baseURLs.operate }}/v1/process-definitions/search"
     headers:
       Content-Type: application/json
       Authorization: "Bearer {{ .helperVenomToken.jwt }}"
     body: '{}'
     retry: 3
-    delay: 20
+    delay: 15
     # TODO: Remove it after debugging Operate issue.
     info: |
-      - Request Body: {{ .result.request.body }}
-      - Response Body: {{ .result.body }}
+      = Request Body: {{ .result.request.body }}
+      = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
     # NOTE: JSON keys are lowercased automatically, the original key is "bpmnProcessId".
@@ -173,15 +240,15 @@ testcases:
   - name: Check deployed BPMN webhook
     type: http
     method: POST
-    url: "http://{{ .releaseName }}-connectors:8080/inbound/test-mywebhook"
+    url: "{{ .coreVars.baseURLs.connectors }}/test-mywebhook"
     headers:
       Content-Type: application/json
       Authorization: "Bearer {{ .helperVenomToken.jwt }}"
     body: '{"webhookDataKey":"webhookDataValue"}'
-    retry: 6
+    retry: 4
     delay: 15
     # info: |
-    #   - Request Body: {{ .result.request.body }}
-    #   - Response Body: {{ .result.body }}
+    #   = Request Body: {{ .result.request.body }}
+    #   = Response Body: {{ .result.body }}
     assertions:
     - result.statuscode ShouldEqual 200
diff --git a/charts/camunda-platform/test/integration/testsuites/preflight/testsuites/preflight.yaml b/charts/camunda-platform/test/integration/testsuites/preflight/testsuites/preflight.yaml
index 60bb1f98..8e8deca4 100644
--- a/charts/camunda-platform/test/integration/testsuites/preflight/testsuites/preflight.yaml
+++ b/charts/camunda-platform/test/integration/testsuites/preflight/testsuites/preflight.yaml
@@ -2,8 +2,9 @@
 # https://github.com/ovh/venom/issues/651
 name: Run preflight checks for Camunda Platform
 
+# Vars without defaults are passed as a Venom var, e.g. "VENOM_VAR_TEST_CLIENT_SECRET".
 vars:
-  releaseName: '{{ .RELEASE_NAME | default "integration" }}'
+  releaseName: integration
   skipTestWebModeler: '{{ .SKIP_TEST_WEBMODELER }}'
 
 testcases:
@@ -14,23 +15,23 @@ testcases:
     type: http
     range:
     # Dependencies.
-    - component: Keycloak
-      url: http://{{ .releaseName }}-keycloak/auth/realms/master
     - component: Elasticsearch
-      url: "http://elasticsearch-master:9200/_cluster/health?&timeout=1s"
+      url: "{{ .preflightVars.baseURLs.elasticsearch }}/_cluster/health?&timeout=1s"
+    - component: Keycloak
+      url: "{{ .preflightVars.baseURLs.keycloak }}/auth/realms/master"
     # Camunda.
     - component: Identity
-      url: http://{{ .releaseName }}-identity:82/actuator/health
+      url: "{{ .preflightVars.baseURLs.identity }}/actuator/health"
     - component: Optimize
-      url: http://{{ .releaseName }}-optimize/api/readyz
+      url: "{{ .preflightVars.baseURLs.optimize }}/api/readyz"
     - component: Operate
-      url: http://{{ .releaseName }}-operate/actuator/health/readiness
+      url: "{{ .preflightVars.baseURLs.operate }}/actuator/health/readiness"
     - component: Tasklist
-      url: http://{{ .releaseName }}-tasklist/actuator/health/readiness
+      url: "{{ .preflightVars.baseURLs.tasklist }}/actuator/health/readiness"
     - component: Connectors
-      url: http://{{ .releaseName }}-connectors:8080/actuator/health/readiness
+      url: "{{ .preflightVars.baseURLs.connectors }}/actuator/health/readiness"
     - component: Zeebe-Gateway
-      url: http://{{ .releaseName }}-zeebe-gateway:9600/health
+      url: "{{ .preflightVars.baseURLs.zeebeGateway }}/health"
     method: GET
     url: "{{ .value.url }}"
     retry: 3
@@ -47,9 +48,9 @@ testcases:
     type: http
     range:
     - component: RESTAPI
-      url: http://{{ .releaseName }}-web-modeler-restapi:8091/health/readiness
+      url: "{{ .preflightVars.baseURLs.webModelerRestapi }}/health/readiness"
     - component: WebApp
-      url: http://{{ .releaseName }}-web-modeler-webapp:8071/health/readiness
+      url: "{{ .preflightVars.baseURLs.webModelerWebapp }}/health/readiness"
     method: GET
     url: "{{ .value.url }}"
     retry: 3
@@ -66,23 +67,23 @@ testcases:
     type: http
     range:
     # Dependencies.
-    - component: Keycloak
-      url: http://{{ .releaseName }}-keycloak/auth/realms/camunda-platform
     - component: Elasticsearch
-      url: "http://elasticsearch-master:9200/_cluster/health?wait_for_status=green&timeout=1s"
+      url: "{{ .preflightVars.baseURLs.elasticsearch }}/_cluster/health?wait_for_status=green&timeout=1s"
+    - component: Keycloak
+      url:  "{{ .preflightVars.baseURLs.keycloak }}/auth/realms/camunda-platform"
     # Camunda.
     - component: Identity
-      url: http://{{ .releaseName }}-identity:82/actuator/health
+      url: "{{ .preflightVars.baseURLs.identity }}/actuator/health"
     - component: Optimize
-      url: http://{{ .releaseName }}-optimize/api/readyz
+      url: "{{ .preflightVars.baseURLs.optimize }}/api/readyz"
     - component: Operate
-      url: http://{{ .releaseName }}-operate/actuator/health/liveness
+      url: "{{ .preflightVars.baseURLs.operate }}/actuator/health/liveness"
     - component: Tasklist
-      url: http://{{ .releaseName }}-tasklist/actuator/health/liveness
+      url: "{{ .preflightVars.baseURLs.tasklist }}/actuator/health/liveness"
     - component: Connectors
-      url: http://{{ .releaseName }}-connectors:8080/actuator/health/liveness
+      url: "{{ .preflightVars.baseURLs.connectors }}/actuator/health/liveness"
     - component: Zeebe-Gateway
-      url: http://{{ .releaseName }}-zeebe-gateway:9600/actuator/health/liveness
+      url: "{{ .preflightVars.baseURLs.zeebeGateway }}/actuator/health/liveness"
     method: GET
     url: "{{ .value.url }}"
     retry: 3
@@ -98,9 +99,9 @@ testcases:
     type: http
     range:
     - component: RESTAPI
-      url: http://{{ .releaseName }}-web-modeler-restapi:8091/health/liveness
+      url:  "{{ .preflightVars.baseURLs.webModelerRestapi }}/health/liveness"
     - component: WebApp
-      url: http://{{ .releaseName }}-web-modeler-webapp:8071/health/liveness
+      url:  "{{ .preflightVars.baseURLs.webModelerWebapp }}/health/liveness"
     method: GET
     url: "{{ .value.url }}"
     retry: 3
diff --git a/charts/camunda-platform/test/unit/connectors/deployment_test.go b/charts/camunda-platform/test/unit/connectors/deployment_test.go
index 3f16e91e..713a4bb4 100644
--- a/charts/camunda-platform/test/unit/connectors/deployment_test.go
+++ b/charts/camunda-platform/test/unit/connectors/deployment_test.go
@@ -797,3 +797,34 @@ func (s *deploymentTemplateTest) TestContainerSetContextPath() {
 
 	s.Require().Contains(env, corev1.EnvVar{Name: "SERVER_SERVLET_CONTEXT_PATH", Value: "/connectors"})
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"connectors.sidecars[0].name":                   "nginx",
+			"connectors.sidecars[0].image":                  "nginx:latest",
+			"connectors.sidecars[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.Containers
+	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/identity/deployment_test.go b/charts/camunda-platform/test/unit/identity/deployment_test.go
index b6b32239..a1224ea6 100644
--- a/charts/camunda-platform/test/unit/identity/deployment_test.go
+++ b/charts/camunda-platform/test/unit/identity/deployment_test.go
@@ -95,6 +95,24 @@ func (s *deploymentTemplateTest) TestContainerWithExternalKeycloak() {
 		})
 }
 
+func (s *deploymentTemplateTest) TestContainerSetPodLabels() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"identity.podLabels.foo": "bar",
+		},
+		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
+	s.Require().Equal("bar", deployment.Spec.Template.Labels["foo"])
+}
+
 func (s *deploymentTemplateTest) TestContainerSetPodAnnotations() {
 	// given
 	options := &helm.Options{
@@ -954,3 +972,63 @@ func (s *deploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"identity.sidecars[0].name":                   "nginx",
+			"identity.sidecars[0].image":                  "nginx:latest",
+			"identity.sidecars[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.Containers
+	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{
+		SetValues: map[string]string{
+			"identity.firstUser.existingSecret": "identityFirstUserSecret",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+		ExtraArgs:      map[string][]string{"template": {"--debug"}, "install": {"--debug"}},
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	env := deployment.Spec.Template.Spec.Containers[0].Env
+	s.Require().Contains(env,
+		corev1.EnvVar{
+			Name: "KEYCLOAK_USERS_0_PASSWORD",
+			ValueFrom: &corev1.EnvVarSource{
+				SecretKeyRef: &corev1.SecretKeySelector{
+					LocalObjectReference: corev1.LocalObjectReference{Name: "identityFirstUserSecret"},
+					Key:                  "identity-firstuser-password",
+				},
+			},
+		})
+}
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 f73b34c5..9c40d19b 100644
--- a/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml
+++ b/charts/camunda-platform/test/unit/identity/golden/deployment.golden.yaml
@@ -42,20 +42,6 @@ spec:
         image: "camunda/identity:8.2.5"
         imagePullPolicy: IfNotPresent
         env:
-          - name: KEYCLOAK_USERS_0_USERNAME
-            value: "demo"
-          - name: KEYCLOAK_USERS_0_PASSWORD
-            value: "demo"
-          - name: KEYCLOAK_USERS_0_EMAIL
-            value: "demo@example.org"
-          - name: KEYCLOAK_USERS_0_FIRST_NAME
-            value: "Demo"
-          - name: KEYCLOAK_USERS_0_LAST_NAME
-            value: "User"
-          - name: KEYCLOAK_USERS_0_ROLES_0
-            value: "Identity"
-          - name: KEYCLOAK_USERS_0_ROLES_1
-            value: "Operate"
           - name: KEYCLOAK_INIT_OPERATE_SECRET
             valueFrom:
               secretKeyRef:
@@ -63,8 +49,6 @@ spec:
                 key: operate-secret
           - name: KEYCLOAK_INIT_OPERATE_ROOT_URL
             value: "http://localhost:8081"
-          - name: KEYCLOAK_USERS_0_ROLES_2
-            value: "Tasklist"
           - name: KEYCLOAK_INIT_TASKLIST_SECRET
             valueFrom:
               secretKeyRef:
@@ -72,8 +56,6 @@ spec:
                 key: tasklist-secret
           - name: KEYCLOAK_INIT_TASKLIST_ROOT_URL
             value: "http://localhost:8082"
-          - name: KEYCLOAK_USERS_0_ROLES_3
-            value: "Optimize"
           - name: KEYCLOAK_INIT_OPTIMIZE_SECRET
             valueFrom:
               secretKeyRef:
@@ -81,8 +63,6 @@ spec:
                 key: optimize-secret
           - name: KEYCLOAK_INIT_OPTIMIZE_ROOT_URL
             value: "http://localhost:8083"
-          - name: KEYCLOAK_USERS_0_ROLES_4
-            value: "Web Modeler"
           - name: KEYCLOAK_INIT_WEBMODELER_ROOT_URL
             value: "http://localhost:8084"
           - name: KEYCLOAK_INIT_ZEEBE_NAME
@@ -136,6 +116,26 @@ spec:
               secretKeyRef:
                 name: camunda-platform-test-keycloak
                 key: admin-password
+          - name: KEYCLOAK_USERS_0_USERNAME
+            value: "demo"
+          - name: KEYCLOAK_USERS_0_PASSWORD
+            value: "demo"
+          - name: KEYCLOAK_USERS_0_EMAIL
+            value: "demo@example.org"
+          - name: KEYCLOAK_USERS_0_FIRST_NAME
+            value: "Demo"
+          - name: KEYCLOAK_USERS_0_LAST_NAME
+            value: "User"
+          - name: KEYCLOAK_USERS_0_ROLES_0
+            value: "Identity"
+          - name: KEYCLOAK_USERS_0_ROLES_1
+            value: "Operate"
+          - name: KEYCLOAK_USERS_0_ROLES_2
+            value: "Tasklist"
+          - name: KEYCLOAK_USERS_0_ROLES_3
+            value: "Optimize"
+          - name: KEYCLOAK_USERS_0_ROLES_4
+            value: "Web Modeler"
         resources:
           limits:
             cpu: 2000m
diff --git a/charts/camunda-platform/test/unit/operate/deployment_test.go b/charts/camunda-platform/test/unit/operate/deployment_test.go
index a6dcc737..abc1dbc4 100644
--- a/charts/camunda-platform/test/unit/operate/deployment_test.go
+++ b/charts/camunda-platform/test/unit/operate/deployment_test.go
@@ -783,3 +783,34 @@ func (s *deploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/test/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/test/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"operate.sidecars[0].name":                   "nginx",
+			"operate.sidecars[0].image":                  "nginx:latest",
+			"operate.sidecars[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.Containers
+	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/deployment_test.go b/charts/camunda-platform/test/unit/optimize/deployment_test.go
index 8493dbf2..8f02bd40 100644
--- a/charts/camunda-platform/test/unit/optimize/deployment_test.go
+++ b/charts/camunda-platform/test/unit/optimize/deployment_test.go
@@ -757,3 +757,34 @@ func (s *deploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/test/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/test/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"optimize.sidecars[0].name":                   "nginx",
+			"optimize.sidecars[0].image":                  "nginx:latest",
+			"optimize.sidecars[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.Containers
+	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/deployment_test.go b/charts/camunda-platform/test/unit/tasklist/deployment_test.go
index eb36418b..bedaddcf 100644
--- a/charts/camunda-platform/test/unit/tasklist/deployment_test.go
+++ b/charts/camunda-platform/test/unit/tasklist/deployment_test.go
@@ -783,3 +783,34 @@ func (s *deploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/test/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/test/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"tasklist.sidecars[0].name":                   "nginx",
+			"tasklist.sidecars[0].image":                  "nginx:latest",
+			"tasklist.sidecars[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.Containers
+	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_restapi_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
index 9e735d75..01aa9a0f 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
@@ -322,3 +322,36 @@ func (s *restapiDeploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *restapiDeploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                    "true",
+			"webModeler.restapi.mail.fromAddress":                   "example@example.com",
+			"webModeler.restapi.sidecars[0].name":                   "nginx",
+			"webModeler.restapi.sidecars[0].image":                  "nginx:latest",
+			"webModeler.restapi.sidecars[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.Containers
+	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 8028161c..8e028ec4 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
@@ -423,3 +423,36 @@ func (s *webappDeploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *webappDeploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                   "true",
+			"webModeler.restapi.mail.fromAddress":                  "example@example.com",
+			"webModeler.webapp.sidecars[0].name":                   "nginx",
+			"webModeler.webapp.sidecars[0].image":                  "nginx:latest",
+			"webModeler.webapp.sidecars[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.Containers
+	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 4dd4c071..d61f239b 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
@@ -141,3 +141,36 @@ func (s *websocketsDeploymentTemplateTest) TestContainerLivenessProbe() {
 
 	s.Require().Equal("http", probe.TCPSocket.Port.StrVal)
 }
+
+func (s *websocketsDeploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                       "true",
+			"webModeler.restapi.mail.fromAddress":                      "example@example.com",
+			"webModeler.websockets.sidecars[0].name":                   "nginx",
+			"webModeler.websockets.sidecars[0].image":                  "nginx:latest",
+			"webModeler.websockets.sidecars[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.Containers
+	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/configmap-shared.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/configmap-shared.golden.yaml
index d91b65e9..d6735a15 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/configmap-shared.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/configmap-shared.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: web-modeler
   annotations:
     {}
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 67c281dc..ec58b27d 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
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: restapi
   annotations:
     {}
@@ -32,14 +32,14 @@ spec:
         app.kubernetes.io/instance: camunda-platform-test
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/part-of: camunda-platform
-        app.kubernetes.io/version: "8.2.3"
+        app.kubernetes.io/version: "8.2.4"
         app.kubernetes.io/component: restapi
     spec:
       imagePullSecrets:
         []
       containers:
       - name: web-modeler-restapi
-        image: "registry.camunda.cloud/web-modeler-ee/modeler-restapi:8.2.3"
+        image: "registry.camunda.cloud/web-modeler-ee/modeler-restapi:8.2.4"
         imagePullPolicy: IfNotPresent
         env:
           - name: JAVA_OPTIONS
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 dbf8e75b..e84d52d5 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
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: webapp
   annotations:
     {}
@@ -32,14 +32,14 @@ spec:
         app.kubernetes.io/instance: camunda-platform-test
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/part-of: camunda-platform
-        app.kubernetes.io/version: "8.2.3"
+        app.kubernetes.io/version: "8.2.4"
         app.kubernetes.io/component: webapp
     spec:
       imagePullSecrets:
         []
       containers:
       - name: web-modeler-webapp
-        image: "registry.camunda.cloud/web-modeler-ee/modeler-webapp:8.2.3"
+        image: "registry.camunda.cloud/web-modeler-ee/modeler-webapp:8.2.4"
         imagePullPolicy: IfNotPresent
         env:
           - name: NODE_ENV
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 8d290e4b..de2760d9 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
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: websockets
   annotations:
     {}
@@ -32,14 +32,14 @@ spec:
         app.kubernetes.io/instance: camunda-platform-test
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/part-of: camunda-platform
-        app.kubernetes.io/version: "8.2.3"
+        app.kubernetes.io/version: "8.2.4"
         app.kubernetes.io/component: websockets
     spec:
       imagePullSecrets:
         []
       containers:
       - name: web-modeler-websockets
-        image: "registry.camunda.cloud/web-modeler-ee/modeler-websockets:8.2.3"
+        image: "registry.camunda.cloud/web-modeler-ee/modeler-websockets:8.2.4"
         imagePullPolicy: IfNotPresent
         env:
           - name: APP_NAME
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/ingress-all-enabled.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/ingress-all-enabled.golden.yaml
index d5c9ccfd..38ba0081 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/ingress-all-enabled.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/ingress-all-enabled.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: web-modeler
   annotations:
     ingress.kubernetes.io/rewrite-target: /
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/ingress.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/ingress.golden.yaml
index d28f1e55..0fc34c76 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/ingress.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/ingress.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: web-modeler
   annotations:
     ingress.kubernetes.io/rewrite-target: /
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/secret-shared.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/secret-shared.golden.yaml
index fb949567..b6d64c8d 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/secret-shared.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/secret-shared.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: web-modeler
   annotations:
     {}
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/service-restapi.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/service-restapi.golden.yaml
index 46ebd85f..6cecc2c2 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/service-restapi.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/service-restapi.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: restapi
   annotations:
 spec:
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/service-webapp.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/service-webapp.golden.yaml
index 224a4a6f..e9966675 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/service-webapp.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/service-webapp.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: webapp
   annotations:
 spec:
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/service-websockets.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/service-websockets.golden.yaml
index a2558e52..c68989f3 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/service-websockets.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/service-websockets.golden.yaml
@@ -10,7 +10,7 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: websockets
   annotations:
 spec:
diff --git a/charts/camunda-platform/test/unit/web-modeler/golden/serviceaccount.golden.yaml b/charts/camunda-platform/test/unit/web-modeler/golden/serviceaccount.golden.yaml
index 00e6a5cb..e5f5b28f 100644
--- a/charts/camunda-platform/test/unit/web-modeler/golden/serviceaccount.golden.yaml
+++ b/charts/camunda-platform/test/unit/web-modeler/golden/serviceaccount.golden.yaml
@@ -10,5 +10,5 @@ metadata:
     app.kubernetes.io/instance: camunda-platform-test
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: camunda-platform
-    app.kubernetes.io/version: "8.2.3"
+    app.kubernetes.io/version: "8.2.4"
     app.kubernetes.io/component: web-modeler
\ No newline at end of file
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 ce4fa188..43f04c5a 100644
--- a/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go
+++ b/charts/camunda-platform/test/unit/zeebe-gateway/deployment_test.go
@@ -717,3 +717,34 @@ func (s *deploymentTemplateTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/test/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/test/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *deploymentTemplateTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"zeebe-gateway.sidecars[0].name":                   "nginx",
+			"zeebe-gateway.sidecars[0].image":                  "nginx:latest",
+			"zeebe-gateway.sidecars[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.Containers
+	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/zeebe/statefulset_test.go b/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
index 73f970d5..3e784cb8 100644
--- a/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
+++ b/charts/camunda-platform/test/unit/zeebe/statefulset_test.go
@@ -821,3 +821,34 @@ func (s *statefulSetTest) TestContainerProbesWithContextPath() {
 	s.Require().Equal("/test/ready", probe.ReadinessProbe.HTTPGet.Path)
 	s.Require().Equal("/test/live", probe.LivenessProbe.HTTPGet.Path)
 }
+
+func (s *statefulSetTest) TestContainerSetSidecar() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"zeebe.sidecars[0].name":                   "nginx",
+			"zeebe.sidecars[0].image":                  "nginx:latest",
+			"zeebe.sidecars[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
+	podContainers := statefulSet.Spec.Template.Spec.Containers
+	expectedContainer := corev1.Container{
+		Name:  "nginx",
+		Image: "nginx:latest",
+		Ports: []corev1.ContainerPort{
+			{
+				ContainerPort: 80,
+			},
+		},
+	}
+
+	s.Require().Contains(podContainers, expectedContainer)
+}
diff --git a/charts/camunda-platform/values/values-latest.yaml b/charts/camunda-platform/values/values-latest.yaml
index c3005dc5..04a9a26d 100644
--- a/charts/camunda-platform/values/values-latest.yaml
+++ b/charts/camunda-platform/values/values-latest.yaml
@@ -38,7 +38,7 @@ webModeler:
   # registry.camunda.cloud/web-modeler-ee
   image:
     # renovate: datasource=docker depName=camunda/web-modeler lookupName=registry.camunda.cloud/web-modeler-ee/modeler-restapi
-    tag: 8.2.3
+    tag: 8.2.4
 
 #
 # Elasticsearch