Skip to content

Onboard a tenant in one deploy

A customer signs up at 4pm. Their tenant database doesn’t exist yet. The old dance: someone runs CREATE DATABASE, waits, then runs the deploy — two steps, two chances to fumble, and a tenant sitting half-born if you get pulled away between them.

Hey folks. I’m Forge Barrett, master of the Content Forge here at SchemaSmith.

Back in Module 1 you onboarded a tenant by hand — you ran the CREATE DATABASE, then discovery found it. Module 2 handed the roster to your config. Today we close the loop: name a tenant that doesn’t exist yet, flip one flag, and SchemaSmith forges the database and the schema in a single run. Let’s fire it up.

Safe by default — a missing tenant is left alone

Section titled “Safe by default — a missing tenant is left alone”

Start where Module 2 left off: a config roster. This one names an existing tenant and one that doesn’t exist yet — fleet_tenant_006. Deploy it with nothing else set:

Terminal window
schemaquench --ConfigFile:quench.settings.skip.json
[localhost,11433] Database 'fleet_tenant_006' does not exist and TemplateTargets CreateIfMissing is false - skipping all iterations for this server-database pair.

001 deploys; 006 is skipped, and — this is the part that matters — not created. SchemaSmith never conjures a database you didn’t explicitly ask it to. The default is to leave gaps alone. Creating one is something you opt into.

The opt-in is one flag on the roster: CreateIfMissing. Here it is in quench.settings.onboard.json:

"TemplateTargets": {
"Main": { "Databases": [ "fleet_tenant_001", "fleet_tenant_006" ], "CreateIfMissing": true }
}

Before you let it create anything, dry-run it. Same flag, but under WhatIf:

Terminal window
schemaquench --ConfigFile:quench.settings.whatif.json
[WhatIf] Would create database [fleet_tenant_006] (CreateIfMissing: true)

It tells you exactly what it would forge — and touches nothing. Check the catalog after and 006 still isn’t there. That’s your look-before-you-leap, now on the create itself.

Onboard — provision and deploy in one strike

Section titled “Onboard — provision and deploy in one strike”

Now the real run:

Terminal window
schemaquench --ConfigFile:quench.settings.onboard.json
Creating database [fleet_tenant_006] (CreateIfMissing: true)

SchemaSmith creates fleet_tenant_006 on the admin connection, kindles the forge inside it, and strikes the whole Shop schema — four tables — into the fresh database. 001 is a no-op. One command took a tenant from doesn’t exist to fully forged. No hand-run DDL, no second step, no half-born database. Add the tenant to the roster, quench, done.

Run it again:

Terminal window
schemaquench --ConfigFile:quench.settings.onboard.json

No Creating database line this time. Under the hood the create is IF NOT EXISTS — a real existence check on PostgreSQL — so a database that already exists is left exactly as-is. CreateIfMissing only ever fills gaps, which means you can leave it on permanently. Every run onboards whatever’s new and no-ops everything that isn’t.

Creating a database is a privileged strike

Section titled “Creating a database is a privileged strike”

Standing up a database is a high-privilege act, and SchemaSmith says so plainly when the deploy account can’t. Run the onboard as a principal that lacks the create right, and it stops before it touches anything — with a message that names the database and the missing privilege:

[localhost,11433] Database provisioning FAILED for 'fleet_tenant_006' (template 'Main'): Failed to provision database 'fleet_tenant_006'. The connecting account must have CREATE DATABASE permission on the admin database (master). Underlying error: CREATE DATABASE permission denied in database 'master'.

No silent skip. No mystery failure. The hammer stays holstered, and the error tells you the grant to ask for. What it’s called differs by engine:

EngineAdmin databaseRequired privilegeUnderlying error
SQL ServermasterCREATE DATABASE (or dbcreator)CREATE DATABASE permission denied in database 'master'
PostgreSQLpostgresCREATEDB42501: permission denied to create database
MySQLinformation_schemaCREATEAccess denied … to database 'fleet_tenant_006'

The account that onboards tenants needs rights for everything it does — reading the catalog to check the server and creating the database. A reader-and-writer without the create grant lands right here, told exactly what’s missing.

CreateIfMissing isn’t for every run. When your tenant databases are provisioned by another system — a control plane, an infrastructure pipeline — leave it off and let those own the create; SchemaSmith’s default skip-with-log keeps a typo’d tenant name from silently spawning a database. Turn it on when the deploy is your onboarding path: the roster is your tenant list, and adding a row should stand the tenant up. One tool, one run, one source of truth.

Check yourself: Your roster names five tenants with CreateIfMissing: true. Four exist; one is brand-new. You run the deploy twice. What does the second run create?

Nothing. The first run creates the one new database (and forges the schema into it); the four that existed are no-ops. The second run finds all five already present — the create is IF NOT EXISTS under the hood — so it creates nothing and reconciles everything to a clean no-op. That’s why CreateIfMissing is safe to leave on: it only ever fills a gap, and there’s no gap left to fill.


A smith doesn’t wait on someone else to cast the blank before he can work. He pulls the iron, heats it, and shapes the piece in one pass at the fire. That’s onboarding a tenant here — the database and its schema come off the same heat, struck in a single run, and the day you don’t have the right to work the forge, the tool tells you plainly instead of leaving cold iron on the floor.

Onboarding tenants by hand and wishing the deploy just did it? Email me at forgebarrett@schemasmith.com — tell me how a new tenant gets its database today, and I’ll show you where CreateIfMissing fits.

Next up: Course 7 · Module 4 — Operating the fleet safely, where you preview a thousand-tenant run before you pull the trigger, tune how hard it hits, and keep going when a single tenant misbehaves.

Until then, may every new tenant rise on the first heat, your onboarding cost but a single strike, and your grants always match your reach.

— Forge