diff --git a/flux2/apps/monitoring/loki-release.yaml b/flux2/apps/monitoring/loki-release.yaml
index ce04d3cb0dbe0542bf25baa2e0324cf12b13a188..eb50dd8f72de559b53a12331ca388695e533f139 100644
--- a/flux2/apps/monitoring/loki-release.yaml
+++ b/flux2/apps/monitoring/loki-release.yaml
@@ -23,6 +23,7 @@ spec:
   valuesFrom:
     - kind: ConfigMap
       name: oas-loki-values
+      optional: false
     # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-loki-override
diff --git a/flux2/apps/rocketchat/kustomization.yaml b/flux2/apps/rocketchat/kustomization.yaml
index 069d8f57139ea83383286ae8c3f02c0bdb2552d2..835ce5fef882f0aa6d74f2ca52346df2cd028acf 100644
--- a/flux2/apps/rocketchat/kustomization.yaml
+++ b/flux2/apps/rocketchat/kustomization.yaml
@@ -3,3 +3,4 @@ kind: Kustomization
 namespace: oas-apps
 resources:
   - release.yaml
+  - rocketchat-values-configmap.yaml
diff --git a/flux2/apps/rocketchat/release.yaml b/flux2/apps/rocketchat/release.yaml
index 2b66ad935da13e9eed4ee88a054ac3bae779889b..eae7c10f37e266467c9460e6244fc3ecd227d432 100644
--- a/flux2/apps/rocketchat/release.yaml
+++ b/flux2/apps/rocketchat/release.yaml
@@ -17,130 +17,11 @@ spec:
   interval: 1h
   install:
     timeout: 15m
-  values:
-    # Hostname for Rocket.chat
-    host: "chat.${domain}"
-
-    # Extra environment variables for Rocket.Chat. Used with tpl function, so this
-    # needs to be a string
-    extraEnv: |
-      - name: ADMIN_USERNAME
-        value: admin
-      - name: ADMIN_PASS
-        value: "${rocketchat_admin_password}"
-      - name: ADMIN_EMAIL
-        value: "${admin_email}"
-        # Set setup wizard to completed. The setup wizard, that allows you to
-        # create a different admin user, gets skipped.
-      - name: OVERWRITE_SETTING_Show_Setup_Wizard
-        value: completed
-      - name: E2E_Enable
-        value: "true"
-      - name: Accounts_RegistrationForm
-        value: Disabled
-      - name: Accounts_RegistrationForm_LinkReplacementText
-        value: "Create a new account at admin.${domain} to add users"
-      # Custom OAuth rules:
-      - name: Accounts_OAuth_Custom_Openappstack
-        value: "true"
-      - name: Accounts_OAuth_Custom_Openappstack_url
-        value: https://sso.${domain}
-      - name: Accounts_OAuth_Custom_Openappstack_token_path
-        value: /oauth2/token
-      - name: Accounts_OAuth_Custom_Openappstack_token_sent_via
-        value: payload
-      - name: Accounts_OAuth_Custom_Openappstack_identity_token_sent_via
-        value: payload
-      - name: Accounts_OAuth_Custom_Openappstack_identity_path
-        value: /userinfo
-      - name: Accounts_OAuth_Custom_Openappstack_authorize_path
-        value: /oauth2/auth
-      - name: Accounts_OAuth_Custom_Openappstack_scope
-        value: openid profile openappstack_roles email
-      - name: Accounts_OAuth_Custom_Openappstack_id
-        value: rocketchat
-      - name: Accounts_OAuth_Custom_Openappstack_secret
-        value: ${rocketchat_oauth_client_secret}
-      - name: Accounts_OAuth_Custom_Openappstack_login_style
-        value: redirect
-      - name: Accounts_OAuth_Custom_Openappstack_button_label_text
-        value: Login via OpenAppStack
-      - name: Accounts_OAuth_Custom_Openappstack_button_label_color
-        value: "#FFFFFF"
-      - name: Accounts_OAuth_Custom_Openappstack_button_color
-        value: "#1d74f5"
-      - name: Accounts_OAuth_Custom_Openappstack_username_field
-        value: preferred_username
-      - name: Accounts_OAuth_Custom_Openappstack_name_field
-        value: preferred_username
-      - name: Accounts_OAuth_Custom_Openappstack_roles_claim
-        value: openappstack_roles
-      - name: Accounts_OAuth_Custom_Openappstack_merge_roles
-        value: "true"
-      - name: Accounts_OAuth_Custom_Openappstack_merge_users
-        value: "true"
-      - name: Accounts_OAuth_Custom_Openappstack_show_button
-        value: "true"
-
-    livenessProbe:
-      initialDelaySeconds: 180
-      failureThreshold: 20
-    readinessProbe:
-      initialDelaySeconds: 60
-      timeoutSeconds: 10
-
-    ingress:
-      enabled: true
-      annotations:
-        # Tell cert-manager to automatically get a TLS certificate
-        kubernetes.io/tls-acme: "true"
-      tls:
-        - hosts:
-            - "chat.${domain}"
-          secretName: oas-rocketchat
-
-    persistence:
-      enabled: true
-      size: 1Gi
-      # FIXME: This valuee leads to an unused PVC, which helm-controller does
-      # not like.
-      # existingClaim: "rocketchat-data"
-
-    podAnnotations:
-      # Let the backup system include rocketchat data.
-      backup.velero.io/backup-volumes: "rocket-data"
-
-    resources:
-      limits:
-        cpu: 400m
-        memory: 1024Mi
-      requests:
-        cpu: 100m
-        memory: 768Mi
-
-    mongodb:
-      mongodbRootPassword: ${mongodb_root_password}
-      mongodbPassword: ${mongodb_password}
-      podAnnotations:
-        # Let the backup system include rocketchat data stored in mongodb.
-        backup.velero.io/backup-volumes: "datadir"
-      persistence:
-        enabled: true
-        # FIXME: This value is ignored by the chart currently in use
-        # existingClaim: "rocketchat-mongodb"
-      resources:
-        limits:
-          cpu: 600m
-          memory: 1024Mi
-        requests:
-          cpu: 300m
-          memory: 768Mi
-
-    image:
-      tag: 3.15.0
-      pullPolicy: IfNotPresent
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-rocketchat-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-rocketchat-override
       optional: true
diff --git a/flux2/apps/rocketchat/rocketchat-values-configmap.yaml b/flux2/apps/rocketchat/rocketchat-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..100c94221daaa1fa01e4d589e29a60b2261ded42
--- /dev/null
+++ b/flux2/apps/rocketchat/rocketchat-values-configmap.yaml
@@ -0,0 +1,128 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-rocketchat-values
+data:
+  values.yaml: |
+    # Hostname for Rocket.chat
+    host: "chat.${domain}"
+
+    # Extra environment variables for Rocket.Chat. Used with tpl function, so this
+    # needs to be a string
+    extraEnv: |
+      - name: ADMIN_USERNAME
+        value: admin
+      - name: ADMIN_PASS
+        value: "${rocketchat_admin_password}"
+      - name: ADMIN_EMAIL
+        value: "${admin_email}"
+        # Set setup wizard to completed. The setup wizard, that allows you to
+        # create a different admin user, gets skipped.
+      - name: OVERWRITE_SETTING_Show_Setup_Wizard
+        value: completed
+      - name: E2E_Enable
+        value: "true"
+      - name: Accounts_RegistrationForm
+        value: Disabled
+      - name: Accounts_RegistrationForm_LinkReplacementText
+        value: "Create a new account at admin.${domain} to add users"
+      # Custom OAuth rules:
+      - name: Accounts_OAuth_Custom_Openappstack
+        value: "true"
+      - name: Accounts_OAuth_Custom_Openappstack_url
+        value: https://sso.${domain}
+      - name: Accounts_OAuth_Custom_Openappstack_token_path
+        value: /oauth2/token
+      - name: Accounts_OAuth_Custom_Openappstack_token_sent_via
+        value: payload
+      - name: Accounts_OAuth_Custom_Openappstack_identity_token_sent_via
+        value: payload
+      - name: Accounts_OAuth_Custom_Openappstack_identity_path
+        value: /userinfo
+      - name: Accounts_OAuth_Custom_Openappstack_authorize_path
+        value: /oauth2/auth
+      - name: Accounts_OAuth_Custom_Openappstack_scope
+        value: openid profile openappstack_roles email
+      - name: Accounts_OAuth_Custom_Openappstack_id
+        value: rocketchat
+      - name: Accounts_OAuth_Custom_Openappstack_secret
+        value: ${rocketchat_oauth_client_secret}
+      - name: Accounts_OAuth_Custom_Openappstack_login_style
+        value: redirect
+      - name: Accounts_OAuth_Custom_Openappstack_button_label_text
+        value: Login via OpenAppStack
+      - name: Accounts_OAuth_Custom_Openappstack_button_label_color
+        value: "#FFFFFF"
+      - name: Accounts_OAuth_Custom_Openappstack_button_color
+        value: "#1d74f5"
+      - name: Accounts_OAuth_Custom_Openappstack_username_field
+        value: preferred_username
+      - name: Accounts_OAuth_Custom_Openappstack_name_field
+        value: preferred_username
+      - name: Accounts_OAuth_Custom_Openappstack_roles_claim
+        value: openappstack_roles
+      - name: Accounts_OAuth_Custom_Openappstack_merge_roles
+        value: "true"
+      - name: Accounts_OAuth_Custom_Openappstack_merge_users
+        value: "true"
+      - name: Accounts_OAuth_Custom_Openappstack_show_button
+        value: "true"
+
+    livenessProbe:
+      initialDelaySeconds: 180
+      failureThreshold: 20
+    readinessProbe:
+      initialDelaySeconds: 60
+      timeoutSeconds: 10
+
+    ingress:
+      enabled: true
+      annotations:
+        # Tell cert-manager to automatically get a TLS certificate
+        kubernetes.io/tls-acme: "true"
+      tls:
+        - hosts:
+            - "chat.${domain}"
+          secretName: oas-rocketchat
+
+    persistence:
+      enabled: true
+      size: 1Gi
+      # FIXME: This valuee leads to an unused PVC, which helm-controller does
+      # not like.
+      # existingClaim: "rocketchat-data"
+
+    podAnnotations:
+      # Let the backup system include rocketchat data.
+      backup.velero.io/backup-volumes: "rocket-data"
+
+    resources:
+      limits:
+        cpu: 400m
+        memory: 1024Mi
+      requests:
+        cpu: 100m
+        memory: 768Mi
+
+    mongodb:
+      mongodbRootPassword: ${mongodb_root_password}
+      mongodbPassword: ${mongodb_password}
+      podAnnotations:
+        # Let the backup system include rocketchat data stored in mongodb.
+        backup.velero.io/backup-volumes: "datadir"
+      persistence:
+        enabled: true
+        # FIXME: This value is ignored by the chart currently in use
+        # existingClaim: "rocketchat-mongodb"
+      resources:
+        limits:
+          cpu: 600m
+          memory: 1024Mi
+        requests:
+          cpu: 300m
+          memory: 768Mi
+
+    image:
+      tag: 3.15.0
+      pullPolicy: IfNotPresent
diff --git a/flux2/apps/velero/kustomization.yaml b/flux2/apps/velero/kustomization.yaml
index c95bcc7fb349532335c453bf595c13382f90e416..4e1d68a9f2b2d6d82bcbe76b572e5cbdce200ffe 100644
--- a/flux2/apps/velero/kustomization.yaml
+++ b/flux2/apps/velero/kustomization.yaml
@@ -3,4 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
 kind: Kustomization
 namespace: velero
 resources:
-  - release.yaml
\ No newline at end of file
+  - release.yaml
+  - velero-values-configmap.yaml
diff --git a/flux2/apps/velero/release.yaml b/flux2/apps/velero/release.yaml
index 3b8dacccad44fa2c2a608f48cf023519605034df..99ccf81b6f60c756a39bf8be29155499c82f4a8c 100644
--- a/flux2/apps/velero/release.yaml
+++ b/flux2/apps/velero/release.yaml
@@ -15,117 +15,11 @@ spec:
         name: vmware-tanzu
         namespace: flux-system
   interval: 1h
-  values:
-    # Init containers to add to the Velero deployment's pod spec. At least one
-    # plugin provider image is required.
-    initContainers:
-      - name: velero-plugin-for-aws
-        image: velero/velero-plugin-for-aws:v1.1.0
-        imagePullPolicy: IfNotPresent
-        volumeMounts:
-          - mountPath: /target
-            name: plugins
-
-    # Settings for Velero's prometheus metrics. Enabled by default.
-    metrics:
-      enabled: true
-      scrapeInterval: 30s
-
-      # Pod annotations for Prometheus
-      podAnnotations:
-        prometheus.io/scrape: "true"
-        prometheus.io/port: "8085"
-        prometheus.io/path: "/metrics"
-
-      serviceMonitor:
-        enabled: false
-        additionalLabels: {}
-
-    # Install CRDs as a templates. Enabled by default.
-    installCRDs: true
-
-    ##
-    ## Parameters for the `default` BackupStorageLocation and VolumeSnapshotLocation,
-    ## and additional server settings.
-    ##
-    configuration:
-      # Cloud provider being used (e.g. aws, azure, gcp).
-      # We don't use aws, but ceph which is S3-compatible.
-      provider: aws
-
-      # Parameters for the `default` BackupStorageLocation. See
-      # https://velero.io/docs/v1.0.0/api-types/backupstoragelocation/
-      backupStorageLocation:
-        # Cloud provider where backups should be stored. Usually should
-        # match `configuration.provider`. Required.
-        # The name "default" seems to be special: backups that don't have a
-        # location specified will use this one.
-        name: default
-        # Provider for the backup storage location. If omitted
-        # `configuration.provider` will be used instead.
-        # provider:
-        # Bucket to store backups in. Required.
-        bucket: ${backup_s3_bucket}
-        # Prefix within bucket under which to store backups. Optional.
-        prefix: ${backup_s3_prefix}
-        # Additional provider-specific configuration. See link above
-        # for details of required/optional fields for your provider.
-        config:
-          s3ForcePathStyle: true
-          s3Url: ${backup_s3_url}
-          region: ${backup_s3_region}
-
-    rbac:
-      # Whether to create the Velero role and role binding to give all permissions to the namespace to Velero.
-      create: true
-      # Whether to create the cluster role binding to give administrator permissions to Velero
-      clusterAdministrator: true
-
-    # Information about the Kubernetes service account Velero uses.
-    serviceAccount:
-      server:
-        create: true
-        name:
-        annotations:
-
-    # Info about the secret to be used by the Velero deployment, which
-    # should contain credentials for the cloud provider IAM account you've
-    # set up for Velero.
-    credentials:
-      useSecret: true
-      secretContents:
-        cloud: |
-          [default]
-          aws_access_key_id=${backup_s3_aws_access_key_id}
-          aws_secret_access_key=${backup_s3_aws_secret_access_key}
-
-    # Whether to create backupstoragelocation crd, if false => do not create a default backup location
-    backupsEnabled: true
-    # Whether to create volumesnapshotlocation crd, if false => disable snapshot feature
-    snapshotsEnabled: false
-
-    # Whether to deploy the restic daemonset.
-    deployRestic: true
-
-    restic:
-      podVolumePath: /var/lib/kubelet/pods
-      privileged: true
-
-    # Backup schedules to create.
-    schedules:
-      # This is just a name, can be anything.
-      nightly:
-        # Every night at 3:30.
-        schedule: "30 3 * * *"
-        template:
-          # Backups are stored for 60 days (1440 hours).
-          ttl: "1440h"
-          includedNamespaces:
-            # We include all namespaces.
-            - '*'
-    configMaps: {}
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-velero-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-velero-override
       optional: true
diff --git a/flux2/apps/velero/velero-values-configmap.yaml b/flux2/apps/velero/velero-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a7b4637a25592c5bc5a7a0d7c6e2a045bb69f199
--- /dev/null
+++ b/flux2/apps/velero/velero-values-configmap.yaml
@@ -0,0 +1,116 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-velero-values
+data:
+  values.yaml: |
+    # Init containers to add to the Velero deployment's pod spec. At least one
+    # plugin provider image is required.
+    initContainers:
+      - name: velero-plugin-for-aws
+        image: velero/velero-plugin-for-aws:v1.1.0
+        imagePullPolicy: IfNotPresent
+        volumeMounts:
+          - mountPath: /target
+            name: plugins
+
+    # Settings for Velero's prometheus metrics. Enabled by default.
+    metrics:
+      enabled: true
+      scrapeInterval: 30s
+
+      # Pod annotations for Prometheus
+      podAnnotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "8085"
+        prometheus.io/path: "/metrics"
+
+      serviceMonitor:
+        enabled: false
+        additionalLabels: {}
+
+    # Install CRDs as a templates. Enabled by default.
+    installCRDs: true
+
+    ##
+    ## Parameters for the `default` BackupStorageLocation and VolumeSnapshotLocation,
+    ## and additional server settings.
+    ##
+    configuration:
+      # Cloud provider being used (e.g. aws, azure, gcp).
+      # We don't use aws, but ceph which is S3-compatible.
+      provider: aws
+
+      # Parameters for the `default` BackupStorageLocation. See
+      # https://velero.io/docs/v1.0.0/api-types/backupstoragelocation/
+      backupStorageLocation:
+        # Cloud provider where backups should be stored. Usually should
+        # match `configuration.provider`. Required.
+        # The name "default" seems to be special: backups that don't have a
+        # location specified will use this one.
+        name: default
+        # Provider for the backup storage location. If omitted
+        # `configuration.provider` will be used instead.
+        # provider:
+        # Bucket to store backups in. Required.
+        bucket: ${backup_s3_bucket}
+        # Prefix within bucket under which to store backups. Optional.
+        prefix: ${backup_s3_prefix}
+        # Additional provider-specific configuration. See link above
+        # for details of required/optional fields for your provider.
+        config:
+          s3ForcePathStyle: true
+          s3Url: ${backup_s3_url}
+          region: ${backup_s3_region}
+
+    rbac:
+      # Whether to create the Velero role and role binding to give all permissions to the namespace to Velero.
+      create: true
+      # Whether to create the cluster role binding to give administrator permissions to Velero
+      clusterAdministrator: true
+
+    # Information about the Kubernetes service account Velero uses.
+    serviceAccount:
+      server:
+        create: true
+        name:
+        annotations:
+
+    # Info about the secret to be used by the Velero deployment, which
+    # should contain credentials for the cloud provider IAM account you've
+    # set up for Velero.
+    credentials:
+      useSecret: true
+      secretContents:
+        cloud: |
+          [default]
+          aws_access_key_id=${backup_s3_aws_access_key_id}
+          aws_secret_access_key=${backup_s3_aws_secret_access_key}
+
+    # Whether to create backupstoragelocation crd, if false => do not create a default backup location
+    backupsEnabled: true
+    # Whether to create volumesnapshotlocation crd, if false => disable snapshot feature
+    snapshotsEnabled: false
+
+    # Whether to deploy the restic daemonset.
+    deployRestic: true
+
+    restic:
+      podVolumePath: /var/lib/kubelet/pods
+      privileged: true
+
+    # Backup schedules to create.
+    schedules:
+      # This is just a name, can be anything.
+      nightly:
+        # Every night at 3:30.
+        schedule: "30 3 * * *"
+        template:
+          # Backups are stored for 60 days (1440 hours).
+          ttl: "1440h"
+          includedNamespaces:
+            # We include all namespaces.
+            - '*'
+    configMaps: {}
+
diff --git a/flux2/core/base/metallb/kustomization.yaml b/flux2/core/base/metallb/kustomization.yaml
index 7d7b5c99318ef59fef86864ceed84f23b0fa4c63..9b688834cf7675e3856db45570dfc5790281c838 100644
--- a/flux2/core/base/metallb/kustomization.yaml
+++ b/flux2/core/base/metallb/kustomization.yaml
@@ -4,3 +4,4 @@ kind: Kustomization
 namespace: kube-system
 resources:
   - release.yaml
+  - metallb-values-configmap.yaml
diff --git a/flux2/core/base/metallb/metallb-values-configmap.yaml b/flux2/core/base/metallb/metallb-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..22db3b569100952fad120063c0c997aca470a298
--- /dev/null
+++ b/flux2/core/base/metallb/metallb-values-configmap.yaml
@@ -0,0 +1,15 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-metallb-values
+data:
+  values.yaml: |
+    # https://artifacthub.io/packages/helm/bitnami/metallb#example-layer-2-configuration
+    configInline:
+      address-pools:
+        - name: default
+          protocol: layer2
+          addresses:
+            - "${ip_address}/32"
+
diff --git a/flux2/core/base/metallb/release.yaml b/flux2/core/base/metallb/release.yaml
index d190242dbde3a73436f936a5a44d08aa5db9a5f3..b154b267d0afbb63699243efb945797a387d5029 100644
--- a/flux2/core/base/metallb/release.yaml
+++ b/flux2/core/base/metallb/release.yaml
@@ -18,16 +18,11 @@ spec:
   interval: 1h
   install:
     timeout: 2m
-  values:
-    # https://artifacthub.io/packages/helm/bitnami/metallb#example-layer-2-configuration
-    configInline:
-      address-pools:
-        - name: default
-          protocol: layer2
-          addresses:
-            - "${ip_address}/32"
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-metallb-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-metallb-override
       optional: true
diff --git a/flux2/core/base/nginx/kustomization.yaml b/flux2/core/base/nginx/kustomization.yaml
index 9045cb5d9036f1e5a9941aefde526fa8ce35e870..5624efc1cc23587798ec3f79c24072c1eab86f3e 100644
--- a/flux2/core/base/nginx/kustomization.yaml
+++ b/flux2/core/base/nginx/kustomization.yaml
@@ -4,3 +4,4 @@ kind: Kustomization
 namespace: oas
 resources:
   - release.yaml
+  - nginx-values-configmap.yaml
diff --git a/flux2/core/base/nginx/nginx-values-configmap b/flux2/core/base/nginx/nginx-values-configmap
new file mode 100644
index 0000000000000000000000000000000000000000..28097c496144d7c2f9c4850d9d4f3072f9fd91e9
--- /dev/null
+++ b/flux2/core/base/nginx/nginx-values-configmap
@@ -0,0 +1,30 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-nginx-values
+data:
+  values.yaml: |
+    # https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
+    controller:
+      image:
+        # Disable image digest validation until flux supports it
+        # https://github.com/fluxcd/flux/issues/3189
+        digest: ''
+      service:
+        ## Set external traffic policy to: "Local" to preserve source IP on
+        ## providers supporting it
+        ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer
+        externalTrafficPolicy: Local
+      config:
+        # http://nginx.org/en/docs/http/ngx_http_access_module.html
+        # comma separated list of CIDRs, e.g. 10.0.0.0/24,172.10.0.1.
+        # By default we allow all access from everywhere
+        whitelist-source-range: '0.0.0.0/0'
+      resources:
+        limits:
+          cpu: 200m
+          memory: 1Gi
+        requests:
+          cpu: 100m
+          memory: 64Mi
diff --git a/flux2/core/base/nginx/release.yaml b/flux2/core/base/nginx/release.yaml
index 7647c14e912a5e75d9a4f47425289e97c8f46e58..48aff56591d1a2ada22ebb74ddebb15195b000dc 100644
--- a/flux2/core/base/nginx/release.yaml
+++ b/flux2/core/base/nginx/release.yaml
@@ -22,31 +22,11 @@ spec:
   dependsOn:
     - name: metallb
       namespace: kube-system
-  values:
-    controller:
-      image:
-        # Disable image digest validation until flux supports it
-        # https://github.com/fluxcd/flux/issues/3189
-        digest: ''
-      service:
-        ## Set external traffic policy to: "Local" to preserve source IP on
-        ## providers supporting it
-        ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer
-        externalTrafficPolicy: Local
-      config:
-        # http://nginx.org/en/docs/http/ngx_http_access_module.html
-        # comma separated list of CIDRs, e.g. 10.0.0.0/24,172.10.0.1.
-        # By default we allow all access from everywhere
-        whitelist-source-range: '0.0.0.0/0'
-      resources:
-        limits:
-          cpu: 200m
-          memory: 1Gi
-        requests:
-          cpu: 100m
-          memory: 64Mi
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-nginx-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-nginx-override
       optional: true
diff --git a/flux2/core/base/single-sign-on/kustomization.yaml b/flux2/core/base/single-sign-on/kustomization.yaml
index 20d46f714a48a613245321382e6a5f319f820f6f..fc3b4afe5a00adc3e0ef7d989fe019cd1f06078d 100644
--- a/flux2/core/base/single-sign-on/kustomization.yaml
+++ b/flux2/core/base/single-sign-on/kustomization.yaml
@@ -4,4 +4,5 @@ kind: Kustomization
 namespace: oas
 resources:
   - pvc.yaml
-  - release.yaml
\ No newline at end of file
+  - release.yaml
+  - single-sign-on-values-configmap.yaml
diff --git a/flux2/core/base/single-sign-on/release.yaml b/flux2/core/base/single-sign-on/release.yaml
index 93e5e45a3c521cbe0354ac4f920a1293f0435f5e..364ee3b1e6036b66052931aa1bb26109ff39e3f9 100644
--- a/flux2/core/base/single-sign-on/release.yaml
+++ b/flux2/core/base/single-sign-on/release.yaml
@@ -19,154 +19,10 @@ spec:
   install:
     remediation:
       retries: 3
-  values:
-    singleSignOnHost: &SSO_HOST "sso.${domain}"
-
-    userpanel:
-      applicationName: &USER_PANEL user-panel
-      ingress:
-        host: "admin.${domain}"
-
-    userbackend:
-      applications:
-        - name: *USER_PANEL
-          description: Administration interface to manage user accounts
-        - name: &NEXTCLOUD nextcloud
-          description: "Nextcloud Files offers an on-premise Universal File Access and sync platform with powerful collaboration capabilities and desktop, mobile and web interfaces."
-        - name: &WORDPRESS wordpress
-          description: "WordPress website hosting."
-        - name: &ROCKETCHAT rocketchat
-          description: "Communicate and collaborate using team chat and switch to video or audio calls with screen sharing for more efficient teamwork."
-        - name: &GRAFANA grafana
-          description: "Grafana allows you to query, visualize, alert on and understand metrics generated by OpenAppStack. It can be used to create explore and share dashboards."
-        - name: &WEKAN wekan
-          description: "Wekan Kanban board."
-      username: "${userbackend_admin_username}"
-      password: "${userbackend_admin_password}"
-      email: "${admin_email}"
-      postgres:
-        password: "${userbackend_postgres_password}"
-      persistence:
-        enabled: true
-        size: 1Gi
-        existingClaim: single-sign-on-userbackend
-      podAnnotations:
-        # Let the backup system include nextcloud database data.
-        backup.velero.io/backup-volumes: "database"
-
-    hydra:
-      hydra:
-        config:
-          urls:
-            self:
-              issuer: "https://sso.${domain}"
-            login: "https://sso.${domain}/login"
-            consent: "https://sso.${domain}/consent"
-          secrets:
-            system: "${hydra_system_secret}"
-          dsn: "memory"
-      ingress:
-        public:
-          enabled: true
-          annotations:
-            kubernetes.io/tls-acme: "true"
-          hosts:
-            - host: *SSO_HOST
-              paths: ["/"]
-          tls:
-            - hosts:
-              - *SSO_HOST
-              secretName: hydra-public.tls
-        admin:
-          enabled: false
-
-    oAuthClients:
-    - clientName: *USER_PANEL
-      clientSecret: "${userpanel_oauth_client_secret}"
-      redirectUri: "https://admin.${domain}/callback"
-      scopes: "openid profile email openappstack_roles"
-      clientUri: "https://admin.${domain}"
-      clientLogoUri: "https://admin.${domain}/favicon.ico"
-      tokenEndpointAuthMethod: "client_secret_basic"
-      responseTypes:
-        - "token"
-      grantTypes:
-        - "implicit"
-    - clientName: *NEXTCLOUD
-      clientSecret: "${nextcloud_oauth_client_secret}"
-      redirectUri: "https://files.${domain}/apps/sociallogin/custom_oidc/oas"
-      scopes: "openid profile email openappstack_roles"
-      clientUri: "https://files.${domain}"
-      clientLogoUri: "https://files.${domain}/core/img/favicon-touch.png"
-      tokenEndpointAuthMethod: "client_secret_post"
-      responseTypes:
-        - "code"
-        - "id_token"
-      grantTypes:
-        - "authorization_code"
-        - "refresh_token"
-        - "client_credentials"
-    - clientName: *WORDPRESS
-      clientSecret: "${wordpress_oauth_client_secret}"
-      redirectUri: "https://www.${domain}/wp-admin/admin-ajax.php?action=openid-connect-authorize"
-      scopes: "openid profile email openappstack_roles offline_access"
-      clientUri: "https://www.${domain}"
-      clientLogoUri: "https://www.${domain}/wp-admin/images/wordpress-logo.svg"
-      tokenEndpointAuthMethod: "client_secret_post"
-      responseTypes:
-        - "code"
-        - "id_token"
-      grantTypes:
-        - "authorization_code"
-        - "refresh_token"
-        - "client_credentials"
-        - "implicit"
-    - clientName: *ROCKETCHAT
-      clientSecret: "${rocketchat_oauth_client_secret}"
-      redirectUri: "https://chat.${domain}/_oauth/openappstack"
-      scopes: "openid profile email openappstack_roles"
-      clientUri: "https://chat.${domain}"
-      clientLogoUri: "https://chat.${domain}/images/logo/logo.svg"
-      tokenEndpointAuthMethod: "client_secret_post"
-      responseTypes:
-        - "code"
-        - "id_token"
-      grantTypes:
-        - "authorization_code"
-        - "refresh_token"
-        - "client_credentials"
-    - clientName: *GRAFANA
-      clientSecret: "${grafana_oauth_client_secret}"
-      redirectUri: "https://grafana.${domain}/login/generic_oauth"
-      scopes: "openid profile email openappstack_roles"
-      clientUri: "https://grafana.${domain}"
-      clientLogoUri: "https://grafana.${domain}/public/img/grafana_icon.svg"
-      tokenEndpointAuthMethod: "client_secret_post"
-      responseTypes:
-        - "code"
-        - "id_token"
-      grantTypes:
-        - "authorization_code"
-        - "refresh_token"
-        - "client_credentials"
-    # https://github.com/wekan/wekan/wiki/Keycloak
-    - clientName: *WEKAN
-      clientSecret: "${wekan_oauth_client_secret}"
-      redirectUri: "https://wekan.${domain}/_oauth/oidc"
-      scopes: "openid profile email"
-      clientUri: "https://wekan.${domain}"
-      clientLogoUri: "https://wekan.${domain}/wekan-logo.svg"
-      tokenEndpointAuthMethod: "client_secret_post"
-      responseTypes:
-        - "code"
-        - "id_token"
-      grantTypes:
-        - "authorization_code"
-        - "refresh_token"
-        - "client_credentials"
-        - "implicit"
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-single-sign-on-values
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-single-sign-on-override
       optional: true
diff --git a/flux2/core/base/single-sign-on/single-sign-on-values-configmap.yaml b/flux2/core/base/single-sign-on/single-sign-on-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..689719a80dbf36ea8b70460599d16f8f522efe11
--- /dev/null
+++ b/flux2/core/base/single-sign-on/single-sign-on-values-configmap.yaml
@@ -0,0 +1,152 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-single-sign-on-values
+data:
+  values.yaml: |
+    singleSignOnHost: &SSO_HOST "sso.${domain}"
+
+    userpanel:
+      applicationName: &USER_PANEL user-panel
+      ingress:
+        host: "admin.${domain}"
+
+    userbackend:
+      applications:
+        - name: *USER_PANEL
+          description: Administration interface to manage user accounts
+        - name: &NEXTCLOUD nextcloud
+          description: "Nextcloud Files offers an on-premise Universal File Access and sync platform with powerful collaboration capabilities and desktop, mobile and web interfaces."
+        - name: &WORDPRESS wordpress
+          description: "WordPress website hosting."
+        - name: &ROCKETCHAT rocketchat
+          description: "Communicate and collaborate using team chat and switch to video or audio calls with screen sharing for more efficient teamwork."
+        - name: &GRAFANA grafana
+          description: "Grafana allows you to query, visualize, alert on and understand metrics generated by OpenAppStack. It can be used to create explore and share dashboards."
+        - name: &WEKAN wekan
+          description: "Wekan Kanban board."
+      username: "${userbackend_admin_username}"
+      password: "${userbackend_admin_password}"
+      email: "${admin_email}"
+      postgres:
+        password: "${userbackend_postgres_password}"
+      persistence:
+        enabled: true
+        size: 1Gi
+        existingClaim: single-sign-on-userbackend
+      podAnnotations:
+        # Let the backup system include nextcloud database data.
+        backup.velero.io/backup-volumes: "database"
+
+    hydra:
+      hydra:
+        config:
+          urls:
+            self:
+              issuer: "https://sso.${domain}"
+            login: "https://sso.${domain}/login"
+            consent: "https://sso.${domain}/consent"
+          secrets:
+            system: "${hydra_system_secret}"
+          dsn: "memory"
+      ingress:
+        public:
+          enabled: true
+          annotations:
+            kubernetes.io/tls-acme: "true"
+          hosts:
+            - host: *SSO_HOST
+              paths: ["/"]
+          tls:
+            - hosts:
+              - *SSO_HOST
+              secretName: hydra-public.tls
+        admin:
+          enabled: false
+
+    oAuthClients:
+    - clientName: *USER_PANEL
+      clientSecret: "${userpanel_oauth_client_secret}"
+      redirectUri: "https://admin.${domain}/callback"
+      scopes: "openid profile email openappstack_roles"
+      clientUri: "https://admin.${domain}"
+      clientLogoUri: "https://admin.${domain}/favicon.ico"
+      tokenEndpointAuthMethod: "client_secret_basic"
+      responseTypes:
+        - "token"
+      grantTypes:
+        - "implicit"
+    - clientName: *NEXTCLOUD
+      clientSecret: "${nextcloud_oauth_client_secret}"
+      redirectUri: "https://files.${domain}/apps/sociallogin/custom_oidc/oas"
+      scopes: "openid profile email openappstack_roles"
+      clientUri: "https://files.${domain}"
+      clientLogoUri: "https://files.${domain}/core/img/favicon-touch.png"
+      tokenEndpointAuthMethod: "client_secret_post"
+      responseTypes:
+        - "code"
+        - "id_token"
+      grantTypes:
+        - "authorization_code"
+        - "refresh_token"
+        - "client_credentials"
+    - clientName: *WORDPRESS
+      clientSecret: "${wordpress_oauth_client_secret}"
+      redirectUri: "https://www.${domain}/wp-admin/admin-ajax.php?action=openid-connect-authorize"
+      scopes: "openid profile email openappstack_roles offline_access"
+      clientUri: "https://www.${domain}"
+      clientLogoUri: "https://www.${domain}/wp-admin/images/wordpress-logo.svg"
+      tokenEndpointAuthMethod: "client_secret_post"
+      responseTypes:
+        - "code"
+        - "id_token"
+      grantTypes:
+        - "authorization_code"
+        - "refresh_token"
+        - "client_credentials"
+        - "implicit"
+    - clientName: *ROCKETCHAT
+      clientSecret: "${rocketchat_oauth_client_secret}"
+      redirectUri: "https://chat.${domain}/_oauth/openappstack"
+      scopes: "openid profile email openappstack_roles"
+      clientUri: "https://chat.${domain}"
+      clientLogoUri: "https://chat.${domain}/images/logo/logo.svg"
+      tokenEndpointAuthMethod: "client_secret_post"
+      responseTypes:
+        - "code"
+        - "id_token"
+      grantTypes:
+        - "authorization_code"
+        - "refresh_token"
+        - "client_credentials"
+    - clientName: *GRAFANA
+      clientSecret: "${grafana_oauth_client_secret}"
+      redirectUri: "https://grafana.${domain}/login/generic_oauth"
+      scopes: "openid profile email openappstack_roles"
+      clientUri: "https://grafana.${domain}"
+      clientLogoUri: "https://grafana.${domain}/public/img/grafana_icon.svg"
+      tokenEndpointAuthMethod: "client_secret_post"
+      responseTypes:
+        - "code"
+        - "id_token"
+      grantTypes:
+        - "authorization_code"
+        - "refresh_token"
+        - "client_credentials"
+    # https://github.com/wekan/wekan/wiki/Keycloak
+    - clientName: *WEKAN
+      clientSecret: "${wekan_oauth_client_secret}"
+      redirectUri: "https://wekan.${domain}/_oauth/oidc"
+      scopes: "openid profile email"
+      clientUri: "https://wekan.${domain}"
+      clientLogoUri: "https://wekan.${domain}/wekan-logo.svg"
+      tokenEndpointAuthMethod: "client_secret_post"
+      responseTypes:
+        - "code"
+        - "id_token"
+      grantTypes:
+        - "authorization_code"
+        - "refresh_token"
+        - "client_credentials"
+        - "implicit"
diff --git a/flux2/infrastructure/cert-manager/cert-manager-values-configmap.yaml b/flux2/infrastructure/cert-manager/cert-manager-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..59a26bcc886d944d5e2b6c34b1cc54ae437e96e2
--- /dev/null
+++ b/flux2/infrastructure/cert-manager/cert-manager-values-configmap.yaml
@@ -0,0 +1,35 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-cert-manager-values
+data:
+  values.yaml: |
+    ingressShim:
+      defaultIssuerName: letsencrypt-issuer
+      defaultIssuerKind: ClusterIssuer
+    resources:
+      requests:
+        cpu: 200m
+        memory: 256Mi
+      limits:
+        cpu: 400m
+        memory: 512Mi
+    cainjector:
+      resources:
+        requests:
+          cpu: 200m
+          memory: 384Mi
+        limits:
+          cpu: 400m
+          memory: 768Mi
+    webhook:
+      resources:
+        requests:
+          cpu: 100m
+          memory: 40Mi
+        limits:
+          cpu: 200m
+          memory: 80Mi
+    installCRDs: true
+
diff --git a/flux2/infrastructure/cert-manager/kustomization.yaml b/flux2/infrastructure/cert-manager/kustomization.yaml
index 972010560504d3287260f4f3ac29b96ea65d33d7..5a4077e67b80a369876ea6d28df8aa422b7dbb01 100644
--- a/flux2/infrastructure/cert-manager/kustomization.yaml
+++ b/flux2/infrastructure/cert-manager/kustomization.yaml
@@ -3,4 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
 kind: Kustomization
 namespace: cert-manager
 resources:
-  - release.yaml
\ No newline at end of file
+  - release.yaml
+  - cert-manager-values-configmap.yaml
diff --git a/flux2/infrastructure/cert-manager/release.yaml b/flux2/infrastructure/cert-manager/release.yaml
index 2d07c6a51e9595434ba10f32768844d204507205..bcaa43760bc75341137c56839ac4338721b8516f 100644
--- a/flux2/infrastructure/cert-manager/release.yaml
+++ b/flux2/infrastructure/cert-manager/release.yaml
@@ -17,36 +17,11 @@ spec:
   install:
     remediation:
       retries: 3
-  values:
-    ingressShim:
-      defaultIssuerName: letsencrypt-issuer
-      defaultIssuerKind: ClusterIssuer
-    resources:
-      requests:
-        cpu: 200m
-        memory: 256Mi
-      limits:
-        cpu: 400m
-        memory: 512Mi
-    cainjector:
-      resources:
-        requests:
-          cpu: 200m
-          memory: 384Mi
-        limits:
-          cpu: 400m
-          memory: 768Mi
-    webhook:
-      resources:
-        requests:
-          cpu: 100m
-          memory: 40Mi
-        limits:
-          cpu: 200m
-          memory: 80Mi
-    installCRDs: true
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-cert-manager-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-cert-manager-override
       optional: true
diff --git a/flux2/infrastructure/local-path-provisioner/kustomization.yaml b/flux2/infrastructure/local-path-provisioner/kustomization.yaml
index 7d7b5c99318ef59fef86864ceed84f23b0fa4c63..2f5f09aaab21702208f978b8aa330eed71a1d084 100644
--- a/flux2/infrastructure/local-path-provisioner/kustomization.yaml
+++ b/flux2/infrastructure/local-path-provisioner/kustomization.yaml
@@ -4,3 +4,4 @@ kind: Kustomization
 namespace: kube-system
 resources:
   - release.yaml
+  - local-path-provisioner-values-configmap.yaml
diff --git a/flux2/infrastructure/local-path-provisioner/local-path-provisioner-values-configmap.yaml b/flux2/infrastructure/local-path-provisioner/local-path-provisioner-values-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b55298422c9777d6650be2cb6764090f0870bb69
--- /dev/null
+++ b/flux2/infrastructure/local-path-provisioner/local-path-provisioner-values-configmap.yaml
@@ -0,0 +1,25 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: oas-local-path-provisioner-values
+data:
+  values.yaml: |
+    nodePathMap:
+      - node: DEFAULT_PATH_FOR_NON_LISTED_NODES
+        paths:
+          - "/var/lib/OpenAppStack/local-storage"
+    storageClass:
+      defaultClass: true
+    # We temporarily use our own build in order to use local volumes instead of
+    # hostPath.
+    image:
+      repository: "open.greenhost.net:4567/openappstack/openappstack/local-path-provisioner"
+      tag: "52f994f-amd64"
+    resources:
+      requests:
+        cpu: 200m
+        memory: 20Mi
+      limits:
+        cpu: 400m
+        memory: 40Mi
diff --git a/flux2/infrastructure/local-path-provisioner/release.yaml b/flux2/infrastructure/local-path-provisioner/release.yaml
index 094b4a36635f6a37a1bb113ce996a07155d6f9ee..f25f1a7231351517d9b3980bd5b6ea3392402b28 100644
--- a/flux2/infrastructure/local-path-provisioner/release.yaml
+++ b/flux2/infrastructure/local-path-provisioner/release.yaml
@@ -16,27 +16,11 @@ spec:
   install:
     remediation:
       retries: 3
-  values:
-    nodePathMap:
-      - node: DEFAULT_PATH_FOR_NON_LISTED_NODES
-        paths:
-          - "/var/lib/OpenAppStack/local-storage"
-    storageClass:
-      defaultClass: true
-    # We temporarily use our own build in order to use local volumes instead of
-    # hostPath.
-    image:
-      repository: "open.greenhost.net:4567/openappstack/openappstack/local-path-provisioner"
-      tag: "52f994f-amd64"
-    resources:
-      requests:
-        cpu: 200m
-        memory: 20Mi
-      limits:
-        cpu: 400m
-        memory: 40Mi
-  # Allow custom values either by configMap or by secret
   valuesFrom:
+    - kind: ConfigMap
+      name: oas-local-path-provisioner-values
+      optional: false
+    # Allow overriding values by ConfigMap or Secret
     - kind: ConfigMap
       name: oas-local-path-provisioner-override
       optional: true