cnpglisted
Install: claude install-skill vanducng/skills
# cnpg
Provision and run CloudNativePG (CNPG) Postgres on Kubernetes as GitOps. Every
concrete identifier below is a placeholder - substitute your own:
`<project>`, `<gcp-sa>`, `<backups-bucket>`, `<cluster>`, `<ns>`, `<svc>`,
`<db>`, `<owner>`, `<env>`, `<s3-endpoint>`, `<objstore-secret>`, `<app-ns>`.
**Two platforms, one operator.** The Cluster spec, bootstrap, pgvector, PITR,
clone, and most gotchas are identical everywhere; only **backup auth** and
**NetworkPolicy** differ. Managed cloud (GKE + GCS): Workload Identity, no keys -
steps below default to this. Self-hosted (K3s / bare-metal + S3-compatible store:
MinIO, Ceph, R2, B2): an access-key Secret, plus explicit NetworkPolicies on a
default-deny cluster. Read **`references/self-hosted-and-networkpolicy.md`**
whenever there's no cloud Workload Identity or the cluster enforces default-deny.
## Mental model - two halves that MUST share one string
A CNPG database is two halves agreeing on exactly one string, `<ns>/<cluster>`:
the **GitOps half** - a CNPG `Cluster` whose `serviceAccountTemplate` annotation
points the auto-created **pod KSA** (named after the **cluster**) at the GCP
backup SA - and the **GCP half** - an IAM `workloadIdentityUser` binding whose
member is `serviceAccount:<project>.svc.id.goog[<ns>/<cluster>]` plus the GCS
backups bucket. Any standalone `ServiceAccount` named `cnpg-backup-sa` is a
**decoy/legacy** resource; CNPG does not use it for backup auth.
Deploy is pure GitOps: commit YAML → a Flux