Skip to content

feat(balancer): declare the cnpg balancer role and Database - #183

Draft
TineoC wants to merge 2 commits into
CodeForPhilly:mainfrom
TineoC:feat/balancer-cnpg-database
Draft

feat(balancer): declare the cnpg balancer role and Database#183
TineoC wants to merge 2 commits into
CodeForPhilly:mainfrom
TineoC:feat/balancer-cnpg-database

Conversation

@TineoC

@TineoC TineoC commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Step 4 (continued) of CodeForPhilly/balancer-main#526. Creates an empty balancer database on shared-cluster with pgvector enabled, so the RDS dump has somewhere to land.

Still no cutover. The app's sealed SQL_HOST is untouched; production keeps reading from AWS RDS after this merges.

Stacked on #182. It branches from that PR, so the diff below includes its commit. Merge #182 first and this rebases to just the second commit. Draft until then — and until the credentials Secret exists (see blocker below).

What changed

balancer/ splits into app/ + cnpg/, matching cfp-sandbox-cluster. The Database CR must stay in the cloudnative-pg namespace — cnpg requires it beside the Cluster it targets — so it cannot sit under the kustomization that rewrites everything to balancer. The existing balancer/kustomization.yaml moves to balancer/app/ unchanged, and its holomapping moves with it (.holo/branches/k8s-manifests/balancer/app/manifests.toml). The new top-level kustomization just composes the two, setting no namespace of its own.

balancer/cnpg/database.yamlDatabase/balancer, owner balancer, with:

extensions:
  - name: vector
    ensure: present

That answers the "is pgvector available on the CfP database?" question from the original Slack thread. It has to go through Database.spec.extensions rather than a CREATE EXTENSION — the balancer role has no SUPERUSER, so cnpg-controller runs it as postgres. Sandbox verified vector 0.8.2 this way.

_infra/cloudnative-pg/shared-cluster.yaml — adds the managed.roles entry deferred out of #182.

Blocker before this can merge

balancer-db-credentials must be sealed into cloudnative-pg.secrets/ first. Until that Secret exists, cnpg reports a role reconcile error. It needs cluster access, so it is not something I can deliver as a PR.

Gotcha from cfp-sandbox-cluster#162, worth having in hand: cnpg does not pick up a newly-created passwordSecret on its periodic resync. A two-hour wait produced nothing; this reconciled in seconds:

kubectl annotate cluster -n cloudnative-pg shared-cluster \
  cnpg.io/reconciliationLoop="$(date +%s)" --overwrite

Verification after deploy

kubectl -n cloudnative-pg get database balancer -o jsonpath='{.status.applied}'         # true
kubectl -n cloudnative-pg get database balancer -o jsonpath='{.status.extensions[0].applied}'  # true
kubectl -n cloudnative-pg exec shared-cluster-1 -- psql -d balancer -tAc "select extname, extversion from pg_extension"
kubectl -n balancer get pods    # unchanged, still pointed at RDS

Last line is the one that matters: nothing about the running app should move.

Next, once this is in

pg_dump RDS → pg_restore into this database → per-table n_live_tup parity check against RDS → only then re-seal balancer-config with the cnpg host and bump the image off 1.1.5. And an object store + ScheduledBackup before this cluster holds the only copy of anything.

TineoC added 2 commits August 13, 2026 00:26
First half of moving Balancer off AWS RDS (CodeForPhilly/balancer-main#526).
Production still reads from RDS; this only stands the cluster up beside it.

Mirrors cfp-sandbox-cluster's layout: chart v0.28.0 as a holosource, projected
to _infra/cloudnative-pg/operator and rendered by a helm3 lens with CRDs
included; the Cluster CR and namespace sit outside the lens root and pass
through raw.

Two deliberate omissions, both documented inline:
  - no managed.roles — the balancer role's passwordSecret must be sealed first,
    or cnpg reports a reconcile error until it exists
  - no backup stanza — needs an object store and credentials that do not exist
    yet. Nothing may depend on this cluster as a sole copy until that lands.

Storage class is pinned to linode-block-storage-retain rather than taking the
cluster default, which sandbox does.

Refs CodeForPhilly/balancer-main#526
Second half of standing cnpg up for Balancer (CodeForPhilly/balancer-main#526).
Creates an empty `balancer` database on shared-cluster with pgvector enabled,
so the RDS dump has somewhere to be restored to. Still no cutover: the app's
sealed SQL_HOST is untouched and production keeps reading from RDS.

Splits balancer/ into app/ + cnpg/ to match cfp-sandbox-cluster. The Database CR
has to stay in the cloudnative-pg namespace — cnpg requires it to sit beside the
Cluster it targets — so it cannot live under the kustomization that rewrites
everything to `balancer`. The existing kustomization moves to app/ unchanged,
along with its holomapping.

The managed role names balancer-db-credentials, which must be sealed into
cloudnative-pg.secrets/ before this merges or cnpg will report a role reconcile
error. Note cnpg does not pick up a newly-created passwordSecret on its periodic
resync — force it with:

  kubectl annotate cluster -n cloudnative-pg shared-cluster \
    cnpg.io/reconciliationLoop="$(date +%s)" --overwrite

Refs CodeForPhilly/balancer-main#526, CodeForPhilly/cfp-sandbox-cluster#162
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant