Managed Databases ยท PostgreSQL
A cluster is one logical PostgreSQL database.
One primary node plus zero or more async read replicas, managed as a single resource. Excloud provisions the nodes, wires up replication, and hands you a hostname and a password. There's no separate CLI today โ one API call at database.excloud.in, the console, or Terraform when those resources land.
$ curl -sS -X POST \ https://database.excloud.in/database/cluster/create \ -H "Authorization: Bearer $TOKEN" \ -d '{"name":"app-prod","image_id":1, "instance_type":"m1a.xlarge","subnet_id":1, "zone_id":1,"project_id":1, "allocate_public_ipv4":false}' โ created โ hostname assigned, stable across restarts
Cluster model
A hostname that outlives every failover.
The hostname returned at create time is stable for the life of the cluster โ it doesn't change across restarts, password rotations, or when you add a node. Restart rolls every node, replicas first, then the primary with a failover; typical primary downtime is a few seconds. Your app should resolve the hostname and reconnect on failure, not cache the underlying IP.
- Default user is postgres, default port 5432
- is_multi_az provisions two standbys at create time
- Add replicas later with /database/node/add โ replication reconfigures automatically
- Terminate is irreversible and drops the DNS record for the hostname
$ psql "postgres://postgres:<password>@app-prod-xxxx.db.excloud.dev:5432/postgres" psql (16.x) Type "help" for help. postgres=#
Credentials
The password surfaces exactly twice: create and reset.
postgres_password comes back in the create response and on an explicit reset โ never on a plain list call. Move it into Secrets immediately so every consumer reads it from one place, then rotate without an outage: reveal the current value, call resetpassword, update the secret, and restart your app so it re-fetches. Apps that cache the password forever start failing the moment the reset lands.
$ exc secret create --path db/app-prod/postgres --from-stdin paste the password, then Ctrl-D $ PG_PASSWORD=$(exc secret reveal --path db/app-prod/postgres) # after a resetpassword call: $ exc secret version add --path db/app-prod/postgres --from-stdin
Lifecycle
Five cluster operations, five scoped permissions.
Create, list, restart, terminate, and reset password each carry a distinct permission scoped to exc:database:cluster/<id>. Grant what the role actually needs.
| Action | Required permission |
|---|---|
| Create | database:cluster:create |
| List | database:cluster:list |
| Restart | database:cluster:restart |
| Terminate | database:cluster:terminate |
| Reset password | database:cluster:resetpassword |
Full list in the permissions reference.
Get started
A running PostgreSQL primary is a single API call away.
Post to the create endpoint, copy the hostname and password from the response, and connect with psql. The cluster is yours to keep or terminate.