Companion code for the Automate logical databases with distinct roles in Postgres blog post.
This Pulumi program demonstrates how to automate the setup of isolated logical PostgreSQL databases on a PlanetScale Postgres cluster. It creates multiple databases (e.g. blog, todo), each with a dedicated application role that can only connect to its own database, enforcing strict tenant isolation at the Postgres level.
- Creates a bootstrap role with
postgres-inherited privileges for Pulumi to manage resources. - Creates logical databases (
blog,todo) on the PlanetScale Postgres branch. - Revokes
CONNECTfromPUBLICon all databases so new roles have no access by default. - Creates per-application roles (
blog_app,todo_app) via PlanetScale with read/write privileges. - Grants each app role
CONNECTandCREATEonly on its designated database. - Explicitly revokes each app role from the
postgresdatabase and from peer databases. - Exports direct (port 5432) and pooled (port 6432) connection URLs for each application.
- Node.js (v18+)
- pnpm
- Pulumi CLI
- A PlanetScale account with a Postgres database cluster
- A PlanetScale service token with permissions to manage branches and roles
git clone https://github.com/planetscale/tutorial-pulumi.git
cd tutorial-pulumi
pnpm installGenerate the PlanetScale provider SDK locally. This creates the sdks/planetscale/ directory.
pulumi package add terraform-provider planetscale/planetscalepulumi stack init devSet the configuration values for your PlanetScale organization and cluster. You will need a service token.
pulumi config set organization "<organization-name>"
pulumi config set clusterName "<database-cluster-name>"
pulumi config set branch "main"
pulumi config set importBranch true
pulumi config set --secret planetScaleServiceToken "pscale_tkn_..."
pulumi config set --plaintext planetScaleServiceTokenId "p..."| Config key | Description |
|---|---|
organization |
Your PlanetScale organization slug |
clusterName |
The name of your PlanetScale Postgres database cluster |
branch |
The Postgres branch to target (default: main) |
importBranch |
Set to true to use an existing branch, false to create one |
planetScaleServiceToken |
PlanetScale service token (stored as a Pulumi secret) |
planetScaleServiceTokenId |
The ID of the service token |
clusterSize |
Required only when importBranch is false (e.g. PS_10_AWS_ARM) |
pulumi upAfter deployment, Pulumi will output connection URLs for each application database.
To add or remove application databases, edit the appDatabases array in lib/services.ts:
export const appDatabases: string[] = ["blog", "todo"];Each entry creates a logical database and a corresponding <name>_app role.
This repository is published as companion code for a tutorial blog post. It is not actively accepting contributions, but you are welcome to open an issue if you have a question or find a problem.
This project is licensed under the Apache License 2.0.