Manage Azure Database for PostgreSQL Migrations

The azure-native:dbforpostgresql:Migration resource, part of the Pulumi Azure Native provider, defines a PostgreSQL database migration from a source server to an Azure Database for PostgreSQL Flexible Server target. This guide focuses on three capabilities: validation and full migration modes, custom authentication and network connectivity, and role and permission migration.

Migrations require both source and target PostgreSQL servers to exist, and may reference a migration instance flexible server for private endpoint scenarios. The examples are intentionally small. Combine them with your own server infrastructure, network configuration, and credential management.

Validate migration compatibility without moving data

Before committing to a full migration, teams run validation checks to identify schema incompatibilities, permission issues, or configuration problems.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    migrationOption: azure_native.dbforpostgresql.MigrationOption.Validate,
    overwriteDbsInTarget: azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.True,
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "examplesourcepassword",
            targetServerPassword: "exampletargetpassword",
        },
    },
    serverName: "exampleserver",
    sourceDbServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    migration_option=azure_native.dbforpostgresql.MigrationOption.VALIDATE,
    overwrite_dbs_in_target=azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.TRUE,
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "examplesourcepassword",
            "target_server_password": "exampletargetpassword",
        },
    },
    server_name="exampleserver",
    source_db_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:             pulumi.String("eastus"),
			MigrationMode:        pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:        pulumi.String("examplemigration"),
			MigrationOption:      pulumi.String(dbforpostgresql.MigrationOptionValidate),
			OverwriteDbsInTarget: pulumi.String(dbforpostgresql.OverwriteDatabasesOnTargetServerTrue),
			ResourceGroupName:    pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("examplesourcepassword"),
					TargetServerPassword: pulumi.String("exampletargetpassword"),
				},
			},
			ServerName:               pulumi.String("exampleserver"),
			SourceDbServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        MigrationOption = AzureNative.DBforPostgreSQL.MigrationOption.Validate,
        OverwriteDbsInTarget = AzureNative.DBforPostgreSQL.OverwriteDatabasesOnTargetServer.True,
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "examplesourcepassword",
                TargetServerPassword = "exampletargetpassword",
            },
        },
        ServerName = "exampleserver",
        SourceDbServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .migrationOption("Validate")
            .overwriteDbsInTarget("True")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("examplesourcepassword")
                    .targetServerPassword("exampletargetpassword")
                    .build())
                .build())
            .serverName("exampleserver")
            .sourceDbServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrationMode: Offline
      migrationName: examplemigration
      migrationOption: Validate
      overwriteDbsInTarget: True
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: examplesourcepassword
          targetServerPassword: exampletargetpassword
      serverName: exampleserver
      sourceDbServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource

The migrationOption property set to “Validate” runs compatibility checks without transferring data. The migrationMode specifies “Offline” (the migration requires downtime). The dbsToMigrate array lists databases to validate, and secretParameters provides admin credentials for both source and target servers. The sourceDbServerResourceId identifies the source server by its Azure resource ID.

Specify custom admin usernames for source and target

When source and target servers use different admin accounts, you need to explicitly provide both usernames.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "examplesourcepassword",
            targetServerPassword: "exampletargetpassword",
        },
        sourceServerUsername: "newadmin@examplesource",
        targetServerUsername: "targetadmin",
    },
    serverName: "exampleserver",
    sourceDbServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "examplesourcepassword",
            "target_server_password": "exampletargetpassword",
        },
        "source_server_username": "newadmin@examplesource",
        "target_server_username": "targetadmin",
    },
    server_name="exampleserver",
    source_db_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:          pulumi.String("eastus"),
			MigrationMode:     pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:     pulumi.String("examplemigration"),
			ResourceGroupName: pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("examplesourcepassword"),
					TargetServerPassword: pulumi.String("exampletargetpassword"),
				},
				SourceServerUsername: pulumi.String("newadmin@examplesource"),
				TargetServerUsername: pulumi.String("targetadmin"),
			},
			ServerName:               pulumi.String("exampleserver"),
			SourceDbServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "examplesourcepassword",
                TargetServerPassword = "exampletargetpassword",
            },
            SourceServerUsername = "newadmin@examplesource",
            TargetServerUsername = "targetadmin",
        },
        ServerName = "exampleserver",
        SourceDbServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("examplesourcepassword")
                    .targetServerPassword("exampletargetpassword")
                    .build())
                .sourceServerUsername("newadmin@examplesource")
                .targetServerUsername("targetadmin")
                .build())
            .serverName("exampleserver")
            .sourceDbServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrationMode: Offline
      migrationName: examplemigration
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: examplesourcepassword
          targetServerPassword: exampletargetpassword
        sourceServerUsername: newadmin@examplesource
        targetServerUsername: targetadmin
      serverName: exampleserver
      sourceDbServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource

The sourceServerUsername and targetServerUsername properties in secretParameters specify the admin accounts to use for connecting to each server. This is necessary when the default admin username differs from the server’s configured admin, or when migrating between servers with different naming conventions (e.g., “newadmin@examplesource” for Single Server vs “targetadmin” for Flexible Server).

Override DNS resolution with custom FQDNs

In private network scenarios or when using custom DNS, the migration service may need explicit FQDNs instead of relying on Azure’s default name resolution.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    overwriteDbsInTarget: azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.True,
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "xxxxxxxx",
            targetServerPassword: "xxxxxxxx",
        },
    },
    serverName: "exampleserver",
    sourceDbServerFullyQualifiedDomainName: "examplesource.contoso.com",
    sourceDbServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    targetDbServerFullyQualifiedDomainName: "exampletarget.contoso.com",
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    overwrite_dbs_in_target=azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.TRUE,
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "xxxxxxxx",
            "target_server_password": "xxxxxxxx",
        },
    },
    server_name="exampleserver",
    source_db_server_fully_qualified_domain_name="examplesource.contoso.com",
    source_db_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    target_db_server_fully_qualified_domain_name="exampletarget.contoso.com")
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:             pulumi.String("eastus"),
			MigrationMode:        pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:        pulumi.String("examplemigration"),
			OverwriteDbsInTarget: pulumi.String(dbforpostgresql.OverwriteDatabasesOnTargetServerTrue),
			ResourceGroupName:    pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("xxxxxxxx"),
					TargetServerPassword: pulumi.String("xxxxxxxx"),
				},
			},
			ServerName:                             pulumi.String("exampleserver"),
			SourceDbServerFullyQualifiedDomainName: pulumi.String("examplesource.contoso.com"),
			SourceDbServerResourceId:               pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource"),
			TargetDbServerFullyQualifiedDomainName: pulumi.String("exampletarget.contoso.com"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        OverwriteDbsInTarget = AzureNative.DBforPostgreSQL.OverwriteDatabasesOnTargetServer.True,
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "xxxxxxxx",
                TargetServerPassword = "xxxxxxxx",
            },
        },
        ServerName = "exampleserver",
        SourceDbServerFullyQualifiedDomainName = "examplesource.contoso.com",
        SourceDbServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
        TargetDbServerFullyQualifiedDomainName = "exampletarget.contoso.com",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .overwriteDbsInTarget("True")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("xxxxxxxx")
                    .targetServerPassword("xxxxxxxx")
                    .build())
                .build())
            .serverName("exampleserver")
            .sourceDbServerFullyQualifiedDomainName("examplesource.contoso.com")
            .sourceDbServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
            .targetDbServerFullyQualifiedDomainName("exampletarget.contoso.com")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrationMode: Offline
      migrationName: examplemigration
      overwriteDbsInTarget: True
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: xxxxxxxx
          targetServerPassword: xxxxxxxx
      serverName: exampleserver
      sourceDbServerFullyQualifiedDomainName: examplesource.contoso.com
      sourceDbServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource
      targetDbServerFullyQualifiedDomainName: exampletarget.contoso.com

The sourceDbServerFullyQualifiedDomainName and targetDbServerFullyQualifiedDomainName properties provide explicit domain names for connecting to source and target servers. When provided, the migration service always uses these FQDNs instead of resolving names through Azure DNS. This is useful in private networking scenarios or when servers are behind custom DNS configurations.

Migrate from on-premises or non-Azure PostgreSQL

Migrations often originate from on-premises servers, AWS RDS, GCP CloudSQL, or other non-Azure PostgreSQL deployments.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    migrationOption: azure_native.dbforpostgresql.MigrationOption.ValidateAndMigrate,
    overwriteDbsInTarget: azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.True,
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "examplesourcepassword",
            targetServerPassword: "exampletargetpassword",
        },
    },
    serverName: "exampleserver",
    sourceDbServerResourceId: "examplesource:5432@exampleuser",
    sourceType: azure_native.dbforpostgresql.SourceType.OnPremises,
    sslMode: azure_native.dbforpostgresql.SslMode.Prefer,
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    migration_option=azure_native.dbforpostgresql.MigrationOption.VALIDATE_AND_MIGRATE,
    overwrite_dbs_in_target=azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.TRUE,
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "examplesourcepassword",
            "target_server_password": "exampletargetpassword",
        },
    },
    server_name="exampleserver",
    source_db_server_resource_id="examplesource:5432@exampleuser",
    source_type=azure_native.dbforpostgresql.SourceType.ON_PREMISES,
    ssl_mode=azure_native.dbforpostgresql.SslMode.PREFER)
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:             pulumi.String("eastus"),
			MigrationMode:        pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:        pulumi.String("examplemigration"),
			MigrationOption:      pulumi.String(dbforpostgresql.MigrationOptionValidateAndMigrate),
			OverwriteDbsInTarget: pulumi.String(dbforpostgresql.OverwriteDatabasesOnTargetServerTrue),
			ResourceGroupName:    pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("examplesourcepassword"),
					TargetServerPassword: pulumi.String("exampletargetpassword"),
				},
			},
			ServerName:               pulumi.String("exampleserver"),
			SourceDbServerResourceId: pulumi.String("examplesource:5432@exampleuser"),
			SourceType:               pulumi.String(dbforpostgresql.SourceTypeOnPremises),
			SslMode:                  pulumi.String(dbforpostgresql.SslModePrefer),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        MigrationOption = AzureNative.DBforPostgreSQL.MigrationOption.ValidateAndMigrate,
        OverwriteDbsInTarget = AzureNative.DBforPostgreSQL.OverwriteDatabasesOnTargetServer.True,
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "examplesourcepassword",
                TargetServerPassword = "exampletargetpassword",
            },
        },
        ServerName = "exampleserver",
        SourceDbServerResourceId = "examplesource:5432@exampleuser",
        SourceType = AzureNative.DBforPostgreSQL.SourceType.OnPremises,
        SslMode = AzureNative.DBforPostgreSQL.SslMode.Prefer,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .migrationOption("ValidateAndMigrate")
            .overwriteDbsInTarget("True")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("examplesourcepassword")
                    .targetServerPassword("exampletargetpassword")
                    .build())
                .build())
            .serverName("exampleserver")
            .sourceDbServerResourceId("examplesource:5432@exampleuser")
            .sourceType("OnPremises")
            .sslMode("Prefer")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrationMode: Offline
      migrationName: examplemigration
      migrationOption: ValidateAndMigrate
      overwriteDbsInTarget: True
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: examplesourcepassword
          targetServerPassword: exampletargetpassword
      serverName: exampleserver
      sourceDbServerResourceId: examplesource:5432@exampleuser
      sourceType: OnPremises
      sslMode: Prefer

The sourceType property specifies the source server type (e.g., “OnPremises”, “AWS_RDS”, “GCP_CloudSQL”). For non-Azure sources, the sourceDbServerResourceId uses a connection string format “hostname:port@username” instead of an Azure resource ID. The sslMode property controls SSL/TLS behavior; “Prefer” attempts SSL but falls back to unencrypted if unavailable. The migrationOption “ValidateAndMigrate” runs validation checks before starting the data transfer.

Route migration through a private endpoint instance

When source or target servers are in private networks without public endpoints, the migration service needs a dedicated migration instance to reach both servers.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrationInstanceResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration",
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    overwriteDbsInTarget: azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.True,
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "examplesourcepassword",
            targetServerPassword: "exampletargetpassword",
        },
    },
    serverName: "exampleserver",
    sourceDbServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migration_instance_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration",
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    overwrite_dbs_in_target=azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.TRUE,
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "examplesourcepassword",
            "target_server_password": "exampletargetpassword",
        },
    },
    server_name="exampleserver",
    source_db_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:                    pulumi.String("eastus"),
			MigrationInstanceResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration"),
			MigrationMode:               pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:               pulumi.String("examplemigration"),
			OverwriteDbsInTarget:        pulumi.String(dbforpostgresql.OverwriteDatabasesOnTargetServerTrue),
			ResourceGroupName:           pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("examplesourcepassword"),
					TargetServerPassword: pulumi.String("exampletargetpassword"),
				},
			},
			ServerName:               pulumi.String("exampleserver"),
			SourceDbServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrationInstanceResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration",
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        OverwriteDbsInTarget = AzureNative.DBforPostgreSQL.OverwriteDatabasesOnTargetServer.True,
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "examplesourcepassword",
                TargetServerPassword = "exampletargetpassword",
            },
        },
        ServerName = "exampleserver",
        SourceDbServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrationInstanceResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .overwriteDbsInTarget("True")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("examplesourcepassword")
                    .targetServerPassword("exampletargetpassword")
                    .build())
                .build())
            .serverName("exampleserver")
            .sourceDbServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrationInstanceResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/flexibleServers/examplesourcemigration
      migrationMode: Offline
      migrationName: examplemigration
      overwriteDbsInTarget: True
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: examplesourcepassword
          targetServerPassword: exampletargetpassword
      serverName: exampleserver
      sourceDbServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource

The migrationInstanceResourceId references a flexible server configured as a migration instance with private endpoint connectivity. This instance acts as a bridge, allowing the migration service to reach servers in private VNets. The migration instance must have network access to both source and target servers.

Include database roles and permissions in migration

Applications often depend on specific database roles, grants, and permissions beyond just schema and data.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const migration = new azure_native.dbforpostgresql.Migration("migration", {
    dbsToMigrate: [
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location: "eastus",
    migrateRoles: azure_native.dbforpostgresql.MigrateRolesAndPermissions.True,
    migrationMode: azure_native.dbforpostgresql.MigrationMode.Offline,
    migrationName: "examplemigration",
    overwriteDbsInTarget: azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.True,
    resourceGroupName: "exampleresourcegroup",
    secretParameters: {
        adminCredentials: {
            sourceServerPassword: "examplesourcepassword",
            targetServerPassword: "exampletargetpassword",
        },
    },
    serverName: "exampleserver",
    sourceDbServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
});
import pulumi
import pulumi_azure_native as azure_native

migration = azure_native.dbforpostgresql.Migration("migration",
    dbs_to_migrate=[
        "exampledatabase1",
        "exampledatabase2",
        "exampledatabase3",
        "exampledatabase4",
    ],
    location="eastus",
    migrate_roles=azure_native.dbforpostgresql.MigrateRolesAndPermissions.TRUE,
    migration_mode=azure_native.dbforpostgresql.MigrationMode.OFFLINE,
    migration_name="examplemigration",
    overwrite_dbs_in_target=azure_native.dbforpostgresql.OverwriteDatabasesOnTargetServer.TRUE,
    resource_group_name="exampleresourcegroup",
    secret_parameters={
        "admin_credentials": {
            "source_server_password": "examplesourcepassword",
            "target_server_password": "exampletargetpassword",
        },
    },
    server_name="exampleserver",
    source_db_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
package main

import (
	dbforpostgresql "github.com/pulumi/pulumi-azure-native-sdk/dbforpostgresql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbforpostgresql.NewMigration(ctx, "migration", &dbforpostgresql.MigrationArgs{
			DbsToMigrate: pulumi.StringArray{
				pulumi.String("exampledatabase1"),
				pulumi.String("exampledatabase2"),
				pulumi.String("exampledatabase3"),
				pulumi.String("exampledatabase4"),
			},
			Location:             pulumi.String("eastus"),
			MigrateRoles:         pulumi.String(dbforpostgresql.MigrateRolesAndPermissionsTrue),
			MigrationMode:        pulumi.String(dbforpostgresql.MigrationModeOffline),
			MigrationName:        pulumi.String("examplemigration"),
			OverwriteDbsInTarget: pulumi.String(dbforpostgresql.OverwriteDatabasesOnTargetServerTrue),
			ResourceGroupName:    pulumi.String("exampleresourcegroup"),
			SecretParameters: &dbforpostgresql.MigrationSecretParametersArgs{
				AdminCredentials: &dbforpostgresql.AdminCredentialsArgs{
					SourceServerPassword: pulumi.String("examplesourcepassword"),
					TargetServerPassword: pulumi.String("exampletargetpassword"),
				},
			},
			ServerName:               pulumi.String("exampleserver"),
			SourceDbServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var migration = new AzureNative.DBforPostgreSQL.Migration("migration", new()
    {
        DbsToMigrate = new[]
        {
            "exampledatabase1",
            "exampledatabase2",
            "exampledatabase3",
            "exampledatabase4",
        },
        Location = "eastus",
        MigrateRoles = AzureNative.DBforPostgreSQL.MigrateRolesAndPermissions.True,
        MigrationMode = AzureNative.DBforPostgreSQL.MigrationMode.Offline,
        MigrationName = "examplemigration",
        OverwriteDbsInTarget = AzureNative.DBforPostgreSQL.OverwriteDatabasesOnTargetServer.True,
        ResourceGroupName = "exampleresourcegroup",
        SecretParameters = new AzureNative.DBforPostgreSQL.Inputs.MigrationSecretParametersArgs
        {
            AdminCredentials = new AzureNative.DBforPostgreSQL.Inputs.AdminCredentialsArgs
            {
                SourceServerPassword = "examplesourcepassword",
                TargetServerPassword = "exampletargetpassword",
            },
        },
        ServerName = "exampleserver",
        SourceDbServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbforpostgresql.Migration;
import com.pulumi.azurenative.dbforpostgresql.MigrationArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.MigrationSecretParametersArgs;
import com.pulumi.azurenative.dbforpostgresql.inputs.AdminCredentialsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var migration = new Migration("migration", MigrationArgs.builder()
            .dbsToMigrate(            
                "exampledatabase1",
                "exampledatabase2",
                "exampledatabase3",
                "exampledatabase4")
            .location("eastus")
            .migrateRoles("True")
            .migrationMode("Offline")
            .migrationName("examplemigration")
            .overwriteDbsInTarget("True")
            .resourceGroupName("exampleresourcegroup")
            .secretParameters(MigrationSecretParametersArgs.builder()
                .adminCredentials(AdminCredentialsArgs.builder()
                    .sourceServerPassword("examplesourcepassword")
                    .targetServerPassword("exampletargetpassword")
                    .build())
                .build())
            .serverName("exampleserver")
            .sourceDbServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource")
            .build());

    }
}
resources:
  migration:
    type: azure-native:dbforpostgresql:Migration
    properties:
      dbsToMigrate:
        - exampledatabase1
        - exampledatabase2
        - exampledatabase3
        - exampledatabase4
      location: eastus
      migrateRoles: True
      migrationMode: Offline
      migrationName: examplemigration
      overwriteDbsInTarget: True
      resourceGroupName: exampleresourcegroup
      secretParameters:
        adminCredentials:
          sourceServerPassword: examplesourcepassword
          targetServerPassword: exampletargetpassword
      serverName: exampleserver
      sourceDbServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/exampleresourcegroup/providers/Microsoft.DBForPostgreSql/servers/examplesource

The migrateRoles property set to “True” includes database roles and their permissions in the migration. This ensures user accounts, role memberships, and access controls transfer to the target server alongside schema and data. Without this setting, you would need to manually recreate roles and grants after migration.

Beyond these examples

These snippets focus on specific migration-level features: validation and migration modes, custom authentication and network routing, and role and permission migration. They’re intentionally minimal rather than full migration workflows.

The examples reference pre-existing infrastructure such as source PostgreSQL servers (Azure Single Server, Flexible Server, or external), target Azure Database for PostgreSQL Flexible Server, and migration instance flexible server (for private endpoint scenarios). They focus on configuring the migration rather than provisioning the servers themselves.

To keep things focused, common migration patterns are omitted, including:

  • Migration window scheduling (migrationWindowStartTimeInUtc, migrationWindowEndTimeInUtc)
  • Cutover triggering and database-specific cutover (triggerCutover, dbsToTriggerCutoverOn)
  • Migration cancellation (cancel, dbsToCancelMigrationOn)
  • Logical replication setup (setupLogicalReplicationOnSourceDbIfNeeded)
  • Data migration start control (startDataMigration)

These omissions are intentional: the goal is to illustrate how each migration feature is wired, not provide drop-in migration modules. See the Migration resource reference for all available configuration options.

Let's manage Azure Database for PostgreSQL Migrations

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Migration Configuration & Setup
What's the difference between Validate and ValidateAndMigrate?
Validate performs validation checks only without migrating data, while ValidateAndMigrate performs validation and then proceeds with the actual migration.
How do I specify the source server for different source types?
The sourceDbServerResourceId format depends on your sourceType. For Azure resources like PostgreSQLSingleServer, use the full ARM resource ID. For external sources like OnPremises, AWS, or GCP, use the format hostname:port@username (e.g., examplesource:5432@exampleuser).
What happens if databases already exist on the target server?
If overwriteDbsInTarget is set to False, the migration will pause and wait for manual confirmation when it detects existing databases. Set it to True for automatic overwriting.
Can I migrate user roles and permissions?
Yes, set migrateRoles to True to migrate roles and permissions along with your databases.
Authentication & Connectivity
What credentials do I need to provide?
You must provide secretParameters with adminCredentials containing sourceServerPassword and targetServerPassword. Optionally, you can specify sourceServerUsername and targetServerUsername if you need to override default admin credentials.
What SSL mode should I use?
The default SSL mode is VerifyFull for PostgreSQLSingleServer sources and Prefer for all other source types. You can override this with the sslMode property.
When should I use the FQDN properties?
Use sourceDbServerFullyQualifiedDomainName or targetDbServerFullyQualifiedDomainName when you want the migration service to always use a specific FQDN or IP address to connect, overriding automatic resolution.
Advanced Features
How do I set up a migration using a private endpoint?
Specify migrationInstanceResourceId pointing to a flexible server resource that acts as the private endpoint migration instance for secure connectivity.
How do I control the migration lifecycle?
Use startDataMigration to begin migration immediately, triggerCutover to initiate cutover for the entire migration or specific databases (via dbsToTriggerCutoverOn), and cancel to cancel the migration (optionally targeting specific databases with dbsToCancelMigrationOn).
Can I specify a migration window?
Yes, use migrationWindowStartTimeInUtc and migrationWindowEndTimeInUtc to define when the migration should run.

Using a different cloud?

Explore database guides for other cloud providers: