Deploy Azure SQL Virtual Machines

The azure-native:sqlvirtualmachine:SqlVirtualMachine resource, part of the Pulumi Azure Native provider, registers Azure VMs running SQL Server with Azure management capabilities. This guide focuses on four capabilities: VM registration with minimal configuration, automated backup scheduling, storage pool configuration, and availability group cluster membership.

SQL VMs reference existing Azure VMs, storage accounts, and optionally SQL virtual machine groups for clustering. The examples are intentionally small. Combine them with your own VM infrastructure, storage accounts, and network configuration.

Register an existing VM with minimal configuration

Most deployments start by registering an existing Azure VM that already has SQL Server installed, establishing the management layer without configuring advanced features.

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

const sqlVirtualMachine = new azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine", {
    location: "northeurope",
    resourceGroupName: "testrg",
    sqlVirtualMachineName: "testvm",
    virtualMachineResourceId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
});
import pulumi
import pulumi_azure_native as azure_native

sql_virtual_machine = azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine",
    location="northeurope",
    resource_group_name="testrg",
    sql_virtual_machine_name="testvm",
    virtual_machine_resource_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sqlvirtualmachine.NewSqlVirtualMachine(ctx, "sqlVirtualMachine", &sqlvirtualmachine.SqlVirtualMachineArgs{
			Location:                 pulumi.String("northeurope"),
			ResourceGroupName:        pulumi.String("testrg"),
			SqlVirtualMachineName:    pulumi.String("testvm"),
			VirtualMachineResourceId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm"),
		})
		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 sqlVirtualMachine = new AzureNative.SqlVirtualMachine.SqlVirtualMachine("sqlVirtualMachine", new()
    {
        Location = "northeurope",
        ResourceGroupName = "testrg",
        SqlVirtualMachineName = "testvm",
        VirtualMachineResourceId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachine;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachineArgs;
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 sqlVirtualMachine = new SqlVirtualMachine("sqlVirtualMachine", SqlVirtualMachineArgs.builder()
            .location("northeurope")
            .resourceGroupName("testrg")
            .sqlVirtualMachineName("testvm")
            .virtualMachineResourceId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
            .build());

    }
}
resources:
  sqlVirtualMachine:
    type: azure-native:sqlvirtualmachine:SqlVirtualMachine
    properties:
      location: northeurope
      resourceGroupName: testrg
      sqlVirtualMachineName: testvm
      virtualMachineResourceId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm

The virtualMachineResourceId property links this resource to an existing Azure VM. Registration enables Azure to manage SQL Server features like backups and patching. Without additional configuration blocks, the VM uses default settings for all SQL management features.

Configure automated backups with custom schedules

Production workloads require backup policies that align with business recovery objectives.

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

const sqlVirtualMachine = new azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine", {
    autoBackupSettings: {
        backupScheduleType: azure_native.sqlvirtualmachine.BackupScheduleType.Manual,
        backupSystemDbs: true,
        daysOfWeek: [
            azure_native.sqlvirtualmachine.AutoBackupDaysOfWeek.Monday,
            azure_native.sqlvirtualmachine.AutoBackupDaysOfWeek.Friday,
        ],
        enable: true,
        enableEncryption: true,
        fullBackupFrequency: azure_native.sqlvirtualmachine.FullBackupFrequencyType.Weekly,
        fullBackupStartTime: 6,
        fullBackupWindowHours: 11,
        logBackupFrequency: 10,
        password: "<Password>",
        retentionPeriod: 17,
        storageAccessKey: "<primary storage access key>",
        storageAccountUrl: "https://teststorage.blob.core.windows.net/",
        storageContainerName: "testcontainer",
    },
    autoPatchingSettings: {
        dayOfWeek: azure_native.sqlvirtualmachine.DayOfWeek.Sunday,
        enable: true,
        maintenanceWindowDuration: 60,
        maintenanceWindowStartingHour: 2,
    },
    keyVaultCredentialSettings: {
        enable: false,
    },
    location: "northeurope",
    resourceGroupName: "testrg",
    serverConfigurationsManagementSettings: {
        additionalFeaturesServerConfigurations: {
            isRServicesEnabled: false,
        },
        sqlConnectivityUpdateSettings: {
            connectivityType: azure_native.sqlvirtualmachine.ConnectivityType.PRIVATE,
            port: 1433,
            sqlAuthUpdatePassword: "<password>",
            sqlAuthUpdateUserName: "sqllogin",
        },
        sqlStorageUpdateSettings: {
            diskConfigurationType: azure_native.sqlvirtualmachine.DiskConfigurationType.NEW,
            diskCount: 1,
            startingDeviceId: 2,
        },
        sqlWorkloadTypeUpdateSettings: {
            sqlWorkloadType: azure_native.sqlvirtualmachine.SqlWorkloadType.OLTP,
        },
    },
    sqlImageSku: azure_native.sqlvirtualmachine.SqlImageSku.Enterprise,
    sqlServerLicenseType: azure_native.sqlvirtualmachine.SqlServerLicenseType.PAYG,
    sqlVirtualMachineName: "testvm",
    virtualMachineResourceId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
});
import pulumi
import pulumi_azure_native as azure_native

sql_virtual_machine = azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine",
    auto_backup_settings={
        "backup_schedule_type": azure_native.sqlvirtualmachine.BackupScheduleType.MANUAL,
        "backup_system_dbs": True,
        "days_of_week": [
            azure_native.sqlvirtualmachine.AutoBackupDaysOfWeek.MONDAY,
            azure_native.sqlvirtualmachine.AutoBackupDaysOfWeek.FRIDAY,
        ],
        "enable": True,
        "enable_encryption": True,
        "full_backup_frequency": azure_native.sqlvirtualmachine.FullBackupFrequencyType.WEEKLY,
        "full_backup_start_time": 6,
        "full_backup_window_hours": 11,
        "log_backup_frequency": 10,
        "password": "<Password>",
        "retention_period": 17,
        "storage_access_key": "<primary storage access key>",
        "storage_account_url": "https://teststorage.blob.core.windows.net/",
        "storage_container_name": "testcontainer",
    },
    auto_patching_settings={
        "day_of_week": azure_native.sqlvirtualmachine.DayOfWeek.SUNDAY,
        "enable": True,
        "maintenance_window_duration": 60,
        "maintenance_window_starting_hour": 2,
    },
    key_vault_credential_settings={
        "enable": False,
    },
    location="northeurope",
    resource_group_name="testrg",
    server_configurations_management_settings={
        "additional_features_server_configurations": {
            "is_r_services_enabled": False,
        },
        "sql_connectivity_update_settings": {
            "connectivity_type": azure_native.sqlvirtualmachine.ConnectivityType.PRIVATE,
            "port": 1433,
            "sql_auth_update_password": "<password>",
            "sql_auth_update_user_name": "sqllogin",
        },
        "sql_storage_update_settings": {
            "disk_configuration_type": azure_native.sqlvirtualmachine.DiskConfigurationType.NEW,
            "disk_count": 1,
            "starting_device_id": 2,
        },
        "sql_workload_type_update_settings": {
            "sql_workload_type": azure_native.sqlvirtualmachine.SqlWorkloadType.OLTP,
        },
    },
    sql_image_sku=azure_native.sqlvirtualmachine.SqlImageSku.ENTERPRISE,
    sql_server_license_type=azure_native.sqlvirtualmachine.SqlServerLicenseType.PAYG,
    sql_virtual_machine_name="testvm",
    virtual_machine_resource_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sqlvirtualmachine.NewSqlVirtualMachine(ctx, "sqlVirtualMachine", &sqlvirtualmachine.SqlVirtualMachineArgs{
			AutoBackupSettings: &sqlvirtualmachine.AutoBackupSettingsArgs{
				BackupScheduleType: pulumi.String(sqlvirtualmachine.BackupScheduleTypeManual),
				BackupSystemDbs:    pulumi.Bool(true),
				DaysOfWeek: pulumi.StringArray{
					pulumi.String(sqlvirtualmachine.AutoBackupDaysOfWeekMonday),
					pulumi.String(sqlvirtualmachine.AutoBackupDaysOfWeekFriday),
				},
				Enable:                pulumi.Bool(true),
				EnableEncryption:      pulumi.Bool(true),
				FullBackupFrequency:   pulumi.String(sqlvirtualmachine.FullBackupFrequencyTypeWeekly),
				FullBackupStartTime:   pulumi.Int(6),
				FullBackupWindowHours: pulumi.Int(11),
				LogBackupFrequency:    pulumi.Int(10),
				Password:              pulumi.String("<Password>"),
				RetentionPeriod:       pulumi.Int(17),
				StorageAccessKey:      pulumi.String("<primary storage access key>"),
				StorageAccountUrl:     pulumi.String("https://teststorage.blob.core.windows.net/"),
				StorageContainerName:  pulumi.String("testcontainer"),
			},
			AutoPatchingSettings: &sqlvirtualmachine.AutoPatchingSettingsArgs{
				DayOfWeek:                     sqlvirtualmachine.DayOfWeekSunday,
				Enable:                        pulumi.Bool(true),
				MaintenanceWindowDuration:     pulumi.Int(60),
				MaintenanceWindowStartingHour: pulumi.Int(2),
			},
			KeyVaultCredentialSettings: &sqlvirtualmachine.KeyVaultCredentialSettingsArgs{
				Enable: pulumi.Bool(false),
			},
			Location:          pulumi.String("northeurope"),
			ResourceGroupName: pulumi.String("testrg"),
			ServerConfigurationsManagementSettings: &sqlvirtualmachine.ServerConfigurationsManagementSettingsArgs{
				AdditionalFeaturesServerConfigurations: &sqlvirtualmachine.AdditionalFeaturesServerConfigurationsArgs{
					IsRServicesEnabled: pulumi.Bool(false),
				},
				SqlConnectivityUpdateSettings: &sqlvirtualmachine.SqlConnectivityUpdateSettingsArgs{
					ConnectivityType:      pulumi.String(sqlvirtualmachine.ConnectivityTypePRIVATE),
					Port:                  pulumi.Int(1433),
					SqlAuthUpdatePassword: pulumi.String("<password>"),
					SqlAuthUpdateUserName: pulumi.String("sqllogin"),
				},
				SqlStorageUpdateSettings: &sqlvirtualmachine.SqlStorageUpdateSettingsArgs{
					DiskConfigurationType: pulumi.String(sqlvirtualmachine.DiskConfigurationTypeNEW),
					DiskCount:             pulumi.Int(1),
					StartingDeviceId:      pulumi.Int(2),
				},
				SqlWorkloadTypeUpdateSettings: &sqlvirtualmachine.SqlWorkloadTypeUpdateSettingsArgs{
					SqlWorkloadType: pulumi.String(sqlvirtualmachine.SqlWorkloadTypeOLTP),
				},
			},
			SqlImageSku:              pulumi.String(sqlvirtualmachine.SqlImageSkuEnterprise),
			SqlServerLicenseType:     pulumi.String(sqlvirtualmachine.SqlServerLicenseTypePAYG),
			SqlVirtualMachineName:    pulumi.String("testvm"),
			VirtualMachineResourceId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm"),
		})
		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 sqlVirtualMachine = new AzureNative.SqlVirtualMachine.SqlVirtualMachine("sqlVirtualMachine", new()
    {
        AutoBackupSettings = new AzureNative.SqlVirtualMachine.Inputs.AutoBackupSettingsArgs
        {
            BackupScheduleType = AzureNative.SqlVirtualMachine.BackupScheduleType.Manual,
            BackupSystemDbs = true,
            DaysOfWeek = new[]
            {
                AzureNative.SqlVirtualMachine.AutoBackupDaysOfWeek.Monday,
                AzureNative.SqlVirtualMachine.AutoBackupDaysOfWeek.Friday,
            },
            Enable = true,
            EnableEncryption = true,
            FullBackupFrequency = AzureNative.SqlVirtualMachine.FullBackupFrequencyType.Weekly,
            FullBackupStartTime = 6,
            FullBackupWindowHours = 11,
            LogBackupFrequency = 10,
            Password = "<Password>",
            RetentionPeriod = 17,
            StorageAccessKey = "<primary storage access key>",
            StorageAccountUrl = "https://teststorage.blob.core.windows.net/",
            StorageContainerName = "testcontainer",
        },
        AutoPatchingSettings = new AzureNative.SqlVirtualMachine.Inputs.AutoPatchingSettingsArgs
        {
            DayOfWeek = AzureNative.SqlVirtualMachine.DayOfWeek.Sunday,
            Enable = true,
            MaintenanceWindowDuration = 60,
            MaintenanceWindowStartingHour = 2,
        },
        KeyVaultCredentialSettings = new AzureNative.SqlVirtualMachine.Inputs.KeyVaultCredentialSettingsArgs
        {
            Enable = false,
        },
        Location = "northeurope",
        ResourceGroupName = "testrg",
        ServerConfigurationsManagementSettings = new AzureNative.SqlVirtualMachine.Inputs.ServerConfigurationsManagementSettingsArgs
        {
            AdditionalFeaturesServerConfigurations = new AzureNative.SqlVirtualMachine.Inputs.AdditionalFeaturesServerConfigurationsArgs
            {
                IsRServicesEnabled = false,
            },
            SqlConnectivityUpdateSettings = new AzureNative.SqlVirtualMachine.Inputs.SqlConnectivityUpdateSettingsArgs
            {
                ConnectivityType = AzureNative.SqlVirtualMachine.ConnectivityType.PRIVATE,
                Port = 1433,
                SqlAuthUpdatePassword = "<password>",
                SqlAuthUpdateUserName = "sqllogin",
            },
            SqlStorageUpdateSettings = new AzureNative.SqlVirtualMachine.Inputs.SqlStorageUpdateSettingsArgs
            {
                DiskConfigurationType = AzureNative.SqlVirtualMachine.DiskConfigurationType.NEW,
                DiskCount = 1,
                StartingDeviceId = 2,
            },
            SqlWorkloadTypeUpdateSettings = new AzureNative.SqlVirtualMachine.Inputs.SqlWorkloadTypeUpdateSettingsArgs
            {
                SqlWorkloadType = AzureNative.SqlVirtualMachine.SqlWorkloadType.OLTP,
            },
        },
        SqlImageSku = AzureNative.SqlVirtualMachine.SqlImageSku.Enterprise,
        SqlServerLicenseType = AzureNative.SqlVirtualMachine.SqlServerLicenseType.PAYG,
        SqlVirtualMachineName = "testvm",
        VirtualMachineResourceId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachine;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachineArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.AutoBackupSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.AutoPatchingSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.KeyVaultCredentialSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.ServerConfigurationsManagementSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.AdditionalFeaturesServerConfigurationsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.SqlConnectivityUpdateSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.SqlStorageUpdateSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.SqlWorkloadTypeUpdateSettingsArgs;
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 sqlVirtualMachine = new SqlVirtualMachine("sqlVirtualMachine", SqlVirtualMachineArgs.builder()
            .autoBackupSettings(AutoBackupSettingsArgs.builder()
                .backupScheduleType("Manual")
                .backupSystemDbs(true)
                .daysOfWeek(                
                    "Monday",
                    "Friday")
                .enable(true)
                .enableEncryption(true)
                .fullBackupFrequency("Weekly")
                .fullBackupStartTime(6)
                .fullBackupWindowHours(11)
                .logBackupFrequency(10)
                .password("<Password>")
                .retentionPeriod(17)
                .storageAccessKey("<primary storage access key>")
                .storageAccountUrl("https://teststorage.blob.core.windows.net/")
                .storageContainerName("testcontainer")
                .build())
            .autoPatchingSettings(AutoPatchingSettingsArgs.builder()
                .dayOfWeek("Sunday")
                .enable(true)
                .maintenanceWindowDuration(60)
                .maintenanceWindowStartingHour(2)
                .build())
            .keyVaultCredentialSettings(KeyVaultCredentialSettingsArgs.builder()
                .enable(false)
                .build())
            .location("northeurope")
            .resourceGroupName("testrg")
            .serverConfigurationsManagementSettings(ServerConfigurationsManagementSettingsArgs.builder()
                .additionalFeaturesServerConfigurations(AdditionalFeaturesServerConfigurationsArgs.builder()
                    .isRServicesEnabled(false)
                    .build())
                .sqlConnectivityUpdateSettings(SqlConnectivityUpdateSettingsArgs.builder()
                    .connectivityType("PRIVATE")
                    .port(1433)
                    .sqlAuthUpdatePassword("<password>")
                    .sqlAuthUpdateUserName("sqllogin")
                    .build())
                .sqlStorageUpdateSettings(SqlStorageUpdateSettingsArgs.builder()
                    .diskConfigurationType("NEW")
                    .diskCount(1)
                    .startingDeviceId(2)
                    .build())
                .sqlWorkloadTypeUpdateSettings(SqlWorkloadTypeUpdateSettingsArgs.builder()
                    .sqlWorkloadType("OLTP")
                    .build())
                .build())
            .sqlImageSku("Enterprise")
            .sqlServerLicenseType("PAYG")
            .sqlVirtualMachineName("testvm")
            .virtualMachineResourceId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
            .build());

    }
}
resources:
  sqlVirtualMachine:
    type: azure-native:sqlvirtualmachine:SqlVirtualMachine
    properties:
      autoBackupSettings:
        backupScheduleType: Manual
        backupSystemDbs: true
        daysOfWeek:
          - Monday
          - Friday
        enable: true
        enableEncryption: true
        fullBackupFrequency: Weekly
        fullBackupStartTime: 6
        fullBackupWindowHours: 11
        logBackupFrequency: 10
        password: <Password>
        retentionPeriod: 17
        storageAccessKey: <primary storage access key>
        storageAccountUrl: https://teststorage.blob.core.windows.net/
        storageContainerName: testcontainer
      autoPatchingSettings:
        dayOfWeek: Sunday
        enable: true
        maintenanceWindowDuration: 60
        maintenanceWindowStartingHour: 2
      keyVaultCredentialSettings:
        enable: false
      location: northeurope
      resourceGroupName: testrg
      serverConfigurationsManagementSettings:
        additionalFeaturesServerConfigurations:
          isRServicesEnabled: false
        sqlConnectivityUpdateSettings:
          connectivityType: PRIVATE
          port: 1433
          sqlAuthUpdatePassword: <password>
          sqlAuthUpdateUserName: sqllogin
        sqlStorageUpdateSettings:
          diskConfigurationType: NEW
          diskCount: 1
          startingDeviceId: 2
        sqlWorkloadTypeUpdateSettings:
          sqlWorkloadType: OLTP
      sqlImageSku: Enterprise
      sqlServerLicenseType: PAYG
      sqlVirtualMachineName: testvm
      virtualMachineResourceId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm

The autoBackupSettings block defines when backups run and where they’re stored. The backupScheduleType of Manual lets you specify daysOfWeek for weekly backups. The fullBackupFrequency controls whether backups run daily or weekly. Backups are encrypted and stored in the Azure Storage account specified by storageAccountUrl, with retentionPeriod controlling how long backups are kept.

Configure storage pools for data and log files

SQL Server performance depends on storage layout. The storageConfigurationSettings block maps Azure managed disks to SQL file locations.

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

const sqlVirtualMachine = new azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine", {
    location: "northeurope",
    resourceGroupName: "testrg",
    sqlVirtualMachineName: "testvm",
    storageConfigurationSettings: {
        diskConfigurationType: azure_native.sqlvirtualmachine.DiskConfigurationType.NEW,
        sqlDataSettings: {
            defaultFilePath: "F:\\folderpath\\",
            luns: [0],
        },
        sqlLogSettings: {
            defaultFilePath: "G:\\folderpath\\",
            luns: [1],
        },
        sqlSystemDbOnDataDisk: true,
        sqlTempDbSettings: {
            dataFileCount: 8,
            dataFileSize: 256,
            dataGrowth: 512,
            defaultFilePath: "D:\\TEMP",
            logFileSize: 256,
            logGrowth: 512,
        },
        storageWorkloadType: azure_native.sqlvirtualmachine.StorageWorkloadType.OLTP,
    },
    virtualMachineResourceId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
});
import pulumi
import pulumi_azure_native as azure_native

sql_virtual_machine = azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine",
    location="northeurope",
    resource_group_name="testrg",
    sql_virtual_machine_name="testvm",
    storage_configuration_settings={
        "disk_configuration_type": azure_native.sqlvirtualmachine.DiskConfigurationType.NEW,
        "sql_data_settings": {
            "default_file_path": "F:\\folderpath\\",
            "luns": [0],
        },
        "sql_log_settings": {
            "default_file_path": "G:\\folderpath\\",
            "luns": [1],
        },
        "sql_system_db_on_data_disk": True,
        "sql_temp_db_settings": {
            "data_file_count": 8,
            "data_file_size": 256,
            "data_growth": 512,
            "default_file_path": "D:\\TEMP",
            "log_file_size": 256,
            "log_growth": 512,
        },
        "storage_workload_type": azure_native.sqlvirtualmachine.StorageWorkloadType.OLTP,
    },
    virtual_machine_resource_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sqlvirtualmachine.NewSqlVirtualMachine(ctx, "sqlVirtualMachine", &sqlvirtualmachine.SqlVirtualMachineArgs{
			Location:              pulumi.String("northeurope"),
			ResourceGroupName:     pulumi.String("testrg"),
			SqlVirtualMachineName: pulumi.String("testvm"),
			StorageConfigurationSettings: &sqlvirtualmachine.StorageConfigurationSettingsArgs{
				DiskConfigurationType: pulumi.String(sqlvirtualmachine.DiskConfigurationTypeNEW),
				SqlDataSettings: &sqlvirtualmachine.SQLStorageSettingsArgs{
					DefaultFilePath: pulumi.String("F:\\folderpath\\"),
					Luns: pulumi.IntArray{
						pulumi.Int(0),
					},
				},
				SqlLogSettings: &sqlvirtualmachine.SQLStorageSettingsArgs{
					DefaultFilePath: pulumi.String("G:\\folderpath\\"),
					Luns: pulumi.IntArray{
						pulumi.Int(1),
					},
				},
				SqlSystemDbOnDataDisk: pulumi.Bool(true),
				SqlTempDbSettings: &sqlvirtualmachine.SQLTempDbSettingsArgs{
					DataFileCount:   pulumi.Int(8),
					DataFileSize:    pulumi.Int(256),
					DataGrowth:      pulumi.Int(512),
					DefaultFilePath: pulumi.String("D:\\TEMP"),
					LogFileSize:     pulumi.Int(256),
					LogGrowth:       pulumi.Int(512),
				},
				StorageWorkloadType: pulumi.String(sqlvirtualmachine.StorageWorkloadTypeOLTP),
			},
			VirtualMachineResourceId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm"),
		})
		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 sqlVirtualMachine = new AzureNative.SqlVirtualMachine.SqlVirtualMachine("sqlVirtualMachine", new()
    {
        Location = "northeurope",
        ResourceGroupName = "testrg",
        SqlVirtualMachineName = "testvm",
        StorageConfigurationSettings = new AzureNative.SqlVirtualMachine.Inputs.StorageConfigurationSettingsArgs
        {
            DiskConfigurationType = AzureNative.SqlVirtualMachine.DiskConfigurationType.NEW,
            SqlDataSettings = new AzureNative.SqlVirtualMachine.Inputs.SQLStorageSettingsArgs
            {
                DefaultFilePath = "F:\\folderpath\\",
                Luns = new[]
                {
                    0,
                },
            },
            SqlLogSettings = new AzureNative.SqlVirtualMachine.Inputs.SQLStorageSettingsArgs
            {
                DefaultFilePath = "G:\\folderpath\\",
                Luns = new[]
                {
                    1,
                },
            },
            SqlSystemDbOnDataDisk = true,
            SqlTempDbSettings = new AzureNative.SqlVirtualMachine.Inputs.SQLTempDbSettingsArgs
            {
                DataFileCount = 8,
                DataFileSize = 256,
                DataGrowth = 512,
                DefaultFilePath = "D:\\TEMP",
                LogFileSize = 256,
                LogGrowth = 512,
            },
            StorageWorkloadType = AzureNative.SqlVirtualMachine.StorageWorkloadType.OLTP,
        },
        VirtualMachineResourceId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachine;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachineArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.StorageConfigurationSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.SQLStorageSettingsArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.SQLTempDbSettingsArgs;
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 sqlVirtualMachine = new SqlVirtualMachine("sqlVirtualMachine", SqlVirtualMachineArgs.builder()
            .location("northeurope")
            .resourceGroupName("testrg")
            .sqlVirtualMachineName("testvm")
            .storageConfigurationSettings(StorageConfigurationSettingsArgs.builder()
                .diskConfigurationType("NEW")
                .sqlDataSettings(SQLStorageSettingsArgs.builder()
                    .defaultFilePath("F:\\folderpath\\")
                    .luns(0)
                    .build())
                .sqlLogSettings(SQLStorageSettingsArgs.builder()
                    .defaultFilePath("G:\\folderpath\\")
                    .luns(1)
                    .build())
                .sqlSystemDbOnDataDisk(true)
                .sqlTempDbSettings(SQLTempDbSettingsArgs.builder()
                    .dataFileCount(8)
                    .dataFileSize(256)
                    .dataGrowth(512)
                    .defaultFilePath("D:\\TEMP")
                    .logFileSize(256)
                    .logGrowth(512)
                    .build())
                .storageWorkloadType("OLTP")
                .build())
            .virtualMachineResourceId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm")
            .build());

    }
}
resources:
  sqlVirtualMachine:
    type: azure-native:sqlvirtualmachine:SqlVirtualMachine
    properties:
      location: northeurope
      resourceGroupName: testrg
      sqlVirtualMachineName: testvm
      storageConfigurationSettings:
        diskConfigurationType: NEW
        sqlDataSettings:
          defaultFilePath: F:\folderpath\
          luns:
            - 0
        sqlLogSettings:
          defaultFilePath: G:\folderpath\
          luns:
            - 1
        sqlSystemDbOnDataDisk: true
        sqlTempDbSettings:
          dataFileCount: 8
          dataFileSize: 256
          dataGrowth: 512
          defaultFilePath: D:\TEMP
          logFileSize: 256
          logGrowth: 512
        storageWorkloadType: OLTP
      virtualMachineResourceId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm

The diskConfigurationType of NEW creates storage pools from attached disks. The sqlDataSettings, sqlLogSettings, and sqlTempDbSettings blocks each specify luns (logical unit numbers) that identify which managed disks to use. The defaultFilePath properties set where SQL Server places files. This configuration separates data, log, and tempdb across dedicated storage pools for optimal I/O performance.

Join a VM to a SQL virtual machine group

High availability configurations like Always On Availability Groups require VMs to join a SQL virtual machine group, which coordinates cluster membership.

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

const sqlVirtualMachine = new azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine", {
    location: "northeurope",
    resourceGroupName: "testrg",
    sqlVirtualMachineGroupResourceId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup",
    sqlVirtualMachineName: "testvm",
    virtualMachineResourceId: "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2",
    wsfcDomainCredentials: {
        clusterBootstrapAccountPassword: "<Password>",
        clusterOperatorAccountPassword: "<Password>",
        sqlServiceAccountPassword: "<Password>",
    },
    wsfcStaticIp: "10.0.0.7",
});
import pulumi
import pulumi_azure_native as azure_native

sql_virtual_machine = azure_native.sqlvirtualmachine.SqlVirtualMachine("sqlVirtualMachine",
    location="northeurope",
    resource_group_name="testrg",
    sql_virtual_machine_group_resource_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup",
    sql_virtual_machine_name="testvm",
    virtual_machine_resource_id="/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2",
    wsfc_domain_credentials={
        "cluster_bootstrap_account_password": "<Password>",
        "cluster_operator_account_password": "<Password>",
        "sql_service_account_password": "<Password>",
    },
    wsfc_static_ip="10.0.0.7")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := sqlvirtualmachine.NewSqlVirtualMachine(ctx, "sqlVirtualMachine", &sqlvirtualmachine.SqlVirtualMachineArgs{
			Location:                         pulumi.String("northeurope"),
			ResourceGroupName:                pulumi.String("testrg"),
			SqlVirtualMachineGroupResourceId: pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup"),
			SqlVirtualMachineName:            pulumi.String("testvm"),
			VirtualMachineResourceId:         pulumi.String("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2"),
			WsfcDomainCredentials: &sqlvirtualmachine.WsfcDomainCredentialsArgs{
				ClusterBootstrapAccountPassword: pulumi.String("<Password>"),
				ClusterOperatorAccountPassword:  pulumi.String("<Password>"),
				SqlServiceAccountPassword:       pulumi.String("<Password>"),
			},
			WsfcStaticIp: pulumi.String("10.0.0.7"),
		})
		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 sqlVirtualMachine = new AzureNative.SqlVirtualMachine.SqlVirtualMachine("sqlVirtualMachine", new()
    {
        Location = "northeurope",
        ResourceGroupName = "testrg",
        SqlVirtualMachineGroupResourceId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup",
        SqlVirtualMachineName = "testvm",
        VirtualMachineResourceId = "/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2",
        WsfcDomainCredentials = new AzureNative.SqlVirtualMachine.Inputs.WsfcDomainCredentialsArgs
        {
            ClusterBootstrapAccountPassword = "<Password>",
            ClusterOperatorAccountPassword = "<Password>",
            SqlServiceAccountPassword = "<Password>",
        },
        WsfcStaticIp = "10.0.0.7",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachine;
import com.pulumi.azurenative.sqlvirtualmachine.SqlVirtualMachineArgs;
import com.pulumi.azurenative.sqlvirtualmachine.inputs.WsfcDomainCredentialsArgs;
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 sqlVirtualMachine = new SqlVirtualMachine("sqlVirtualMachine", SqlVirtualMachineArgs.builder()
            .location("northeurope")
            .resourceGroupName("testrg")
            .sqlVirtualMachineGroupResourceId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup")
            .sqlVirtualMachineName("testvm")
            .virtualMachineResourceId("/subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2")
            .wsfcDomainCredentials(WsfcDomainCredentialsArgs.builder()
                .clusterBootstrapAccountPassword("<Password>")
                .clusterOperatorAccountPassword("<Password>")
                .sqlServiceAccountPassword("<Password>")
                .build())
            .wsfcStaticIp("10.0.0.7")
            .build());

    }
}
resources:
  sqlVirtualMachine:
    type: azure-native:sqlvirtualmachine:SqlVirtualMachine
    properties:
      location: northeurope
      resourceGroupName: testrg
      sqlVirtualMachineGroupResourceId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachineGroups/testvmgroup
      sqlVirtualMachineName: testvm
      virtualMachineResourceId: /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/testrg/providers/Microsoft.Compute/virtualMachines/testvm2
      wsfcDomainCredentials:
        clusterBootstrapAccountPassword: <Password>
        clusterOperatorAccountPassword: <Password>
        sqlServiceAccountPassword: <Password>
      wsfcStaticIp: 10.0.0.7

The sqlVirtualMachineGroupResourceId property links this VM to an existing group. The wsfcDomainCredentials block provides passwords for cluster service accounts. The wsfcStaticIp assigns a static IP address for cluster communication. The VM must be domain-joined before joining the group, and the specified static IP must be available in the subnet.

Beyond these examples

These snippets focus on specific SQL VM features: VM registration and group membership, automated backup and patching schedules, and storage pool configuration for SQL files. They’re intentionally minimal rather than full SQL Server deployments.

The examples reference pre-existing infrastructure such as Azure VMs with SQL Server installed, SQL virtual machine groups for cluster scenarios, Azure Storage accounts for backups, and managed disks attached to VMs for storage configuration. They focus on configuring the SQL VM resource rather than provisioning the underlying infrastructure.

To keep things focused, common SQL VM patterns are omitted, including:

  • SQL instance settings (collation, memory, MaxDOP)
  • Assessment schedules and best practices analysis
  • Azure AD authentication configuration
  • Managed identity integration
  • Connectivity and port configuration
  • License type selection (PAYG vs AHUB)

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

Let's deploy Azure SQL Virtual Machines

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
What's required to create a SQL virtual machine resource?
You must provide virtualMachineResourceId (ARM ID of an existing Azure VM created from SQL marketplace image), location, resourceGroupName, and sqlVirtualMachineName. All other properties are optional.
What properties can't be changed after creating the SQL VM?
These properties are immutable: location, identity, resourceGroupName, sqlImageOffer, sqlVirtualMachineName, and virtualMachineResourceId. Changing them requires recreating the resource.
Which properties are deprecated and shouldn't be used?
Don’t use identity (use virtualMachineIdentitySettings instead) or sqlManagement (the API automatically detects SQL Management mode). Both are marked for deprecation.
High Availability & Clustering
How do I join a SQL VM to a failover cluster group?

Configure three required properties:

  1. sqlVirtualMachineGroupResourceId with the cluster group’s ARM ID
  2. wsfcDomainCredentials containing clusterBootstrapAccountPassword, clusterOperatorAccountPassword, and sqlServiceAccountPassword
  3. wsfcStaticIp with the static IP address for the cluster
Storage Configuration
What's the difference between NEW and EXTEND disk configuration types?
NEW creates new storage pools for data, log, and tempdb files. You specify LUNs, default file paths, and storage pool settings. EXTEND adds disks to existing storage pools and only requires LUN specifications.
How do I configure storage for data, log, and tempdb files?
Use storageConfigurationSettings with diskConfigurationType set to NEW. Configure sqlDataSettings, sqlLogSettings, and sqlTempDbSettings with LUNs, file paths, and sizing parameters. Set storageWorkloadType to match your workload (OLTP, DW, or General).
Backup & Maintenance
How do I set up automated backups?

Configure autoBackupSettings with:

  • enable set to true
  • backupScheduleType (Manual or Automated)
  • Storage account details (storageAccountUrl, storageAccessKey, storageContainerName)
  • Backup frequency and retention settings
  • Optional: enableEncryption with password for encrypted backups
How do I configure automatic patching windows?
Use autoPatchingSettings to specify dayOfWeek, maintenanceWindowStartingHour, and maintenanceWindowDuration (in minutes). Set enable to true to activate automatic patching.
Identity & Security
How do I enable managed identity for my SQL VM?
Configure virtualMachineIdentitySettings with type set to UserAssigned and resourceId pointing to your managed identity resource (e.g., /subscriptions/.../providers/Microsoft.ManagedIdentity/userAssignedIdentities/...).
Is automatic upgrade of the SQL IaaS extension enabled by default?
No, enableAutomaticUpgrade defaults to false. Set it to true if you want automatic upgrades of the SQL IaaS extension agent.

Using a different cloud?

Explore database guides for other cloud providers: