Deploy Azure SQL Databases

The azure-native:sql:Database resource, part of the Pulumi Azure Native provider, defines an Azure SQL Database: its compute tier, creation mode, and storage configuration. This guide focuses on five capabilities: basic provisioning, SKU selection, database copy and restore, geo-replication, and backup redundancy.

Databases belong to Azure SQL servers and may reference source databases for copy or restore operations. The examples are intentionally small. Combine them with your own server infrastructure, networking, and security configuration.

Create a database with minimal configuration

Most deployments start by specifying only the essential properties: name, location, resource group, and server.

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

const database = new azure_native.sql.Database("database", {
    databaseName: "testdb",
    location: "southeastasia",
    resourceGroupName: "Default-SQL-SouthEastAsia",
    serverName: "testsvr",
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    database_name="testdb",
    location="southeastasia",
    resource_group_name="Default-SQL-SouthEastAsia",
    server_name="testsvr")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			DatabaseName:      pulumi.String("testdb"),
			Location:          pulumi.String("southeastasia"),
			ResourceGroupName: pulumi.String("Default-SQL-SouthEastAsia"),
			ServerName:        pulumi.String("testsvr"),
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        DatabaseName = "testdb",
        Location = "southeastasia",
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        ServerName = "testsvr",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .databaseName("testdb")
            .location("southeastasia")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .serverName("testsvr")
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      databaseName: testdb
      location: southeastasia
      resourceGroupName: Default-SQL-SouthEastAsia
      serverName: testsvr

The databaseName, location, resourceGroupName, and serverName properties are required. Without an explicit sku, Azure assigns a default tier (typically General Purpose). The database uses default collation, size limits, and backup settings.

Specify compute tier using service objective

VCore-based databases let you control compute capacity by specifying a service objective abbreviation (like BC for Business Critical) along with hardware generation and core count.

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

const database = new azure_native.sql.Database("database", {
    databaseName: "testdb",
    location: "southeastasia",
    resourceGroupName: "Default-SQL-SouthEastAsia",
    serverName: "testsvr",
    sku: {
        capacity: 2,
        family: "Gen4",
        name: "BC",
    },
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    database_name="testdb",
    location="southeastasia",
    resource_group_name="Default-SQL-SouthEastAsia",
    server_name="testsvr",
    sku={
        "capacity": 2,
        "family": "Gen4",
        "name": "BC",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			DatabaseName:      pulumi.String("testdb"),
			Location:          pulumi.String("southeastasia"),
			ResourceGroupName: pulumi.String("Default-SQL-SouthEastAsia"),
			ServerName:        pulumi.String("testsvr"),
			Sku: &sql.SkuArgs{
				Capacity: pulumi.Int(2),
				Family:   pulumi.String("Gen4"),
				Name:     pulumi.String("BC"),
			},
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        DatabaseName = "testdb",
        Location = "southeastasia",
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        ServerName = "testsvr",
        Sku = new AzureNative.Sql.Inputs.SkuArgs
        {
            Capacity = 2,
            Family = "Gen4",
            Name = "BC",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
import com.pulumi.azurenative.sql.inputs.SkuArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .databaseName("testdb")
            .location("southeastasia")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .serverName("testsvr")
            .sku(SkuArgs.builder()
                .capacity(2)
                .family("Gen4")
                .name("BC")
                .build())
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      databaseName: testdb
      location: southeastasia
      resourceGroupName: Default-SQL-SouthEastAsia
      serverName: testsvr
      sku:
        capacity: 2
        family: Gen4
        name: BC

The sku property defines compute resources. The name field uses a tier abbreviation (BC for Business Critical), family specifies hardware generation (Gen4), and capacity sets vCore count. This configuration provides predictable performance for production workloads.

Copy an existing database to a new database

Database copies create transactionally consistent snapshots, useful for testing or creating point-in-time backups.

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

const database = new azure_native.sql.Database("database", {
    createMode: azure_native.sql.CreateMode.Copy,
    databaseName: "dbcopy",
    location: "southeastasia",
    resourceGroupName: "Default-SQL-SouthEastAsia",
    serverName: "testsvr",
    sku: {
        name: "S0",
        tier: "Standard",
    },
    sourceDatabaseId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb",
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    create_mode=azure_native.sql.CreateMode.COPY,
    database_name="dbcopy",
    location="southeastasia",
    resource_group_name="Default-SQL-SouthEastAsia",
    server_name="testsvr",
    sku={
        "name": "S0",
        "tier": "Standard",
    },
    source_database_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			CreateMode:        pulumi.String(sql.CreateModeCopy),
			DatabaseName:      pulumi.String("dbcopy"),
			Location:          pulumi.String("southeastasia"),
			ResourceGroupName: pulumi.String("Default-SQL-SouthEastAsia"),
			ServerName:        pulumi.String("testsvr"),
			Sku: &sql.SkuArgs{
				Name: pulumi.String("S0"),
				Tier: pulumi.String("Standard"),
			},
			SourceDatabaseId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb"),
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        CreateMode = AzureNative.Sql.CreateMode.Copy,
        DatabaseName = "dbcopy",
        Location = "southeastasia",
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        ServerName = "testsvr",
        Sku = new AzureNative.Sql.Inputs.SkuArgs
        {
            Name = "S0",
            Tier = "Standard",
        },
        SourceDatabaseId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
import com.pulumi.azurenative.sql.inputs.SkuArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .createMode("Copy")
            .databaseName("dbcopy")
            .location("southeastasia")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .serverName("testsvr")
            .sku(SkuArgs.builder()
                .name("S0")
                .tier("Standard")
                .build())
            .sourceDatabaseId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb")
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      createMode: Copy
      databaseName: dbcopy
      location: southeastasia
      resourceGroupName: Default-SQL-SouthEastAsia
      serverName: testsvr
      sku:
        name: S0
        tier: Standard
      sourceDatabaseId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SouthEastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb

When createMode is Copy, the sourceDatabaseId points to the database to clone. The copy operation creates a new database with the same schema and data. The sku property can differ from the source, allowing you to copy a production database to a smaller tier for development.

Restore a database to a specific point in time

Point-in-time restore recovers a database to any moment within its retention period, enabling recovery from accidental changes.

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

const database = new azure_native.sql.Database("database", {
    createMode: azure_native.sql.CreateMode.PointInTimeRestore,
    databaseName: "dbpitr",
    location: "southeastasia",
    resourceGroupName: "Default-SQL-SouthEastAsia",
    restorePointInTime: "2020-10-22T05:35:31.503Z",
    serverName: "testsvr",
    sourceDatabaseId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb",
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    create_mode=azure_native.sql.CreateMode.POINT_IN_TIME_RESTORE,
    database_name="dbpitr",
    location="southeastasia",
    resource_group_name="Default-SQL-SouthEastAsia",
    restore_point_in_time="2020-10-22T05:35:31.503Z",
    server_name="testsvr",
    source_database_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			CreateMode:         pulumi.String(sql.CreateModePointInTimeRestore),
			DatabaseName:       pulumi.String("dbpitr"),
			Location:           pulumi.String("southeastasia"),
			ResourceGroupName:  pulumi.String("Default-SQL-SouthEastAsia"),
			RestorePointInTime: pulumi.String("2020-10-22T05:35:31.503Z"),
			ServerName:         pulumi.String("testsvr"),
			SourceDatabaseId:   pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb"),
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        CreateMode = AzureNative.Sql.CreateMode.PointInTimeRestore,
        DatabaseName = "dbpitr",
        Location = "southeastasia",
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        RestorePointInTime = "2020-10-22T05:35:31.503Z",
        ServerName = "testsvr",
        SourceDatabaseId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .createMode("PointInTimeRestore")
            .databaseName("dbpitr")
            .location("southeastasia")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .restorePointInTime("2020-10-22T05:35:31.503Z")
            .serverName("testsvr")
            .sourceDatabaseId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb")
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      createMode: PointInTimeRestore
      databaseName: dbpitr
      location: southeastasia
      resourceGroupName: Default-SQL-SouthEastAsia
      restorePointInTime: 2020-10-22T05:35:31.503Z
      serverName: testsvr
      sourceDatabaseId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-SoutheastAsia/providers/Microsoft.Sql/servers/testsvr/databases/testdb

When createMode is PointInTimeRestore, the restorePointInTime specifies the target timestamp (ISO8601 format). The sourceDatabaseId identifies the database to restore from. Azure uses automatic backups to reconstruct the database state at the specified time.

Configure geo-replication with online secondary

Geo-replicated secondaries provide disaster recovery by continuously replicating data to a different region.

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

const database = new azure_native.sql.Database("database", {
    createMode: azure_native.sql.CreateMode.Secondary,
    databaseName: "testdb",
    location: "southeastasia",
    resourceGroupName: "Default-SQL-SouthEastAsia",
    secondaryType: azure_native.sql.SecondaryType.Geo,
    serverName: "testsvr",
    sku: {
        name: "S0",
        tier: "Standard",
    },
    sourceDatabaseId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb",
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    create_mode=azure_native.sql.CreateMode.SECONDARY,
    database_name="testdb",
    location="southeastasia",
    resource_group_name="Default-SQL-SouthEastAsia",
    secondary_type=azure_native.sql.SecondaryType.GEO,
    server_name="testsvr",
    sku={
        "name": "S0",
        "tier": "Standard",
    },
    source_database_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			CreateMode:        pulumi.String(sql.CreateModeSecondary),
			DatabaseName:      pulumi.String("testdb"),
			Location:          pulumi.String("southeastasia"),
			ResourceGroupName: pulumi.String("Default-SQL-SouthEastAsia"),
			SecondaryType:     pulumi.String(sql.SecondaryTypeGeo),
			ServerName:        pulumi.String("testsvr"),
			Sku: &sql.SkuArgs{
				Name: pulumi.String("S0"),
				Tier: pulumi.String("Standard"),
			},
			SourceDatabaseId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb"),
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        CreateMode = AzureNative.Sql.CreateMode.Secondary,
        DatabaseName = "testdb",
        Location = "southeastasia",
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        SecondaryType = AzureNative.Sql.SecondaryType.Geo,
        ServerName = "testsvr",
        Sku = new AzureNative.Sql.Inputs.SkuArgs
        {
            Name = "S0",
            Tier = "Standard",
        },
        SourceDatabaseId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
import com.pulumi.azurenative.sql.inputs.SkuArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .createMode("Secondary")
            .databaseName("testdb")
            .location("southeastasia")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .secondaryType("Geo")
            .serverName("testsvr")
            .sku(SkuArgs.builder()
                .name("S0")
                .tier("Standard")
                .build())
            .sourceDatabaseId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb")
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      createMode: Secondary
      databaseName: testdb
      location: southeastasia
      resourceGroupName: Default-SQL-SouthEastAsia
      secondaryType: Geo
      serverName: testsvr
      sku:
        name: S0
        tier: Standard
      sourceDatabaseId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/Default-SQL-NorthEurope/providers/Microsoft.Sql/servers/testsvr1/databases/testdb

When createMode is Secondary and secondaryType is Geo, the database becomes a readable replica in a different region. The sourceDatabaseId points to the primary database. The location must differ from the primary’s region. If the primary region fails, you can promote the secondary to become the new primary.

Configure backup storage redundancy

Backup storage redundancy controls how database backups are replicated, affecting both durability and cost.

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

const database = new azure_native.sql.Database("database", {
    databaseName: "testdb",
    location: "southeastasia",
    requestedBackupStorageRedundancy: azure_native.sql.BackupStorageRedundancy.Zone,
    resourceGroupName: "Default-SQL-SouthEastAsia",
    serverName: "testsvr",
});
import pulumi
import pulumi_azure_native as azure_native

database = azure_native.sql.Database("database",
    database_name="testdb",
    location="southeastasia",
    requested_backup_storage_redundancy=azure_native.sql.BackupStorageRedundancy.ZONE,
    resource_group_name="Default-SQL-SouthEastAsia",
    server_name="testsvr")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sql.NewDatabase(ctx, "database", &sql.DatabaseArgs{
			DatabaseName:                     pulumi.String("testdb"),
			Location:                         pulumi.String("southeastasia"),
			RequestedBackupStorageRedundancy: pulumi.String(sql.BackupStorageRedundancyZone),
			ResourceGroupName:                pulumi.String("Default-SQL-SouthEastAsia"),
			ServerName:                       pulumi.String("testsvr"),
		})
		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 database = new AzureNative.Sql.Database("database", new()
    {
        DatabaseName = "testdb",
        Location = "southeastasia",
        RequestedBackupStorageRedundancy = AzureNative.Sql.BackupStorageRedundancy.Zone,
        ResourceGroupName = "Default-SQL-SouthEastAsia",
        ServerName = "testsvr",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.Database;
import com.pulumi.azurenative.sql.DatabaseArgs;
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 database = new Database("database", DatabaseArgs.builder()
            .databaseName("testdb")
            .location("southeastasia")
            .requestedBackupStorageRedundancy("Zone")
            .resourceGroupName("Default-SQL-SouthEastAsia")
            .serverName("testsvr")
            .build());

    }
}
resources:
  database:
    type: azure-native:sql:Database
    properties:
      databaseName: testdb
      location: southeastasia
      requestedBackupStorageRedundancy: Zone
      resourceGroupName: Default-SQL-SouthEastAsia
      serverName: testsvr

The requestedBackupStorageRedundancy property sets the replication strategy for backups. Zone-redundant storage replicates backups across availability zones within a region, providing protection against zone failures. Other options include local (single zone) and geo-redundant (cross-region) storage.

Beyond these examples

These snippets focus on specific database-level features: SKU configuration and compute tiers, database creation modes, and backup storage redundancy. They’re intentionally minimal rather than full database deployments.

The examples reference pre-existing infrastructure such as Azure SQL servers, source databases for copy/restore operations, and resource groups and subscriptions. They focus on configuring the database rather than provisioning the surrounding infrastructure.

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

  • Elastic pool assignment (elasticPoolId)
  • Collation and character set configuration
  • Maximum database size limits (maxSizeBytes)
  • High availability replica counts
  • Maintenance windows and update schedules
  • Encryption and Always Encrypted enclaves

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

Let's deploy Azure SQL Databases

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Database Creation & Restore
What are the different ways to create or restore a database?

You can create a database using different createMode values:

  • Default - Standard database creation
  • Copy - Create a copy of an existing database (requires sourceDatabaseId)
  • Secondary - Create a secondary replica (requires sourceDatabaseId and secondaryType)
  • PointInTimeRestore - Restore to a specific point in time (requires sourceDatabaseId and restorePointInTime)
  • Recovery - Restore from geo-replicated backup (requires sourceDatabaseId as recoverable database resource ID)
  • Restore - Restore from backup of deleted database (requires sourceDatabaseId)
  • RestoreLongTermRetentionBackup - Restore from long-term retention vault (requires recoveryServicesRecoveryPointResourceId)
How do I restore a database from a different subscription?
Use sourceResourceId instead of sourceDatabaseId for cross-subscription restore (DataWarehouse edition only). Set createMode to PointInTimeRestore, Restore, or Recovery. When the source subscription belongs to a different tenant, include the x-ms-authorization-auxiliary header with authentication token for the source tenant.
What properties can't be changed after database creation?
These properties are immutable: location, databaseName, serverName, collation, catalogCollation, createMode, isLedgerOn, identity, and all source-related properties (sourceDatabaseId, sourceResourceId, restorePointInTime, etc.).
High Availability & Replication
What types of secondary databases can I create?

You can create three types of secondary databases by setting createMode to Secondary and specifying secondaryType:

  • Geo - Online geo-secondary for disaster recovery
  • Standby - Standby secondary replica
  • Named - Named replica for Hyperscale tier databases
How do I configure high availability replicas?
Set highAvailabilityReplicaCount to specify the number of secondary replicas for Business Critical, Premium, or Hyperscale databases. This property isn’t applicable to Hyperscale databases within elastic pools.
How do I enable zone redundancy?
Set zoneRedundant to true to spread database replicas across multiple availability zones. You can also pin a database to a specific zone using the availabilityZone property.
Scaling & Performance
How do I perform a manual cutover when scaling to Hyperscale?

Scaling to Hyperscale with manual cutover is a two-step process:

  1. Set manualCutover to true when initiating the scale operation (only when scaling from Business Critical/General Purpose/Premium/Standard to Hyperscale)
  2. When the operation enters Waiting state, provide performCutover to trigger the actual cutover and role-change
How do I specify the database SKU?
Configure the sku property with name, tier, capacity, and optionally family. You can either specify a service objective name (e.g., name: "BC", family: "Gen4") or a combined SKU name (e.g., name: "BC_Gen4"). Available SKUs vary by region; use az sql db list-editions or Get-AzSqlServerServiceObjective to see options.
Can I configure auto-pause for my database?
Yes, set autoPauseDelay to the number of minutes of inactivity before auto-pause. Use -1 to disable automatic pause.
Backup & Recovery
How do I configure backup storage redundancy?
Set requestedBackupStorageRedundancy to specify the storage type: Geo, Local, Zone, or GeoZone. The actual redundancy used is reflected in currentBackupStorageRedundancy.
Security & Compliance
What's the difference between Default and VBS enclave types?
Set preferredEnclaveType to Default or VBS to specify the Always Encrypted enclave type. VBS (Virtualization-Based Security) provides additional security isolation for sensitive data operations.
Can I enable ledger functionality after creating a database?
No, isLedgerOn cannot be changed after database creation. All tables in a ledger database are automatically ledger tables, so decide whether to enable this feature before creating the database.
Configuration & Limits
How do I use free monthly limits for my database?
Set useFreeLimit to true (allowed on one database per subscription). Configure freeLimitExhaustionBehavior to specify what happens when limits are exhausted: AutoPause (database pauses) or BillForUsage (database continues with billing for overage).
Can I enable read-only routing for my database?
Yes, set readScale to Enabled to route readonly connections to a secondary replica in the same region. This isn’t applicable to Hyperscale databases within elastic pools.

Using a different cloud?

Explore database guides for other cloud providers: