Repository navigation
feat(cloudnative-pg): add CloudNativePG operator + Cluster catalog entry - #337
Merged
Merged
Conversation
Adds infra/cloudnative-pg with two independent sub-entries, both sourcing https://cloudnative-pg.github.io/charts: - install/ cnpg/cloudnative-pg 0.29.0 (app 1.30.0), sync-wave -10 - cluster/ cnpg/cluster 0.8.1 (the official Cluster CR chart), sync-wave 0 Split because the lifecycles differ: one operator per cluster, N databases against it. cluster/ derives its Application name from clusterName + destination so several Postgres clusters can share a target cluster. Three catalog entries (backstage, zitadel, harbor) each carry a bundled Bitnami Postgres, one of them pinned to bitnamilegacy. This entry is the shared managed alternative; migrating those three is deliberately not part of this change. Notes: - destination.namespace defaults to `postgres` for install/, matching stuttgart-things/helm's database/postgres.yaml.gotmpl rather than upstream's cnpg-system. Documented in the README so nobody "fixes" it. - ServerSideApply is required, not stylistic: the clusters.postgresql.cnpg.io CRD exceeds the 262144-byte last-applied-configuration annotation limit. - cluster/ emits cluster.initdb.secret only when appSecretName is non-empty; an empty secret.name breaks CNPG bootstrap. - owner is schema-constrained to exclude `{}` because upstream runs cluster.initdb.owner through tpl. Root README gains the infra/ row only; the stale entry counts in that index are left alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018THyZwQsAgdoZSC4ZY4eGf
patrick-hermann-sva
temporarily deployed
to
k8s
August 29, 2026 14:46 — with
GitHub Actions
Inactive
patrick-hermann-sva
temporarily deployed
to
k8s
August 29, 2026 14:46 — with
GitHub Actions
Inactive
patrick-hermann-sva
temporarily deployed
to
k8s
August 29, 2026 14:47 — with
GitHub Actions
Inactive
patrick-hermann-sva
temporarily deployed
to
k8s
August 29, 2026 14:47 — with
GitHub Actions
Inactive
|
🎉 This PR is included in version 0.10.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
6 tasks done
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
infra/cloudnative-pg— CloudNativePG as a catalog entry, in two independent sub-entries, both sourcinghttps://cloudnative-pg.github.io/charts:install/cnpg/cloudnative-pg(operator)0.29.0(app 1.30.0)-10cluster/cnpg/cluster(theClusterCR)0.8.10Port of the Helmfile definitions in
stuttgart-things/helm#161.Why
Three catalog entries each carry their own bundled Bitnami PostgreSQL —
apps/backstage/install,apps/zitadel/install, andapps/harbor/install(the last pinned tobitnamilegacy/postgresql, a deprecation shim).apps/zitadel/install/values.yamlalready says in its own comment to point ZITADEL at managed PostgreSQL for production. This entry is the shared answer.Migrating those three is not part of this PR — that means data movement and a per-app credentials rewire, and it belongs in its own change.
infra/rather thanapps/because CNPG is a dependency of other catalog entries, which puts it alongsideexternal-secretsandcert-manager.apps/redis-stackis a surface-level analog but a leaf — nothing in the catalog consumes it.Shape
Follows the house pattern:
apps/redis-stack/installfor the computed-valuesObjectshape,infra/longhorn/installfor a plain-HTTPS chart repo. Four files per sub-entry plus one entry README. Strictvalues.schema.json(additionalProperties: false);extraValuesandsyncPolicystay open.Split into two sub-entries because the lifecycles genuinely differ — one operator per cluster, N databases against it.
cluster/derives its Application name fromclusterName+ destination (not destination alone), so several Postgres clusters can share one target cluster without colliding.Decisions worth a reviewer's eye
install/defaultsdestination.namespacetopostgres, not upstream'scnpg-system— matchingstuttgart-things/helm'sdatabase/postgres.yaml.gotmpl. Consistency across the sibling repos; documented in the README so nobody "fixes" it.ServerSideApplyis required, not stylistic. Theclusters.postgresql.cnpg.ioCRD is far past the 262144-bytelast-applied-configurationannotation limit, so a client-side apply fails outright.cluster/emitscluster.initdb.secretonly whenappSecretNameis non-empty. An emptysecret.namebreaks CNPG bootstrap; empty means CNPG generates<clusterName>-appitself.owneris schema-constrained to exclude{/}because upstream runscluster.initdb.ownerthroughtpl.retryblock is load-bearing. Sync waves only order resources within one Application, so syncingcluster/against a cluster whose operator isn't up yet fails the dry-run on the unknownpostgresql.cnpg.io/v1kind; retry (limit 5, exponential to 3m) is what recovers it. Documented rather than papered over.cluster/'sdestination.namespacehas no good default — aClusterbelongs in the consuming app's namespace, not the operator's. It isrequiredin the schema, andvalues.yamlcarries an inert placeholder (cnpg-cluster) purely so the chart renders standalone for CI. Because Helm deep-merges maps, a consumer overriding onlydestination.serverinherits that placeholder — called out prominently in the README. If you'd prefer a hard render-timerequiredinstead, that trades away a green barehelm template.infra/row only. The entry counts in that index are already stale (infra/claims 8, holds 11 now); reconciling it is its own change.Validation
helm lint+helm templateclean on both sub-entries.Applications confirmed forrepoURL(https://cloudnative-pg.github.io/charts),chart,targetRevision, and sync-wave.valuesObjects fed back through the real upstream charts. The operator renders 11 CRDs (matching the documented teardown list); theclusterchart renders aClusterwith the expectedinstances/storage/walStorage/enablePDB/bootstrap.initdb— includingsecret.nameappearing only whenappSecretNameis set — plusPodMonitor+PrometheusRulewhen monitoring is on, andextraValuesdeep-merging intocluster.*alongside the computed keys.ownerare both rejected.renovate.jsoncustomManager regex — both match with the rightdepName(cloudnative-pg/cluster) andregistryUrl.Not done: no
platforms/storageApplicationSet (the brief marks it optional/on-request), and no live-cluster apply from this branch.🤖 Generated with Claude Code
https://claude.ai/code/session_018THyZwQsAgdoZSC4ZY4eGf