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 FREEFrequently Asked Questions
Database Creation & Restore
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
sourceDatabaseIdandsecondaryType) - PointInTimeRestore - Restore to a specific point in time (requires
sourceDatabaseIdandrestorePointInTime) - Recovery - Restore from geo-replicated backup (requires
sourceDatabaseIdas recoverable database resource ID) - Restore - Restore from backup of deleted database (requires
sourceDatabaseId) - RestoreLongTermRetentionBackup - Restore from long-term retention vault (requires
recoveryServicesRecoveryPointResourceId)
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.location, databaseName, serverName, collation, catalogCollation, createMode, isLedgerOn, identity, and all source-related properties (sourceDatabaseId, sourceResourceId, restorePointInTime, etc.).High Availability & Replication
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
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.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
Scaling to Hyperscale with manual cutover is a two-step process:
- Set
manualCutoverto true when initiating the scale operation (only when scaling from Business Critical/General Purpose/Premium/Standard to Hyperscale) - When the operation enters Waiting state, provide
performCutoverto trigger the actual cutover and role-change
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.autoPauseDelay to the number of minutes of inactivity before auto-pause. Use -1 to disable automatic pause.Backup & Recovery
requestedBackupStorageRedundancy to specify the storage type: Geo, Local, Zone, or GeoZone. The actual redundancy used is reflected in currentBackupStorageRedundancy.Security & Compliance
preferredEnclaveType to Default or VBS to specify the Always Encrypted enclave type. VBS (Virtualization-Based Security) provides additional security isolation for sensitive data operations.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
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).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.