From 151e8c6524d72f09ce86e56dead0bd57e6463092 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:04:39 +0100 Subject: [PATCH 01/17] Add chart --- charts/cnpg-database/.helmignore | 23 ++++ charts/cnpg-database/Chart.yaml | 24 ++++ charts/cnpg-database/templates/_helpers.tpl | 62 +++++++++ charts/cnpg-database/templates/cert.yaml | 25 ++++ charts/cnpg-database/templates/cluster.yaml | 130 ++++++++++++++++++ .../templates/scheduled-backup.yaml | 19 +++ charts/cnpg-database/templates/secret-s3.yaml | 16 +++ .../templates/secrets-users.yaml | 22 +++ charts/cnpg-database/templates/service.yaml | 43 ++++++ charts/cnpg-database/values.yaml | 113 +++++++++++++++ 10 files changed, 477 insertions(+) create mode 100644 charts/cnpg-database/.helmignore create mode 100644 charts/cnpg-database/Chart.yaml create mode 100644 charts/cnpg-database/templates/_helpers.tpl create mode 100644 charts/cnpg-database/templates/cert.yaml create mode 100644 charts/cnpg-database/templates/cluster.yaml create mode 100644 charts/cnpg-database/templates/scheduled-backup.yaml create mode 100644 charts/cnpg-database/templates/secret-s3.yaml create mode 100644 charts/cnpg-database/templates/secrets-users.yaml create mode 100644 charts/cnpg-database/templates/service.yaml create mode 100644 charts/cnpg-database/values.yaml diff --git a/charts/cnpg-database/.helmignore b/charts/cnpg-database/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/cnpg-database/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/cnpg-database/Chart.yaml b/charts/cnpg-database/Chart.yaml new file mode 100644 index 0000000..54243a7 --- /dev/null +++ b/charts/cnpg-database/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: cnpg-database +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0-dev + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0-dev" diff --git a/charts/cnpg-database/templates/_helpers.tpl b/charts/cnpg-database/templates/_helpers.tpl new file mode 100644 index 0000000..868d14d --- /dev/null +++ b/charts/cnpg-database/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cnpg-database.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cnpg-database.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cnpg-database.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cnpg-database.labels" -}} +helm.sh/chart: {{ include "cnpg-database.chart" . }} +{{ include "cnpg-database.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cnpg-database.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cnpg-database.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cnpg-database.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cnpg-database.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/cnpg-database/templates/cert.yaml b/charts/cnpg-database/templates/cert.yaml new file mode 100644 index 0000000..552a507 --- /dev/null +++ b/charts/cnpg-database/templates/cert.yaml @@ -0,0 +1,25 @@ +{{- if .Values.cert.enabled }} +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "cnpg-database.fullname" . }}-cert +spec: + {{- with .Values.cert.dnsNames }} + dnsNames: + {{- range . }} + - {{ . }} + {{- end }} + {{- end }} + {{- with .Values.cert.usages }} + usages: + {{- range . }} + - {{ . }} + {{- end }} + {{- end }} + {{- with .Values.cert.issuerRef }} + issuerRef: + {{- toYaml . | nindent 4 }} + {{- end }} + secretName: {{ include "cnpg-database.fullname" . }}-cert +{{- end }} diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml new file mode 100644 index 0000000..d0b3638 --- /dev/null +++ b/charts/cnpg-database/templates/cluster.yaml @@ -0,0 +1,130 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/postgresql.cnpg.io/cluster_v1.json +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: {{ include "cnpg-database.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "cnpg-database.labels" . | nindent 4 }} + {{- with .Values.postgres.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.postgres.description }} + description: {{ .Values.postgres.description }} + {{- end }} + instances: {{ .Values.postgres.instances }} + imageName: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}" + enablePDB: {{ .Values.postgres.enablePDB }} + enableSuperuserAccess: {{ .Values.postgres.enableSuperuserAccess }} + monitoring: + enablePodMonitor: {{ .Values.postgres.enablePodMonitor }} + {{- with .Values.postgres.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + storage: + storageClass: {{ .Values.postgres.storage.class }} + resizeInUseVolumes: {{ .Values.postgres.storage.data.resizeInUseVolume }} + size: {{ .Values.postgres.storage.data.size }} + walStorage: + storageClass: {{ .Values.postgres.storage.class }} + size: {{ .Values.postgres.storage.wal.size }} + resizeInUseVolumes: {{ .Values.postgres.storage.wal.resizeInUseVolume }} + {{- if .Values.postgres.bootstrap.recovery.enabled }} + bootstrap: + recovery: + source: {{ .Values.postgres.bootstrap.recovery.name | default (include "cnpg-database.fullname" .) | quote }} + database: {{ .Values.postgres.bootstrap.database }} + owner: {{ .Values.postgres.bootstrap.owner }} + externalClusters: + - name: {{ .Values.postgres.bootstrap.recovery.name | default (include "cnpg-database.fullname" .) | quote }} + barmanObjectStore: + serverName: {{ .Values.postgres.bootstrap.recovery.name | default (include "cnpg-database.fullname" .) | quote }} + destinationPath: {{ .Values.backup.s3.destinationPath | quote }} + endpointURL: {{ .Values.backup.s3.endpointURL | quote }} + {{- if and .Values.backup.trustBundleName .Values.backup.trustBundleKey }} + endpointCA: + name: {{ .Values.backup.trustBundleName }} + key: {{ .Values.backup.trustBundleKey }} + {{- end }} + s3Credentials: + accessKeyId: + key: S3_ACCESS_KEY + name: {{ include "cnpg-database.fullname" . }}-s3 + secretAccessKey: + key: S3_SECRET_KEY + name: {{ include "cnpg-database.fullname" . }}-s3 + {{- else }} + bootstrap: + initdb: + database: {{ .Values.postgres.bootstrap.database }} + owner: {{ .Values.postgres.bootstrap.owner }} + {{- end }} + {{- with .Values.postgres.parameters }} + postgresql: + parameters: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if or .Values.postgres.groups .Values.postgres.users }} + managed: + roles: + {{- range .Values.postgres.groups }} + - name: {{ . | quote }} + ensure: present + {{- end }} + {{- range .Values.postgres.users }} + - name: {{ .username | quote }} + ensure: present + login: true + passwordSecret: + name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + {{- with .inRoles }} + inRoles: + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.backup.enabled }} + backup: + retentionPolicy: {{ .Values.backup.retentionPolicy }} + target: {{ .Values.backup.target }} + barmanObjectStore: + serverName: {{ .Values.backup.name | default (include "cnpg-database.fullname" .) | quote }} + data: + compression: {{ .Values.backup.data.compression }} + destinationPath: {{ .Values.backup.s3.destinationPath }} + endpointURL: {{ .Values.backup.s3.endpointURL }} + {{- if and .Values.backup.trustBundleName .Values.backup.trustBundleKey }} + endpointCA: + name: {{ .Values.backup.trustBundleName }} + key: {{ .Values.backup.trustBundleKey }} + {{- end }} + s3Credentials: + accessKeyId: + key: S3_ACCESS_KEY + name: {{ include "cnpg-database.fullname" . }}-s3 + secretAccessKey: + key: S3_SECRET_KEY + name: {{ include "cnpg-database.fullname" . }}-s3 + wal: + compression: {{ .Values.backup.wal.compression }} + {{- with .Values.backup.wal.maxParallel }} + maxParallel: {{ . }} + {{- end }} + {{- with .Values.backup.wal.encryption }} + encryption: {{ . }} + {{- end }} + {{- end }} + {{- if or .Values.postgres.serverCASecret .Values.cert.enabled }} + certificates: + {{- with .Values.postgres.serverCASecret }} + serverCASecret: {{ . }} + {{- end }} + {{- if .Values.cert.enabled }} + serverTLSSecret: {{ include "cnpg-database.fullname" . }}-cert + {{- end }} + {{- end }} diff --git a/charts/cnpg-database/templates/scheduled-backup.yaml b/charts/cnpg-database/templates/scheduled-backup.yaml new file mode 100644 index 0000000..246fa41 --- /dev/null +++ b/charts/cnpg-database/templates/scheduled-backup.yaml @@ -0,0 +1,19 @@ +{{- if .Values.backup.enabled }} +# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/postgresql.cnpg.io/scheduledbackup_v1.json +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: {{ include "cnpg-database.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- with .Values.backup.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + suspend: {{.Values.backup.suspend }} + schedule: {{ .Values.backup.schedule | quote }} + immediate: {{ .Values.backup.immediate }} + backupOwnerReference: self + cluster: + name: {{ include "cnpg-database.fullname" . }} +{{- end }} diff --git a/charts/cnpg-database/templates/secret-s3.yaml b/charts/cnpg-database/templates/secret-s3.yaml new file mode 100644 index 0000000..f54e05d --- /dev/null +++ b/charts/cnpg-database/templates/secret-s3.yaml @@ -0,0 +1,16 @@ +{{- if .Values.backup.enabled }} +# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/bitnami.com/sealedsecret_v1alpha1.json +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: {{ include "cnpg-database.fullname" . }}-s3 + namespace: {{ .Release.Namespace }} + annotations: + sealedsecrets.bitnami.com/namespace-wide: "true" + labels: + {{- include "cnpg-database.labels" . | nindent 4 }} +spec: + encryptedData: + S3_ACCESS_KEY: {{.Values.backup.s3.accessKey }} + S3_SECRET_KEY: {{.Values.backup.s3.secretKey }} +{{- end }} diff --git a/charts/cnpg-database/templates/secrets-users.yaml b/charts/cnpg-database/templates/secrets-users.yaml new file mode 100644 index 0000000..7b8dbfa --- /dev/null +++ b/charts/cnpg-database/templates/secrets-users.yaml @@ -0,0 +1,22 @@ +{{- with .Values.postgres.users }} +{{- range . }} +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/bitnami.com/sealedsecret_v1alpha1.json +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + namespace: {{ $.Release.Namespace }} + annotations: + sealedsecrets.bitnami.com/namespace-wide: "true" +spec: + encryptedData: + password: {{ .password | quote }} + template: + metadata: + name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + type: kubernetes.io/basic-auth + data: + username: {{ .username | quote }} +{{- end }} +{{- end }} diff --git a/charts/cnpg-database/templates/service.yaml b/charts/cnpg-database/templates/service.yaml new file mode 100644 index 0000000..1b9959f --- /dev/null +++ b/charts/cnpg-database/templates/service.yaml @@ -0,0 +1,43 @@ +{{- if .Values.additionalService.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "cnpg-database.fullname" . }} + {{- with .Values.additionalService.labels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.additionalService.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if eq .Values.additionalService.type "ClusterIP" }} + type: ClusterIP + {{- with .Values.additionalService.clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- else if eq .Values.additionalService.type "LoadBalancer" }} + type: LoadBalancer + {{- with .Values.additionalService.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + {{- with .Values.additionalService.loadBalancerClass }} + loadBalancerClass: {{ . }} + {{- end }} + {{- with .Values.additionalService.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- else }} + type: {{ .Values.additionalService.type }} + {{- end }} + ports: + - name: postgres + protocol: TCP + port: {{ .Values.additionalService.port }} + targetPort: {{ .Values.additionalService.targetPort }} + selector: + {{- include "cnpg-database.selectorLabels" . | nindent 4 }} + cnpg.io/instanceRole: {{ .Values.additionalService.instanceRole }} +{{- end }} diff --git a/charts/cnpg-database/values.yaml b/charts/cnpg-database/values.yaml new file mode 100644 index 0000000..d316c0b --- /dev/null +++ b/charts/cnpg-database/values.yaml @@ -0,0 +1,113 @@ +postgres: + description: "" + annotations: {} + + instances: 1 + image: + repository: ghcr.io/cloudnative-pg/postgresql + tag: "18-standard-trixie" + + enablePDB: true + enableSuperuserAccess: true + enablePodMonitor: true + + resources: + requests: + memory: "512Mi" + cpu: "50m" + limits: + memory: "512Mi" + cpu: "50m" + + # Storage configuration, see https://cloudnative-pg.io/documentation/current/storage/ + storage: + class: standard + data: + resizeInUseVolume: true + size: 10Gi + wal: + resizeInUseVolume: true + size: 10Gi + + # Bootstrap the PostgreSQL: https://cloudnative-pg.io/documentation/current/bootstrap/ + bootstrap: + database: db + owner: user + recovery: + enabled: false + # Name of the S3 backup to recover from. Uses S3 settings from backup section. + name: "" + + # Parameters passed to PostgreSQL: https://cloudnative-pg.io/documentation/current/postgresql_conf/ + parameters: {} + + groups: [] + # - "my_group_role" + + # Usernames are unsealed and passwords are sealed (refer to https://github.com/bitnami-labs/sealed-secrets) + users: [] + # - username: "john.doe" + # password: "MySealedPassword" + # inRoles: + # - my_group_role + + # Secret name for root CA certificate + serverCASecret: "" + +backup: + enabled: false + + # Name of the current instance backup into the S3 bucket. + # Cannot be set to a backup name that already exists inside the bucket. + # For more details see https://github.com/cloudnative-pg/cloudnative-pg/issues/5203 + name: "" + annotations: {} + + # Schedule of the backup job + schedule: "0 0 0 * * *" + suspend: false + immediate: false + + retentionPolicy: 14d + target: "prefer-standby" + + trustBundleName: "" + trustBundleKey: "" + + # access and secret keys are sealed (refer to https://github.com/bitnami-labs/sealed-secrets) + s3: + destinationPath: s3://my-bucket + endpointURL: https://my-s3-endpoint.example + accessKey: "MyAccessKeyId" + secretKey: "MySecretKeyId" + data: + compression: gzip + wal: + compression: gzip + maxParallel: 8 + encryption: AES256 + +# CNPG deploys services for the database by default. This is just here if you require an extra service. +additionalService: + enabled: false + + type: ClusterIP + clusterIP: "" + loadBalancerIP: "" + loadBalancerClass: "" + loadBalancerSourceRanges: [] + + port: 5432 + targetPort: 5432 + + # Whether to chose the primary or the readonly replica instance + instanceRole: replica + +cert: + enabled: false + dnsNames: [] + usages: [] + issuerRef: + # group: cert-manager.io + # kind: ClusterIssuer + # name: my-issuer From 0bb2a3a9e1f54b9bf8a78cc5916ea017a43e41b5 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:13:48 +0100 Subject: [PATCH 02/17] Add CI and versioning --- .github/release.yaml | 25 +++++++++++++++++++++ .github/workflows/ci.yaml | 39 +++++++++++++++++++++++++++++++++ .gitignore | 4 ++++ bumpversion.cfg | 10 +++++++++ charts/cnpg-database/Chart.yaml | 4 ++-- 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 .github/release.yaml create mode 100644 .github/workflows/ci.yaml create mode 100644 .gitignore create mode 100644 bumpversion.cfg diff --git a/.github/release.yaml b/.github/release.yaml new file mode 100644 index 0000000..5baac10 --- /dev/null +++ b/.github/release.yaml @@ -0,0 +1,25 @@ +name: Release + +on: + workflow_dispatch: + inputs: + release-type: + description: "Scope of the release." + type: choice + required: true + default: patch + options: + - patch + - minor + - major + +jobs: + release: + name: Release + uses: bakdata/ci-templates/.github/workflows/bump-version-release.yaml@1.35.1 + with: + release-type: "${{ github.event.inputs.release-type }}" + secrets: + github-username: "${{ secrets.GH_USERNAME }}" + github-email: "${{ secrets.GH_EMAIL }}" + github-token: "${{ secrets.GH_TOKEN }}" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..0e58603 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + +jobs: + get-version: + name: Get Version + runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.get-version.outputs.version }} + steps: + - name: Check out repository + uses: bakdata/ci-templates/actions/checkout@1.69.2 + + - name: Get version + id: get-version + shell: bash + env: + DEFAULT_BRANCH: refs/heads/${{ github.event.repository.default_branch }} + run: | + version=$(sed -n 's/^current_version = \(\.*\)/\1/p' < .bumpversion.cfg) + if [[ "${GITHUB_REF}" != refs/tags/* ]]; then + version="${version}-SNAPSHOT" + fi + echo "version=${version}" >> "$GITHUB_OUTPUT" + + build-and-publish: + name: Helm + uses: bakdata/ci-templates/.github/workflows/helm-multi-release.yaml@1.69.2 + needs: get-version + with: + charts-path: "charts" + subdirs: "['cnpg-database']" + version: ${{ needs.get-version.outputs.version }} + secrets: + github-username: ${{ secrets.GH_USERNAME }} + github-email: ${{ secrets.GH_EMAIL }} + github-token: ${{ secrets.GH_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6e029a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.* +!.github +!.gitignore +!.bumpversion.cfg diff --git a/bumpversion.cfg b/bumpversion.cfg new file mode 100644 index 0000000..50c8cc1 --- /dev/null +++ b/bumpversion.cfg @@ -0,0 +1,10 @@ +[bumpversion] +current_version = 0.1.0 +parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?P\w+))? +serialize = + {major}.{minor}.{patch}-{suffix} + {major}.{minor}.{patch} + +[bumpversion:file:charts/cnpg-database/Chart.yaml] +search = version: {current_version} +replace = version: {new_version} diff --git a/charts/cnpg-database/Chart.yaml b/charts/cnpg-database/Chart.yaml index 54243a7..fc84e4e 100644 --- a/charts/cnpg-database/Chart.yaml +++ b/charts/cnpg-database/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0-dev +version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.1.0-dev" +appVersion: "0.1.0" From 32a7c444aa7fb954951811b293f40d8fc636b836 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:14:25 +0100 Subject: [PATCH 03/17] Add CI and versioning --- bumpversion.cfg => .bumpversion.cfg | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bumpversion.cfg => .bumpversion.cfg (100%) diff --git a/bumpversion.cfg b/.bumpversion.cfg similarity index 100% rename from bumpversion.cfg rename to .bumpversion.cfg From a289cf9968b4cf54a114ac982ead1e1bfc3f8487 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:15:36 +0100 Subject: [PATCH 04/17] Add CI and versioning --- .github/lint-config.yaml | 1 + .github/{ => workflows}/release.yaml | 0 2 files changed, 1 insertion(+) create mode 100644 .github/lint-config.yaml rename .github/{ => workflows}/release.yaml (100%) diff --git a/.github/lint-config.yaml b/.github/lint-config.yaml new file mode 100644 index 0000000..21095dd --- /dev/null +++ b/.github/lint-config.yaml @@ -0,0 +1 @@ +target-branch: "main" diff --git a/.github/release.yaml b/.github/workflows/release.yaml similarity index 100% rename from .github/release.yaml rename to .github/workflows/release.yaml From c12a501b2aee028e44712b64356e54e3f07be65e Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:16:57 +0100 Subject: [PATCH 05/17] Add CI and versioning --- charts/cnpg-database/Chart.yaml | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/charts/cnpg-database/Chart.yaml b/charts/cnpg-database/Chart.yaml index fc84e4e..36803be 100644 --- a/charts/cnpg-database/Chart.yaml +++ b/charts/cnpg-database/Chart.yaml @@ -1,24 +1,8 @@ apiVersion: v2 name: cnpg-database description: A Helm chart for Kubernetes - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) version: 0.1.0 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "0.1.0" +maintainers: + - name: bakdata + email: opensource@bakdata.com + url: bakdata.com From 2de8efc6659c9b323900aeb5966ec0699f488701 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:17:26 +0100 Subject: [PATCH 06/17] Add CI and versioning --- charts/cnpg-database/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cnpg-database/Chart.yaml b/charts/cnpg-database/Chart.yaml index 36803be..154a133 100644 --- a/charts/cnpg-database/Chart.yaml +++ b/charts/cnpg-database/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: cnpg-database -description: A Helm chart for Kubernetes +description: A Helm chart for deploying a CNPG database version: 0.1.0 maintainers: - name: bakdata From b0f7234c722620db610dbbc299b40bcdec7ea518 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:28:04 +0100 Subject: [PATCH 07/17] Change dev suffix --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e58603..b521c75 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,7 +21,7 @@ jobs: run: | version=$(sed -n 's/^current_version = \(\.*\)/\1/p' < .bumpversion.cfg) if [[ "${GITHUB_REF}" != refs/tags/* ]]; then - version="${version}-SNAPSHOT" + version="${version}-dev" fi echo "version=${version}" >> "$GITHUB_OUTPUT" From 500ee25540aa3762441ebe10de53069040ba2fb7 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Fri, 20 Mar 2026 14:31:58 +0100 Subject: [PATCH 08/17] Add README --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2373188..5d19f3f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # cnpg-database-helm-chart -Helm chart for a CNPG database + +Helm chart for deploying a CNPG database + +## Install + +```shell +helm repo add cnpg-database https://bakdata.github.io/cnpg-database-helm-chart/ +helm repo update +helm install cnpg-database/cnpg-database +``` From 7066f3079aa114a3a327d291c6442693c7200ff5 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 16:52:11 +0100 Subject: [PATCH 09/17] Address feedback --- charts/cnpg-database/templates/cluster.yaml | 1 - charts/cnpg-database/templates/scheduled-backup.yaml | 1 - charts/cnpg-database/templates/secret-s3.yaml | 1 - charts/cnpg-database/templates/secrets-users.yaml | 1 - 4 files changed, 4 deletions(-) diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml index d0b3638..f9238c2 100644 --- a/charts/cnpg-database/templates/cluster.yaml +++ b/charts/cnpg-database/templates/cluster.yaml @@ -3,7 +3,6 @@ apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: {{ include "cnpg-database.fullname" . }} - namespace: {{ .Release.Namespace }} labels: {{- include "cnpg-database.labels" . | nindent 4 }} {{- with .Values.postgres.annotations }} diff --git a/charts/cnpg-database/templates/scheduled-backup.yaml b/charts/cnpg-database/templates/scheduled-backup.yaml index 246fa41..b7ce788 100644 --- a/charts/cnpg-database/templates/scheduled-backup.yaml +++ b/charts/cnpg-database/templates/scheduled-backup.yaml @@ -4,7 +4,6 @@ apiVersion: postgresql.cnpg.io/v1 kind: ScheduledBackup metadata: name: {{ include "cnpg-database.fullname" . }} - namespace: {{ .Release.Namespace }} {{- with .Values.backup.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/cnpg-database/templates/secret-s3.yaml b/charts/cnpg-database/templates/secret-s3.yaml index f54e05d..999f6ce 100644 --- a/charts/cnpg-database/templates/secret-s3.yaml +++ b/charts/cnpg-database/templates/secret-s3.yaml @@ -4,7 +4,6 @@ apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: name: {{ include "cnpg-database.fullname" . }}-s3 - namespace: {{ .Release.Namespace }} annotations: sealedsecrets.bitnami.com/namespace-wide: "true" labels: diff --git a/charts/cnpg-database/templates/secrets-users.yaml b/charts/cnpg-database/templates/secrets-users.yaml index 7b8dbfa..efa64b6 100644 --- a/charts/cnpg-database/templates/secrets-users.yaml +++ b/charts/cnpg-database/templates/secrets-users.yaml @@ -6,7 +6,6 @@ apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} - namespace: {{ $.Release.Namespace }} annotations: sealedsecrets.bitnami.com/namespace-wide: "true" spec: From acc4dd9617b1e31dc09b222e53ba4ffaca09cdb6 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 16:56:13 +0100 Subject: [PATCH 10/17] Address feedback --- charts/cnpg-database/templates/cert.yaml | 25 ------------------- .../templates/secrets-users.yaml | 2 +- charts/cnpg-database/values.yaml | 9 ------- 3 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 charts/cnpg-database/templates/cert.yaml diff --git a/charts/cnpg-database/templates/cert.yaml b/charts/cnpg-database/templates/cert.yaml deleted file mode 100644 index 552a507..0000000 --- a/charts/cnpg-database/templates/cert.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if .Values.cert.enabled }} -# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ include "cnpg-database.fullname" . }}-cert -spec: - {{- with .Values.cert.dnsNames }} - dnsNames: - {{- range . }} - - {{ . }} - {{- end }} - {{- end }} - {{- with .Values.cert.usages }} - usages: - {{- range . }} - - {{ . }} - {{- end }} - {{- end }} - {{- with .Values.cert.issuerRef }} - issuerRef: - {{- toYaml . | nindent 4 }} - {{- end }} - secretName: {{ include "cnpg-database.fullname" . }}-cert -{{- end }} diff --git a/charts/cnpg-database/templates/secrets-users.yaml b/charts/cnpg-database/templates/secrets-users.yaml index efa64b6..17e518c 100644 --- a/charts/cnpg-database/templates/secrets-users.yaml +++ b/charts/cnpg-database/templates/secrets-users.yaml @@ -5,7 +5,7 @@ apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: - name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + name: {{ include "cnpg-database.fullname" . }}-{{ printf "%s-credentials" .username | replace "." "-" | quote }} annotations: sealedsecrets.bitnami.com/namespace-wide: "true" spec: diff --git a/charts/cnpg-database/values.yaml b/charts/cnpg-database/values.yaml index d316c0b..e2ca724 100644 --- a/charts/cnpg-database/values.yaml +++ b/charts/cnpg-database/values.yaml @@ -102,12 +102,3 @@ additionalService: # Whether to chose the primary or the readonly replica instance instanceRole: replica - -cert: - enabled: false - dnsNames: [] - usages: [] - issuerRef: - # group: cert-manager.io - # kind: ClusterIssuer - # name: my-issuer From 086d1ed600b9d1870ee0dc6f4838b0b2e9b20194 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 17:01:26 +0100 Subject: [PATCH 11/17] Address feedback --- charts/cnpg-database/templates/cluster.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml index f9238c2..5c5a172 100644 --- a/charts/cnpg-database/templates/cluster.yaml +++ b/charts/cnpg-database/templates/cluster.yaml @@ -123,7 +123,7 @@ spec: {{- with .Values.postgres.serverCASecret }} serverCASecret: {{ . }} {{- end }} - {{- if .Values.cert.enabled }} - serverTLSSecret: {{ include "cnpg-database.fullname" . }}-cert + {{- with .Values.postgres.serverTLSSecret }} + serverTLSSecret: {{ . }} {{- end }} {{- end }} From 8762ea908ffb21758438218d72b64014577e9967 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 17:03:07 +0100 Subject: [PATCH 12/17] Address feedback --- charts/cnpg-database/templates/cluster.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml index 5c5a172..d0529af 100644 --- a/charts/cnpg-database/templates/cluster.yaml +++ b/charts/cnpg-database/templates/cluster.yaml @@ -118,7 +118,7 @@ spec: encryption: {{ . }} {{- end }} {{- end }} - {{- if or .Values.postgres.serverCASecret .Values.cert.enabled }} + {{- if or .Values.postgres.serverCASecret .Values.postgres.serverTLSSecret }} certificates: {{- with .Values.postgres.serverCASecret }} serverCASecret: {{ . }} From 39d64d77d46bc6a7a38dce8360b23ff5e8b8ff01 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 17:41:46 +0100 Subject: [PATCH 13/17] Address feedback --- charts/cnpg-database/templates/cluster.yaml | 2 +- charts/cnpg-database/templates/secrets-users.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml index d0529af..ca82a25 100644 --- a/charts/cnpg-database/templates/cluster.yaml +++ b/charts/cnpg-database/templates/cluster.yaml @@ -78,7 +78,7 @@ spec: ensure: present login: true passwordSecret: - name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + name: {{ printf "%s-creds-%s" (include "cnpg-database.fullname" $) .username | replace "." "-" | trunc 63 | quote }} {{- with .inRoles }} inRoles: {{- range . }} diff --git a/charts/cnpg-database/templates/secrets-users.yaml b/charts/cnpg-database/templates/secrets-users.yaml index 17e518c..538dc0c 100644 --- a/charts/cnpg-database/templates/secrets-users.yaml +++ b/charts/cnpg-database/templates/secrets-users.yaml @@ -5,7 +5,7 @@ apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: - name: {{ include "cnpg-database.fullname" . }}-{{ printf "%s-credentials" .username | replace "." "-" | quote }} + name: {{ printf "%s-creds-%s" (include "cnpg-database.fullname" $) .username | replace "." "-" | trunc 63 | quote }} annotations: sealedsecrets.bitnami.com/namespace-wide: "true" spec: @@ -13,7 +13,7 @@ spec: password: {{ .password | quote }} template: metadata: - name: {{ printf "%s-credentials" .username | replace "." "-" | quote }} + name: {{ printf "%s-creds-%s" (include "cnpg-database.fullname" $) .username | replace "." "-" | trunc 63 | quote }} type: kubernetes.io/basic-auth data: username: {{ .username | quote }} From cc09a7e01a108981ba4c5014ee4d511286792882 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 18:13:11 +0100 Subject: [PATCH 14/17] Address feedback --- charts/cnpg-database/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/cnpg-database/values.yaml b/charts/cnpg-database/values.yaml index e2ca724..962843f 100644 --- a/charts/cnpg-database/values.yaml +++ b/charts/cnpg-database/values.yaml @@ -53,6 +53,8 @@ postgres: # Secret name for root CA certificate serverCASecret: "" + # Secret name for TLS + serverTLSSecret: "" backup: enabled: false From aa9de38e4c3fff07bcab7aa70c2d2ea5b2325510 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 18:27:23 +0100 Subject: [PATCH 15/17] Address feedback --- charts/cnpg-database/templates/service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cnpg-database/templates/service.yaml b/charts/cnpg-database/templates/service.yaml index 1b9959f..e2e23af 100644 --- a/charts/cnpg-database/templates/service.yaml +++ b/charts/cnpg-database/templates/service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "cnpg-database.fullname" . }} + name: {{ include "cnpg-database.fullname" . }}-additional {{- with .Values.additionalService.labels }} labels: {{- toYaml . | nindent 4 }} From 831fcf7e8710846256c7de9e57ed975ecde5a470 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Wed, 25 Mar 2026 18:37:07 +0100 Subject: [PATCH 16/17] Address feedback --- charts/cnpg-database/templates/service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cnpg-database/templates/service.yaml b/charts/cnpg-database/templates/service.yaml index e2e23af..b1538b2 100644 --- a/charts/cnpg-database/templates/service.yaml +++ b/charts/cnpg-database/templates/service.yaml @@ -38,6 +38,6 @@ spec: port: {{ .Values.additionalService.port }} targetPort: {{ .Values.additionalService.targetPort }} selector: - {{- include "cnpg-database.selectorLabels" . | nindent 4 }} + cnpg.io/cluster: {{ include "cnpg-database.fullname" . }} cnpg.io/instanceRole: {{ .Values.additionalService.instanceRole }} {{- end }} From a8b5a910cc1d2cc475cd2c052a855fff85303a96 Mon Sep 17 00:00:00 2001 From: yannick-roeder Date: Thu, 26 Mar 2026 12:27:37 +0100 Subject: [PATCH 17/17] Address feedback --- charts/cnpg-database/templates/cluster.yaml | 2 -- charts/cnpg-database/templates/pod-monitor.yaml | 13 +++++++++++++ charts/cnpg-database/templates/secret-s3.yaml | 4 ++++ charts/cnpg-database/templates/secrets-users.yaml | 3 ++- charts/cnpg-database/values.yaml | 11 +++++++---- 5 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 charts/cnpg-database/templates/pod-monitor.yaml diff --git a/charts/cnpg-database/templates/cluster.yaml b/charts/cnpg-database/templates/cluster.yaml index ca82a25..66ee7f3 100644 --- a/charts/cnpg-database/templates/cluster.yaml +++ b/charts/cnpg-database/templates/cluster.yaml @@ -17,8 +17,6 @@ spec: imageName: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}" enablePDB: {{ .Values.postgres.enablePDB }} enableSuperuserAccess: {{ .Values.postgres.enableSuperuserAccess }} - monitoring: - enablePodMonitor: {{ .Values.postgres.enablePodMonitor }} {{- with .Values.postgres.resources }} resources: {{- toYaml . | nindent 4 }} diff --git a/charts/cnpg-database/templates/pod-monitor.yaml b/charts/cnpg-database/templates/pod-monitor.yaml new file mode 100644 index 0000000..c73079e --- /dev/null +++ b/charts/cnpg-database/templates/pod-monitor.yaml @@ -0,0 +1,13 @@ +{{- if .Values.podMonitor.enabled }} +# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/monitoring.coreos.com/podmonitor_v1.json +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "cnpg-database.fullname" . }} +spec: + selector: + matchLabels: + cnpg.io/cluster: {{ include "cnpg-database.fullname" . }} + podMetricsEndpoints: + - port: metrics +{{- end }} diff --git a/charts/cnpg-database/templates/secret-s3.yaml b/charts/cnpg-database/templates/secret-s3.yaml index 999f6ce..2a93afe 100644 --- a/charts/cnpg-database/templates/secret-s3.yaml +++ b/charts/cnpg-database/templates/secret-s3.yaml @@ -12,4 +12,8 @@ spec: encryptedData: S3_ACCESS_KEY: {{.Values.backup.s3.accessKey }} S3_SECRET_KEY: {{.Values.backup.s3.secretKey }} + template: + metadata: + annotations: + cnpg.io/reload: "true" {{- end }} diff --git a/charts/cnpg-database/templates/secrets-users.yaml b/charts/cnpg-database/templates/secrets-users.yaml index 538dc0c..6023d1c 100644 --- a/charts/cnpg-database/templates/secrets-users.yaml +++ b/charts/cnpg-database/templates/secrets-users.yaml @@ -13,7 +13,8 @@ spec: password: {{ .password | quote }} template: metadata: - name: {{ printf "%s-creds-%s" (include "cnpg-database.fullname" $) .username | replace "." "-" | trunc 63 | quote }} + annotations: + cnpg.io/reload: "true" type: kubernetes.io/basic-auth data: username: {{ .username | quote }} diff --git a/charts/cnpg-database/values.yaml b/charts/cnpg-database/values.yaml index 962843f..9dc1037 100644 --- a/charts/cnpg-database/values.yaml +++ b/charts/cnpg-database/values.yaml @@ -9,7 +9,6 @@ postgres: enablePDB: true enableSuperuserAccess: true - enablePodMonitor: true resources: requests: @@ -19,7 +18,7 @@ postgres: memory: "512Mi" cpu: "50m" - # Storage configuration, see https://cloudnative-pg.io/documentation/current/storage/ + # Storage configuration, see https://cloudnative-pg.io/docs/current/storage/ storage: class: standard data: @@ -29,7 +28,7 @@ postgres: resizeInUseVolume: true size: 10Gi - # Bootstrap the PostgreSQL: https://cloudnative-pg.io/documentation/current/bootstrap/ + # Bootstrap the PostgreSQL: https://cloudnative-pg.io/docs/current/bootstrap/ bootstrap: database: db owner: user @@ -38,7 +37,7 @@ postgres: # Name of the S3 backup to recover from. Uses S3 settings from backup section. name: "" - # Parameters passed to PostgreSQL: https://cloudnative-pg.io/documentation/current/postgresql_conf/ + # Parameters passed to PostgreSQL: https://cloudnative-pg.io/docs/current/postgresql_conf/ parameters: {} groups: [] @@ -89,6 +88,10 @@ backup: maxParallel: 8 encryption: AES256 +# See https://cloudnative-pg.io/docs/current/monitoring/#monitoring-with-the-prometheus-operator +podMonitor: + enabled: true + # CNPG deploys services for the database by default. This is just here if you require an extra service. additionalService: enabled: false