CapyDB/ docs
GuidesImports & Migrations

Migrate from Azure Database for PostgreSQL

Move an Azure Flexible Server database into CapyDB.

This covers Flexible Server. Single Server is retired; if you are still on it, the shape below still works, but the parameter names differ and Microsoft's own guidance is to move to Flexible Server first.

Get the source connection string

From the portal's Connect blade, or:

az postgres flexible-server show --name your-server --resource-group your-rg --query fullyQualifiedDomainName -o tsv
postgres://adminuser:password@your-server.postgres.database.azure.com:5432/dbname?sslmode=require

Azure requires TLS, which the importer sets by default.

Reachability

Flexible Server is either public access with a firewall allowlist, or private access inside a VNet. The importer connects from the CapyDB control plane, so a private-access server is not reachable and you will need a dump-file import instead. For a public-access server, add a firewall rule for the import window and remove it afterwards.

Azure-specific caveats

  • The admin user is not a superuser. It is a member of azure_pg_admin. Event triggers and extensions outside Azure's allowlist do not move; the preflight names them.
  • azure.extensions controls which extensions can be created at all, so what you have installed is already a subset - usually a small one.
  • Server parameters, not postgresql.conf. Everything below is changed in the portal's Server parameters blade or with az postgres flexible-server parameter set.

For a near-zero-downtime import

A streaming import needs logical replication, which is off by default:

az postgres flexible-server parameter set \
  --name wal_level --value logical \
  --server-name your-server --resource-group your-rg

az postgres flexible-server restart --name your-server --resource-group your-rg

Then give the migration role the replication attribute:

ALTER ROLE migration_user WITH REPLICATION;
GRANT azure_pg_admin TO migration_user;

Confirm it took effect before planning the window:

capydb migrate scan --source-url "$AZURE_DATABASE_URL"

If wal_level is still replica, the restart has not happened yet - Azure applies static parameters on restart, not on save.

Preflight and import

capydb import preflight --project your-project --source-url "$AZURE_DATABASE_URL"

# streaming, if the scan above says the source is ready
capydb import --project your-project --source-url "$AZURE_DATABASE_URL" --follow
capydb import follow-status --project your-project
capydb import cutover --project your-project

If logical replication is not available to you, dump and restore inside a maintenance window instead.

After the import

  1. \dx for extensions, and re-enable on the project anything the restore could not create.
  2. Spot-check sequences.
  3. ANALYZE;
  4. Swap the connection string in every consumer - capydb doctor catches environment files still pointing at Azure - then remove the temporary firewall rule.