Manifest Mapping

Field-by-field mapping from the Zalando CR (acid.zalan.do/v1 postgresql) to CloudNativePG resources (postgresql.cnpg.io/v1).

An automated conversion script, zalando-to-cnpg, ships with the product delivery (operator source repository, hack/zalando-to-cnpg/): it emits a Cluster plus Pooler/Database resources and prints an explicit WARN for every field it cannot map — treat each warning as a checklist item.

Legend: direct = copy; transform = rename/convert; mechanism = different resource or approach; none = no equivalent (the tool warns).

Core

ZalandoCloudNativePGKindNotes
metadata.namemetadata.namedirectNo teamId- prefix rule in CNPG; renaming changes service DNS names.
spec.teamId—noneConvention only; preserved as a label via inheritedMetadata.
spec.numberOfInstancesspec.instancesdirectZalando 0 (hibernation) → annotation cnpg.io/hibernation: "on", not instances: 0.
spec.dockerImagespec.imageNametransformNever copy — Spilo images are unusable with CNPG. Derive from postgresql.version → PostgreSQL operand image for that major.
spec.postgresql.versionimage majortransformCNPG infers the version from the image.
spec.envspec.envtransformDrop Spilo/WAL-G variables (WAL_S3_BUCKET, USE_WALG_*, AWS_*, …) — backup config moves to the barman-cloud ObjectStore.

Storage and resources

ZalandoCloudNativePGKindNotes
spec.volume.sizespec.storage.sizedirectIn-place growth supported; no shrink (either side).
spec.volume.storageClassspec.storage.storageClassdirect
spec.volume.selectorspec.storage.pvcTemplate.selectortransform
spec.volume.subPath / iops / throughput—noneFixed PGDATA layout; IOPS/throughput were AWS EBS API calls — express via the StorageClass.
spec.additionalVolumes—none (partial)Secrets/ConfigMaps → spec.projectedVolumeTemplate; data volumes → spec.tablespaces / spec.walStorage.
spec.resourcesspec.resourcesdirectIf absent in the Zalando CR, operator-config defaults applied — set explicit values in CNPG.

Users and databases

ZalandoCloudNativePGKindNotes
spec.usersspec.managed.roles[]transformFlags map 1:1 (superuser, createdb, createrole, replication, bypassrls; nologin → login: false). ⚠ Zalando users are LOGIN by default; CNPG managed roles default login: false — the tool always emits login explicitly.
credential secretsmanaged.roles[].passwordSecretmechanismCNPG expects kubernetes.io/basic-auth secrets. Copy passwords from the Zalando <user>.<cluster>.credentials... secrets to keep application credentials working.
spec.usersWithSecretRotation (+ in-place variant)—noneNo automated password rotation.
spec.databasesbootstrap.initdb.{database,owner} + Database CRstransformFirst entry bootstraps the cluster; each additional one becomes a Database resource.
spec.preparedDatabasesDatabase CR (schemas, extensions) + rolestransformThe Zalando auto role hierarchy (<db>_owner/_reader/_writer + default privileges) is not auto-created — synthesize roles and GRANTs (e.g. postInitApplicationSQL).

PostgreSQL configuration

ZalandoCloudNativePGKindNotes
spec.postgresql.parametersspec.postgresql.parameterstransformCopy, minus operator-controlled parameters (the tool strips and warns): archive_*, restore_command, port, hot_standby, recovery targets, ssl*, synchronous_standby_names, shared_preload_libraries (→ dedicated field), listen/log/file-path settings. Tuning parameters (max_connections, shared_buffers, …) all pass through.
spec.patroni.pg_hbaspec.postgresql.pg_hbatransformCNPG prepends fixed rules and appends host all all all scram-sha-256; Zalando's list replaced the whole file. Spilo-specific lines (pam, standby) are stripped.
spec.patroni.initdbspec.bootstrap.initdbtransformencoding/locale/data-checksums map; only relevant for fresh bootstrap.
spec.patroni.synchronous_modespec.postgresql.synchronoustransform→ {method: any, number: <synchronous_node_count or 1>}; non-strict → dataDurability: preferred, synchronous_mode_strict: true → required.
spec.patroni.slotsspec.replicationSlotsmechanismHA slots are automatic; permanent logical slots for CDC → Publication/Subscription resources or SQL.
spec.patroni.ttl / loop_wait / retry_timeout / maximum_lag_on_failover / failsafe_mode—nonePatroni/DCS tuning has no counterpart (related: spec.failoverDelay, spec.probes).

Pooling, services, networking

ZalandoCloudNativePGKindNotes
spec.enableConnectionPoolerseparate Pooler resourcemechanism⚠ Zalando default pool mode is transaction; the CNPG default is session — set pgbouncer.poolMode: transaction explicitly. Zalando default 2 instances vs CNPG 1. Applications repoint to the Pooler service.
spec.enableReplicaConnectionPoolersecond Pooler with type: romechanism
spec.connectionPooler.*Pooler.spec.*transformnumberOfInstances → instances; mode → pgbouncer.poolMode; maxDBConnections → pgbouncer.parameters; resources/image → pod template.
spec.enableMasterLoadBalancer / enableReplicaLoadBalancerspec.managed.services.additional[]mechanismAdd {selectorType: rw or ro, serviceTemplate: {spec: {type: LoadBalancer}}} — default services are never mutated; service DNS names change.
spec.allowedSourceRanges…serviceTemplate.spec.loadBalancerSourceRangestransform
spec.serviceAnnotations (+ per-role variants)service templates / inheritedMetadata.annotationstransform
spec.podAnnotationsspec.inheritedMetadata.annotationstransformApplies to all generated objects.

Scheduling and pod attributes

ZalandoCloudNativePGKindNotes
spec.nodeAffinityspec.affinity.nodeAffinitydirectCNPG adds anti-affinity controls (podAntiAffinityType, topologyKey).
spec.tolerationsspec.affinity.tolerationsdirectNote the nesting under affinity.
spec.podPriorityClassNamespec.priorityClassNamedirect
spec.schedulerNamespec.schedulerNamedirect
spec.spiloRunAsUser / spiloRunAsGroup / spiloFSGroupspec.postgresUID / postgresGIDtransformCNPG default uid/gid 26 (Spilo used 101); normally drop.
spec.sidecars / spec.initContainers—noneDeliberately unsupported. Metrics sidecar → built-in exporter; init logic → bootstrap.initdb.postInit*SQL.
spec.maintenanceWindows—noneClosest: spec.primaryUpdateStrategy: supervised.

Backup, clone, standby, TLS, CDC

ZalandoCloudNativePGKindNotes
spec.enableLogicalBackup + schedule—noneCNPG backups are physical via ScheduledBackup (⚠ 6-field cron — prepend a seconds field). Keep logical dumps as your own CronJob if needed.
spec.clone (no timestamp)spec.bootstrap.pg_basebackup + externalClustersmechanismClone from a live cluster — works against a running Zalando cluster (a supported migration path).
spec.clone (timestamp / s3 fields)bootstrap.recovery + externalClusters[].barmanObjectStoremechanismOnly from a barman-format archive — Spilo WAL-E/WAL-G archives are unreadable by CNPG.
spec.standby (S3 WAL path)—noneSame archive incompatibility.
spec.standby (host/port)spec.replica + externalClustersmechanismStreaming standby of an external primary; promote by flipping replica.enabled.
spec.tlsspec.certificatestransformOne-secret model splits into server/client(+replication) certificates; SANs must cover <cluster>-rw.<ns>.svc. Simplest: omit and let CNPG self-manage.
spec.streams (CDC)—noneRe-architect on Publication/Subscription resources or external Debezium (wal_level=logical is the CNPG default).

Fork-specific Zalando fields (previous ACP PostgreSQL releases)

Zalando (ACP fork)CloudNativePGNotes
spec.backup (WAL-G schedule/retention/storage)barman-cloud ObjectStore + spec.plugins + ScheduledBackup + retentionPolicyFirst CNPG backup is a fresh full backup.
spec.exporter / enableExporterspec.monitoring (built-in exporter)See the Grafana dashboards guide (How To section).
spec.enablePgpool2—PgBouncer Pooler only; query load-balancing ≈ -ro service + app routing.
spec.clusterReplicationspec.replica + externalClusters (+ promotion/demotion tokens)CNPG replica-cluster (distributed topology) model.
spec.usersCustomizedPasswdmanaged.roles[].passwordSecretMove passwords out of the CR into basic-auth secrets.
spec.ipFamilyPreferservice templates ipFamilies/ipFamilyPolicySingle-stack IPv6 requires the url.Build fix in the operator (see Configuration).

Worked example

Zalando source:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: acid-orders
spec:
  teamId: acid
  numberOfInstances: 3
  postgresql:
    version: "16"
    parameters:
      shared_buffers: 512MB
      max_connections: "300"
  volume:
    size: 20Gi
    storageClass: sc-topolvm
  users:
    orders_svc: [createdb]
    analyst: []
  databases:
    orders: orders_svc
  patroni:
    pg_hba: [host all all 10.0.0.0/8 md5]
    synchronous_mode: true
    synchronous_node_count: 1
  resources:
    requests: {cpu: "1", memory: 2Gi}
    limits: {cpu: "2", memory: 4Gi}
  enableConnectionPooler: true

Converted (what the tool emits — a Cluster plus a Pooler):

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: acid-orders
spec:
  instances: 3
  imageName: <postgresql-16-operand-image>   # per your platform registry
  inheritedMetadata:
    labels:
      acid.zalan.do/team: acid
  bootstrap:
    initdb:
      database: orders
      owner: orders_svc
  managed:
    roles:
      - {name: analyst, ensure: present, login: true}
      - {name: orders_svc, ensure: present, login: true, createdb: true}
  postgresql:
    parameters:
      shared_buffers: 512MB
      max_connections: "300"
    pg_hba: [host all all 10.0.0.0/8 md5]
    synchronous:
      method: any
      number: 1
      dataDurability: preferred   # synchronous_mode without 'strict'
  storage: {size: 20Gi, storageClass: sc-topolvm}
  resources:
    requests: {cpu: "1", memory: 2Gi}
    limits: {cpu: "2", memory: 4Gi}
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
  name: acid-orders-pooler-rw
spec:
  cluster: {name: acid-orders}
  type: rw
  instances: 2                   # Zalando default
  pgbouncer:
    poolMode: transaction        # Zalando default (CNPG default is session!)

This exact conversion was verified end-to-end during release qualification: the converted manifests deployed to a healthy 3-instance cluster, with the bootstrap database/owner, role flags, synchronous replication (ANY 1 (...)), parameters, and pg_hba verified by SQL, and writes executed through the Pooler in transaction mode.

What changes for the application:

ZalandoCloudNativePG
write endpointacid-orders.<ns>.svcacid-orders-rw.<ns>.svc (or the Pooler service)
read endpointacid-orders-repl.<ns>.svcacid-orders-ro.<ns>.svc
credentialsorders_svc.acid-orders.credentials... secretacid-orders-app (bootstrap owner) / your basic-auth secrets

Trademark Notice

CloudNativePG™ is a trademark of The Linux Foundation.

PostgreSQL® is a registered trademark of the PostgreSQL Community Association of Canada.

Alauda is an independent vendor. This product is not affiliated with, endorsed by, or sponsored by The Linux Foundation, PostgreSQL Community Association of Canada. All trademarks are the property of their respective owners and are used here for identification purposes only.