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 tsvpostgres://adminuser:password@your-server.postgres.database.azure.com:5432/dbname?sslmode=requireAzure 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.extensionscontrols 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 withaz 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-rgThen 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-projectIf logical replication is not available to you, dump and restore inside a maintenance window instead.
After the import
\dxfor extensions, and re-enable on the project anything the restore could not create.- Spot-check sequences.
ANALYZE;- Swap the connection string in every consumer -
capydb doctorcatches environment files still pointing at Azure - then remove the temporary firewall rule.