A very simple Kubernetes operator that can create PostgreSQL databases + roles as native Kubernetes resources. This operator can be used to automate manual Postgres operations. This project has been built for our company's innoweek to learn about writing your own operator. Wanted to make it open-source in case it helps anyone!
Create a PostgresDatabase custom resource and the operator will:
- Create the database on your PostgreSQL server
- Create an admin role with full privileges
- Optionally create a read-only role with
SELECT-only access - Write connection credentials into a Kubernetes
Secretin the same namespace as the resource
Create a secret with your PostgreSQL password:
kubectl create secret generic postgres-credentials \
--from-literal=password=<your-postgres-password>Create a values.yaml:
postgres:
host: <pg-host>
user: <pg-user>
password:
existingSecret: postgres-credentialsInstall the Helm chart:
helm upgrade --install postgres-db-admin-operator \
oci://ghcr.io/nielstenboom/charts/postgres-db-admin-operator \
-f values.yamlapiVersion: postgresdbadminoperator.github.io/v1
kind: PostgresDatabase
metadata:
name: my-app
namespace: default
# optional: uncommment if you also want a read-only user
# to be created alongside the admin user
# spec:
# createReadOnlyUser: truekubectl apply -f database.yamlOnce reconciled, the operator writes a Secret named my-app-credentials in the same namespace:
$ kubectl get secret my-app-credentials -o yaml
apiVersion: v1
data:
admin-database-url: postgresql://xxx
admin-password: xxx
admin-username: xxx
dbname: my-app
host: <pg-host>
port: 5432
readonly-database-url: postgresql://xxx
readonly-password: xxx
readonly-username: xxx
kind: Secret
metadata:
creationTimestamp: "2026-04-01T09:15:05Z"
name: my-app-credentials
namespace: default
type: OpaqueThe readonly-* keys are only present when createReadOnlyUser: true.
| Value | Description | Default |
|---|---|---|
postgres.host |
PostgreSQL host | "" |
postgres.port |
PostgreSQL port | 5432 |
postgres.user |
PostgreSQL superuser | "" |
postgres.password.existingSecret |
Name of the secret containing the password | "" |
postgres.password.secretKey |
Key within the secret | "password" |
cleanupOnDelete |
Drop database and roles when the resource is deleted | false |
- Docker
- kind
- kubectl + helm
- uv
| Command | Description |
|---|---|
make init |
Create a local kind cluster and deploy PostgreSQL into it |
make deploy |
Build the image, load it into kind, and install/upgrade the Helm chart |
make port-forward |
Port-forward PostgreSQL to localhost:5432 |
make test |
Run the test suite (requires Docker) |
make destroy |
Tear down the kind cluster |
make init
make port-forward &
PG_HOST=localhost PG_USER=postgres PG_PASSWORD=devpassword \
uv run kopf run src/postgres_db_admin_operator/main.py --all-namespaces