Deploy Azure Stack HCI Virtual Machines

The azure-native:azurestackhci:VirtualMachine resource, part of the Pulumi Azure Native provider, defines virtual machines on Azure Stack HCI clusters: their image source, hardware profile, networking, and security settings. This guide focuses on three capabilities: gallery and marketplace image deployment, existing disk attachment, and security profile configuration.

Azure Stack HCI VMs depend on custom locations (Azure Arc extended locations), image or disk resources, storage containers, and network interfaces. The examples are intentionally small. Combine them with your own Azure Stack HCI infrastructure and networking.

Most deployments start with a pre-configured gallery image and enable TPM and Secure Boot for compliance.

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

const virtualMachine = new azure_native.azurestackhci.VirtualMachine("virtualMachine", {
    extendedLocation: {
        name: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        type: azure_native.azurestackhci.ExtendedLocationTypes.CustomLocation,
    },
    hardwareProfile: {
        vmSize: azure_native.azurestackhci.VmSizeEnum.Default,
    },
    location: "West US2",
    networkProfile: {
        networkInterfaces: [{
            id: "test-nic",
        }],
    },
    osProfile: {
        adminPassword: "password",
        adminUsername: "localadmin",
        computerName: "luamaster",
    },
    resourceGroupName: "test-rg",
    securityProfile: {
        enableTPM: true,
        uefiSettings: {
            secureBootEnabled: true,
        },
    },
    storageProfile: {
        imageReference: {
            id: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image",
        },
        vmConfigStoragePathId: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtualMachineName: "test-vm",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_machine = azure_native.azurestackhci.VirtualMachine("virtualMachine",
    extended_location={
        "name": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        "type": azure_native.azurestackhci.ExtendedLocationTypes.CUSTOM_LOCATION,
    },
    hardware_profile={
        "vm_size": azure_native.azurestackhci.VmSizeEnum.DEFAULT,
    },
    location="West US2",
    network_profile={
        "network_interfaces": [{
            "id": "test-nic",
        }],
    },
    os_profile={
        "admin_password": "password",
        "admin_username": "localadmin",
        "computer_name": "luamaster",
    },
    resource_group_name="test-rg",
    security_profile={
        "enable_tpm": True,
        "uefi_settings": {
            "secure_boot_enabled": True,
        },
    },
    storage_profile={
        "image_reference": {
            "id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image",
        },
        "vm_config_storage_path_id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtual_machine_name="test-vm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := azurestackhci.NewVirtualMachine(ctx, "virtualMachine", &azurestackhci.VirtualMachineArgs{
			ExtendedLocation: &azurestackhci.ExtendedLocationArgs{
				Name: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location"),
				Type: pulumi.String(azurestackhci.ExtendedLocationTypesCustomLocation),
			},
			HardwareProfile: &azurestackhci.VirtualMachinePropertiesHardwareProfileArgs{
				VmSize: pulumi.String(azurestackhci.VmSizeEnumDefault),
			},
			Location: pulumi.String("West US2"),
			NetworkProfile: &azurestackhci.VirtualMachinePropertiesNetworkProfileArgs{
				NetworkInterfaces: azurestackhci.VirtualMachinePropertiesNetworkInterfacesArray{
					&azurestackhci.VirtualMachinePropertiesNetworkInterfacesArgs{
						Id: pulumi.String("test-nic"),
					},
				},
			},
			OsProfile: &azurestackhci.VirtualMachinePropertiesOsProfileArgs{
				AdminPassword: pulumi.String("password"),
				AdminUsername: pulumi.String("localadmin"),
				ComputerName:  pulumi.String("luamaster"),
			},
			ResourceGroupName: pulumi.String("test-rg"),
			SecurityProfile: &azurestackhci.VirtualMachinePropertiesSecurityProfileArgs{
				EnableTPM: pulumi.Bool(true),
				UefiSettings: &azurestackhci.VirtualMachinePropertiesUefiSettingsArgs{
					SecureBootEnabled: pulumi.Bool(true),
				},
			},
			StorageProfile: &azurestackhci.VirtualMachinePropertiesStorageProfileArgs{
				ImageReference: &azurestackhci.VirtualMachinePropertiesImageReferenceArgs{
					Id: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image"),
				},
				VmConfigStoragePathId: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container"),
			},
			VirtualMachineName: pulumi.String("test-vm"),
		})
		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 virtualMachine = new AzureNative.AzureStackHCI.VirtualMachine("virtualMachine", new()
    {
        ExtendedLocation = new AzureNative.AzureStackHCI.Inputs.ExtendedLocationArgs
        {
            Name = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
            Type = AzureNative.AzureStackHCI.ExtendedLocationTypes.CustomLocation,
        },
        HardwareProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesHardwareProfileArgs
        {
            VmSize = AzureNative.AzureStackHCI.VmSizeEnum.Default,
        },
        Location = "West US2",
        NetworkProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkProfileArgs
        {
            NetworkInterfaces = new[]
            {
                new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkInterfacesArgs
                {
                    Id = "test-nic",
                },
            },
        },
        OsProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesOsProfileArgs
        {
            AdminPassword = "password",
            AdminUsername = "localadmin",
            ComputerName = "luamaster",
        },
        ResourceGroupName = "test-rg",
        SecurityProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesSecurityProfileArgs
        {
            EnableTPM = true,
            UefiSettings = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesUefiSettingsArgs
            {
                SecureBootEnabled = true,
            },
        },
        StorageProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesStorageProfileArgs
        {
            ImageReference = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesImageReferenceArgs
            {
                Id = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image",
            },
            VmConfigStoragePathId = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
        },
        VirtualMachineName = "test-vm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.azurestackhci.VirtualMachine;
import com.pulumi.azurenative.azurestackhci.VirtualMachineArgs;
import com.pulumi.azurenative.azurestackhci.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesHardwareProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesNetworkProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesOsProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesSecurityProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesUefiSettingsArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesStorageProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesImageReferenceArgs;
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 virtualMachine = new VirtualMachine("virtualMachine", VirtualMachineArgs.builder()
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location")
                .type("CustomLocation")
                .build())
            .hardwareProfile(VirtualMachinePropertiesHardwareProfileArgs.builder()
                .vmSize("Default")
                .build())
            .location("West US2")
            .networkProfile(VirtualMachinePropertiesNetworkProfileArgs.builder()
                .networkInterfaces(VirtualMachinePropertiesNetworkInterfacesArgs.builder()
                    .id("test-nic")
                    .build())
                .build())
            .osProfile(VirtualMachinePropertiesOsProfileArgs.builder()
                .adminPassword("password")
                .adminUsername("localadmin")
                .computerName("luamaster")
                .build())
            .resourceGroupName("test-rg")
            .securityProfile(VirtualMachinePropertiesSecurityProfileArgs.builder()
                .enableTPM(true)
                .uefiSettings(VirtualMachinePropertiesUefiSettingsArgs.builder()
                    .secureBootEnabled(true)
                    .build())
                .build())
            .storageProfile(VirtualMachinePropertiesStorageProfileArgs.builder()
                .imageReference(VirtualMachinePropertiesImageReferenceArgs.builder()
                    .id("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image")
                    .build())
                .vmConfigStoragePathId("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container")
                .build())
            .virtualMachineName("test-vm")
            .build());

    }
}
resources:
  virtualMachine:
    type: azure-native:azurestackhci:VirtualMachine
    properties:
      extendedLocation:
        name: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location
        type: CustomLocation
      hardwareProfile:
        vmSize: Default
      location: West US2
      networkProfile:
        networkInterfaces:
          - id: test-nic
      osProfile:
        adminPassword: password
        adminUsername: localadmin
        computerName: luamaster
      resourceGroupName: test-rg
      securityProfile:
        enableTPM: true
        uefiSettings:
          secureBootEnabled: true
      storageProfile:
        imageReference:
          id: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/galleryImages/test-gallery-image
        vmConfigStoragePathId: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container
      virtualMachineName: test-vm

The extendedLocation property places the VM on a specific Azure Stack HCI cluster via a custom location. The storageProfile.imageReference points to a gallery image, while vmConfigStoragePathId specifies where VM configuration files are stored. The securityProfile enables TPM (enableTPM) and Secure Boot (uefiSettings.secureBootEnabled), which are required for many compliance frameworks. The osProfile sets initial credentials, and networkProfile attaches the VM to a pre-existing network interface.

Deploy from Azure Marketplace images

Azure Stack HCI supports marketplace gallery images for standardized OS deployments without maintaining custom images.

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

const virtualMachine = new azure_native.azurestackhci.VirtualMachine("virtualMachine", {
    extendedLocation: {
        name: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        type: azure_native.azurestackhci.ExtendedLocationTypes.CustomLocation,
    },
    hardwareProfile: {
        vmSize: azure_native.azurestackhci.VmSizeEnum.Default,
    },
    location: "West US2",
    networkProfile: {
        networkInterfaces: [{
            id: "test-nic",
        }],
    },
    osProfile: {
        adminPassword: "password",
        adminUsername: "localadmin",
        computerName: "luamaster",
    },
    resourceGroupName: "test-rg",
    securityProfile: {
        enableTPM: true,
        uefiSettings: {
            secureBootEnabled: true,
        },
    },
    storageProfile: {
        imageReference: {
            id: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image",
        },
        vmConfigStoragePathId: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtualMachineName: "test-vm",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_machine = azure_native.azurestackhci.VirtualMachine("virtualMachine",
    extended_location={
        "name": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        "type": azure_native.azurestackhci.ExtendedLocationTypes.CUSTOM_LOCATION,
    },
    hardware_profile={
        "vm_size": azure_native.azurestackhci.VmSizeEnum.DEFAULT,
    },
    location="West US2",
    network_profile={
        "network_interfaces": [{
            "id": "test-nic",
        }],
    },
    os_profile={
        "admin_password": "password",
        "admin_username": "localadmin",
        "computer_name": "luamaster",
    },
    resource_group_name="test-rg",
    security_profile={
        "enable_tpm": True,
        "uefi_settings": {
            "secure_boot_enabled": True,
        },
    },
    storage_profile={
        "image_reference": {
            "id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image",
        },
        "vm_config_storage_path_id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtual_machine_name="test-vm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := azurestackhci.NewVirtualMachine(ctx, "virtualMachine", &azurestackhci.VirtualMachineArgs{
			ExtendedLocation: &azurestackhci.ExtendedLocationArgs{
				Name: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location"),
				Type: pulumi.String(azurestackhci.ExtendedLocationTypesCustomLocation),
			},
			HardwareProfile: &azurestackhci.VirtualMachinePropertiesHardwareProfileArgs{
				VmSize: pulumi.String(azurestackhci.VmSizeEnumDefault),
			},
			Location: pulumi.String("West US2"),
			NetworkProfile: &azurestackhci.VirtualMachinePropertiesNetworkProfileArgs{
				NetworkInterfaces: azurestackhci.VirtualMachinePropertiesNetworkInterfacesArray{
					&azurestackhci.VirtualMachinePropertiesNetworkInterfacesArgs{
						Id: pulumi.String("test-nic"),
					},
				},
			},
			OsProfile: &azurestackhci.VirtualMachinePropertiesOsProfileArgs{
				AdminPassword: pulumi.String("password"),
				AdminUsername: pulumi.String("localadmin"),
				ComputerName:  pulumi.String("luamaster"),
			},
			ResourceGroupName: pulumi.String("test-rg"),
			SecurityProfile: &azurestackhci.VirtualMachinePropertiesSecurityProfileArgs{
				EnableTPM: pulumi.Bool(true),
				UefiSettings: &azurestackhci.VirtualMachinePropertiesUefiSettingsArgs{
					SecureBootEnabled: pulumi.Bool(true),
				},
			},
			StorageProfile: &azurestackhci.VirtualMachinePropertiesStorageProfileArgs{
				ImageReference: &azurestackhci.VirtualMachinePropertiesImageReferenceArgs{
					Id: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image"),
				},
				VmConfigStoragePathId: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container"),
			},
			VirtualMachineName: pulumi.String("test-vm"),
		})
		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 virtualMachine = new AzureNative.AzureStackHCI.VirtualMachine("virtualMachine", new()
    {
        ExtendedLocation = new AzureNative.AzureStackHCI.Inputs.ExtendedLocationArgs
        {
            Name = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
            Type = AzureNative.AzureStackHCI.ExtendedLocationTypes.CustomLocation,
        },
        HardwareProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesHardwareProfileArgs
        {
            VmSize = AzureNative.AzureStackHCI.VmSizeEnum.Default,
        },
        Location = "West US2",
        NetworkProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkProfileArgs
        {
            NetworkInterfaces = new[]
            {
                new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkInterfacesArgs
                {
                    Id = "test-nic",
                },
            },
        },
        OsProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesOsProfileArgs
        {
            AdminPassword = "password",
            AdminUsername = "localadmin",
            ComputerName = "luamaster",
        },
        ResourceGroupName = "test-rg",
        SecurityProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesSecurityProfileArgs
        {
            EnableTPM = true,
            UefiSettings = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesUefiSettingsArgs
            {
                SecureBootEnabled = true,
            },
        },
        StorageProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesStorageProfileArgs
        {
            ImageReference = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesImageReferenceArgs
            {
                Id = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image",
            },
            VmConfigStoragePathId = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
        },
        VirtualMachineName = "test-vm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.azurestackhci.VirtualMachine;
import com.pulumi.azurenative.azurestackhci.VirtualMachineArgs;
import com.pulumi.azurenative.azurestackhci.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesHardwareProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesNetworkProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesOsProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesSecurityProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesUefiSettingsArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesStorageProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesImageReferenceArgs;
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 virtualMachine = new VirtualMachine("virtualMachine", VirtualMachineArgs.builder()
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location")
                .type("CustomLocation")
                .build())
            .hardwareProfile(VirtualMachinePropertiesHardwareProfileArgs.builder()
                .vmSize("Default")
                .build())
            .location("West US2")
            .networkProfile(VirtualMachinePropertiesNetworkProfileArgs.builder()
                .networkInterfaces(VirtualMachinePropertiesNetworkInterfacesArgs.builder()
                    .id("test-nic")
                    .build())
                .build())
            .osProfile(VirtualMachinePropertiesOsProfileArgs.builder()
                .adminPassword("password")
                .adminUsername("localadmin")
                .computerName("luamaster")
                .build())
            .resourceGroupName("test-rg")
            .securityProfile(VirtualMachinePropertiesSecurityProfileArgs.builder()
                .enableTPM(true)
                .uefiSettings(VirtualMachinePropertiesUefiSettingsArgs.builder()
                    .secureBootEnabled(true)
                    .build())
                .build())
            .storageProfile(VirtualMachinePropertiesStorageProfileArgs.builder()
                .imageReference(VirtualMachinePropertiesImageReferenceArgs.builder()
                    .id("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image")
                    .build())
                .vmConfigStoragePathId("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container")
                .build())
            .virtualMachineName("test-vm")
            .build());

    }
}
resources:
  virtualMachine:
    type: azure-native:azurestackhci:VirtualMachine
    properties:
      extendedLocation:
        name: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location
        type: CustomLocation
      hardwareProfile:
        vmSize: Default
      location: West US2
      networkProfile:
        networkInterfaces:
          - id: test-nic
      osProfile:
        adminPassword: password
        adminUsername: localadmin
        computerName: luamaster
      resourceGroupName: test-rg
      securityProfile:
        enableTPM: true
        uefiSettings:
          secureBootEnabled: true
      storageProfile:
        imageReference:
          id: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/marketplaceGalleryImages/test-marketplace-gallery-image
        vmConfigStoragePathId: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container
      virtualMachineName: test-vm

The imageReference.id now points to a marketplaceGalleryImages resource instead of a custom gallery image. This allows you to deploy from Azure’s curated catalog. All other configuration (security, networking, storage) remains identical to gallery image deployment.

Attach an existing OS disk

When migrating VMs or using custom disk configurations, you can attach a pre-configured virtual hard disk.

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

const virtualMachine = new azure_native.azurestackhci.VirtualMachine("virtualMachine", {
    extendedLocation: {
        name: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        type: azure_native.azurestackhci.ExtendedLocationTypes.CustomLocation,
    },
    hardwareProfile: {
        vmSize: azure_native.azurestackhci.VmSizeEnum.Default,
    },
    location: "West US2",
    networkProfile: {
        networkInterfaces: [{
            id: "test-nic",
        }],
    },
    resourceGroupName: "test-rg",
    securityProfile: {
        enableTPM: true,
        uefiSettings: {
            secureBootEnabled: true,
        },
    },
    storageProfile: {
        osDisk: {
            id: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd",
        },
        vmConfigStoragePathId: "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtualMachineName: "test-vm",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_machine = azure_native.azurestackhci.VirtualMachine("virtualMachine",
    extended_location={
        "name": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
        "type": azure_native.azurestackhci.ExtendedLocationTypes.CUSTOM_LOCATION,
    },
    hardware_profile={
        "vm_size": azure_native.azurestackhci.VmSizeEnum.DEFAULT,
    },
    location="West US2",
    network_profile={
        "network_interfaces": [{
            "id": "test-nic",
        }],
    },
    resource_group_name="test-rg",
    security_profile={
        "enable_tpm": True,
        "uefi_settings": {
            "secure_boot_enabled": True,
        },
    },
    storage_profile={
        "os_disk": {
            "id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd",
        },
        "vm_config_storage_path_id": "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
    },
    virtual_machine_name="test-vm")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := azurestackhci.NewVirtualMachine(ctx, "virtualMachine", &azurestackhci.VirtualMachineArgs{
			ExtendedLocation: &azurestackhci.ExtendedLocationArgs{
				Name: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location"),
				Type: pulumi.String(azurestackhci.ExtendedLocationTypesCustomLocation),
			},
			HardwareProfile: &azurestackhci.VirtualMachinePropertiesHardwareProfileArgs{
				VmSize: pulumi.String(azurestackhci.VmSizeEnumDefault),
			},
			Location: pulumi.String("West US2"),
			NetworkProfile: &azurestackhci.VirtualMachinePropertiesNetworkProfileArgs{
				NetworkInterfaces: azurestackhci.VirtualMachinePropertiesNetworkInterfacesArray{
					&azurestackhci.VirtualMachinePropertiesNetworkInterfacesArgs{
						Id: pulumi.String("test-nic"),
					},
				},
			},
			ResourceGroupName: pulumi.String("test-rg"),
			SecurityProfile: &azurestackhci.VirtualMachinePropertiesSecurityProfileArgs{
				EnableTPM: pulumi.Bool(true),
				UefiSettings: &azurestackhci.VirtualMachinePropertiesUefiSettingsArgs{
					SecureBootEnabled: pulumi.Bool(true),
				},
			},
			StorageProfile: &azurestackhci.VirtualMachinePropertiesStorageProfileArgs{
				OsDisk: &azurestackhci.VirtualMachinePropertiesOsDiskArgs{
					Id: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd"),
				},
				VmConfigStoragePathId: pulumi.String("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container"),
			},
			VirtualMachineName: pulumi.String("test-vm"),
		})
		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 virtualMachine = new AzureNative.AzureStackHCI.VirtualMachine("virtualMachine", new()
    {
        ExtendedLocation = new AzureNative.AzureStackHCI.Inputs.ExtendedLocationArgs
        {
            Name = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location",
            Type = AzureNative.AzureStackHCI.ExtendedLocationTypes.CustomLocation,
        },
        HardwareProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesHardwareProfileArgs
        {
            VmSize = AzureNative.AzureStackHCI.VmSizeEnum.Default,
        },
        Location = "West US2",
        NetworkProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkProfileArgs
        {
            NetworkInterfaces = new[]
            {
                new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesNetworkInterfacesArgs
                {
                    Id = "test-nic",
                },
            },
        },
        ResourceGroupName = "test-rg",
        SecurityProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesSecurityProfileArgs
        {
            EnableTPM = true,
            UefiSettings = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesUefiSettingsArgs
            {
                SecureBootEnabled = true,
            },
        },
        StorageProfile = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesStorageProfileArgs
        {
            OsDisk = new AzureNative.AzureStackHCI.Inputs.VirtualMachinePropertiesOsDiskArgs
            {
                Id = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd",
            },
            VmConfigStoragePathId = "/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container",
        },
        VirtualMachineName = "test-vm",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.azurestackhci.VirtualMachine;
import com.pulumi.azurenative.azurestackhci.VirtualMachineArgs;
import com.pulumi.azurenative.azurestackhci.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesHardwareProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesNetworkProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesSecurityProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesUefiSettingsArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesStorageProfileArgs;
import com.pulumi.azurenative.azurestackhci.inputs.VirtualMachinePropertiesOsDiskArgs;
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 virtualMachine = new VirtualMachine("virtualMachine", VirtualMachineArgs.builder()
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location")
                .type("CustomLocation")
                .build())
            .hardwareProfile(VirtualMachinePropertiesHardwareProfileArgs.builder()
                .vmSize("Default")
                .build())
            .location("West US2")
            .networkProfile(VirtualMachinePropertiesNetworkProfileArgs.builder()
                .networkInterfaces(VirtualMachinePropertiesNetworkInterfacesArgs.builder()
                    .id("test-nic")
                    .build())
                .build())
            .resourceGroupName("test-rg")
            .securityProfile(VirtualMachinePropertiesSecurityProfileArgs.builder()
                .enableTPM(true)
                .uefiSettings(VirtualMachinePropertiesUefiSettingsArgs.builder()
                    .secureBootEnabled(true)
                    .build())
                .build())
            .storageProfile(VirtualMachinePropertiesStorageProfileArgs.builder()
                .osDisk(VirtualMachinePropertiesOsDiskArgs.builder()
                    .id("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd")
                    .build())
                .vmConfigStoragePathId("/subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container")
                .build())
            .virtualMachineName("test-vm")
            .build());

    }
}
resources:
  virtualMachine:
    type: azure-native:azurestackhci:VirtualMachine
    properties:
      extendedLocation:
        name: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.ExtendedLocation/customLocations/dogfood-location
        type: CustomLocation
      hardwareProfile:
        vmSize: Default
      location: West US2
      networkProfile:
        networkInterfaces:
          - id: test-nic
      resourceGroupName: test-rg
      securityProfile:
        enableTPM: true
        uefiSettings:
          secureBootEnabled: true
      storageProfile:
        osDisk:
          id: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/virtualHardDisks/test-vhd
        vmConfigStoragePathId: /subscriptions/a95612cb-f1fa-4daa-a4fd-272844fa512c/resourceGroups/dogfoodarc/providers/Microsoft.AzureStackHCI/storageContainers/test-container
      virtualMachineName: test-vm

The storageProfile.osDisk property references an existing virtual hard disk instead of an image. This approach skips image provisioning and boots directly from the specified disk. Note that osProfile is omitted because the disk already contains OS configuration and credentials.

Beyond these examples

These snippets focus on specific VM-level features: image-based and disk-based provisioning, security configuration, and custom and marketplace image sources. They’re intentionally minimal rather than full VM deployments.

The examples reference pre-existing infrastructure such as custom locations (Azure Arc extended locations), gallery images, marketplace images, or virtual hard disks, storage containers for VM configuration files, and network interfaces. They focus on configuring the VM rather than provisioning the surrounding Azure Stack HCI infrastructure.

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

  • Guest agent configuration (guestAgentProfile)
  • Managed identity assignment (identity)
  • Data disk attachment beyond OS disk
  • VM sizing and hardware customization (processors, memory)

These omissions are intentional: the goal is to illustrate how each VM feature is wired, not provide drop-in infrastructure modules. See the Azure Stack HCI VirtualMachine resource reference for all available configuration options.

Let's deploy Azure Stack HCI 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

Storage & Images
What are the different ways to deploy a VM's operating system?
You have three options: use imageReference with a galleryImages resource, use imageReference with a marketplaceGalleryImages resource, or use osDisk with an existing virtualHardDisks resource.
What's the difference between using an image reference and an OS disk?
When using imageReference, you must provide osProfile with admin credentials and computer name. When using osDisk with an existing virtual hard disk, you can omit osProfile since the OS is already configured.
What is vmConfigStoragePathId and is it required?
vmConfigStoragePathId specifies the storage container for VM configuration files. All examples include this property in storageProfile, pointing to a storage container resource.
Location & Deployment
What is extendedLocation and how do I configure it?
extendedLocation specifies the Azure Stack HCI custom location where your VM runs. Set name to your custom location resource path and type to CustomLocation.
What properties can't I change after creating the VM?
The location, resourceGroupName, and virtualMachineName properties are immutable and cannot be changed after creation.
Security Configuration
What security features are available for Azure Stack HCI VMs?
You can enable TPM via securityProfile.enableTPM and Secure Boot via securityProfile.uefiSettings.secureBootEnabled. All examples show both features enabled.

Using a different cloud?

Explore compute guides for other cloud providers: