|
| 1 | +--- |
| 2 | +title: Create Azure Local VM from Azure Compute Gallery images via Azure CLI |
| 3 | +description: Learn how to create Azure Local VM images using Azure Compute Gallery images. |
| 4 | +author: sipastak |
| 5 | +ms.author: sipastak |
| 6 | +ms.topic: how-to |
| 7 | +ms.service: azure-local |
| 8 | +ms.custom: |
| 9 | + - devx-track-azurecli |
| 10 | +ms.date: 05/21/2025 |
| 11 | +--- |
| 12 | + |
| 13 | +# Create Azure Local VM image using Azure Compute Gallery images |
| 14 | + |
| 15 | +[!INCLUDE [hci-applies-to-23h2](../includes/hci-applies-to-23h2.md)] |
| 16 | + |
| 17 | +This article describes how to create Azure Local VMs enabled by Azure Arc using source images from the Azure Compute Gallery. You can create VM images on Azure CLI using the instructions in this article and then use these VM images to create Azure Local VMs. |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +- Make sure to review and [complete the Azure Local VM prerequisites](./azure-arc-vm-management-prerequisites.md). |
| 22 | +- Make sure that your image is using a [supported operating system](/azure/azure-arc/servers/prerequisites#supported-operating-systems). |
| 23 | +- For custom images in Azure Compute Gallery, ensure you meet the following extra prerequisites: |
| 24 | + - You should have a Virtual Hard Disk (VHD) loaded in your Azure Compute Gallery. See how to [Create an image definition and image version](/azure/virtual-machines/image-version). |
| 25 | + - If using a VHDX: |
| 26 | + - The VHDX image must be Gen 2 type and secure boot enabled. |
| 27 | + - The VHDX image must be prepared using `sysprep /generalize /shutdown /oobe`. For more information, see [Sysprep command-line options](/windows-hardware/manufacture/desktop/sysprep-command-line-options). |
| 28 | + |
| 29 | +## Create an Azure Local VM image from Azure Compute Gallery |
| 30 | + |
| 31 | +Follow these steps to create an Azure Local VM image using Azure CLI. |
| 32 | + |
| 33 | +### Sign in and set subscription |
| 34 | + |
| 35 | +[!INCLUDE [hci-vm-sign-in-set-subscription](../includes/hci-vm-sign-in-set-subscription.md)] |
| 36 | + |
| 37 | +### Export image to managed disk |
| 38 | + |
| 39 | +To transfer your Azure Compute Gallery image to be an Azure Local compatible image, you need to export your Azure Compute Gallery image version to a managed disk. |
| 40 | + |
| 41 | +1. To download the Azure Compute Gallery image to your resource group, follow the steps in [Export an image version to a managed disk](/azure/virtual-machines/managed-disk-from-image-version). Note the name of the managed disk. |
| 42 | + |
| 43 | +1. Obtain the SAS token of the managed disk by using the following command: |
| 44 | + |
| 45 | + ```azurecli |
| 46 | + az disk grant-access --resource-group $resourceGroupName --name $diskName --duration-in-seconds $sasExpiryDuration --query [accessSas] -o tsv |
| 47 | + ``` |
| 48 | +
|
| 49 | +### Set parameters |
| 50 | +
|
| 51 | +Before creating an Azure Local VM image, you'll need to set some parameters. |
| 52 | +
|
| 53 | +- Set your subscription, resource group, location, path to the image in local share, and OS type for the image. Replace the parameters in `< >` with the appropriate values. |
| 54 | +
|
| 55 | + ```azurecli |
| 56 | + $subscription = "<Subscription ID>" |
| 57 | + $resource_group = "<Resource group>" |
| 58 | + $location = "<Location for your Azure Local>" |
| 59 | + $osType = "<OS of source image>" |
| 60 | + $imageName = "<VM image name>" |
| 61 | + ``` |
| 62 | +
|
| 63 | + The parameters are described in the following table: |
| 64 | + |
| 65 | + | Parameter | Description | |
| 66 | + |------------------|--------------------------------------------------------------------------------------------| |
| 67 | + | `subscription` | Subscription for Azure Local that you associate with this image. | |
| 68 | + | `resource_group` | Resource group for Azure Local that you associate with this image. | |
| 69 | + | `location` | Location for your Azure Local instance. For example, this could be `eastus`. | |
| 70 | + | `imageName` | Name of the VM image created starting with the image in your local share. <br> **Note**: Azure rejects all the names that contain the keyword Windows. | |
| 71 | + | `os-type` | Operating system associated with the source image. This can be Windows or Linux. | |
| 72 | + |
| 73 | + Here's a sample output: |
| 74 | + |
| 75 | + ```azurecli |
| 76 | + PS C:\Users\azcli> $subscription = "<Subscription ID>" |
| 77 | + PS C:\Users\azcli> $resource_group = "mylocal-rg" |
| 78 | + PS C:\Users\azcli> $location = "eastus" |
| 79 | + PS C:\Users\azcli> $osType = "Windows" |
| 80 | + PS C:\Users\azcli> $imageName = "mylocal-computegalleryimage" |
| 81 | + ``` |
| 82 | +
|
| 83 | +### Create an Azure Local VM image |
| 84 | +
|
| 85 | +To create an Azure Local VM image: |
| 86 | +
|
| 87 | +1. Select a custom location to deploy your VM image. The custom location should correspond to the custom location for your Azure Local. Get the custom location ID for your Azure Local. Run the following command: |
| 88 | +
|
| 89 | + ```azurecli |
| 90 | + $customLocationID=(az customlocation show --resource-group $resource_group --name "<custom location name for your Azure Local>" --query id -o tsv) |
| 91 | + ``` |
| 92 | +
|
| 93 | +1. Create the VM image starting with a specified marketplace image. Make sure to specify the offer, publisher, sku and version for the marketplace image. |
| 94 | +
|
| 95 | + ```azurecli |
| 96 | + az stack-hci-vm image create --subscription $subscription --resource-group $resource_Group --custom-location $customLocationID --location $location --name $imageName --os-type $osType --image-path $imageSourcePath --storage-path-id $storagepathid |
| 97 | + ``` |
| 98 | +
|
| 99 | + A deployment job starts for the VM image. |
| 100 | +
|
| 101 | + In this example, the storage path was specified using the `--storage-path-id` flag and that ensured that the workload data (including the VM, VM image, non-OS data disk) is placed in the specified storage path. |
| 102 | +
|
| 103 | + If the flag is not specified, the workload data is automatically placed in a high availability storage path. |
| 104 | +
|
| 105 | + The image deployment takes a few minutes to complete. The time taken to download the image depends on the size of the image and the network bandwidth available for the download. |
| 106 | +
|
| 107 | + Here's a sample output: |
| 108 | +
|
| 109 | + ```azurecli |
| 110 | + { |
| 111 | + "extendedLocation": { |
| 112 | + "name": "/subscriptions/<Subscription ID>/resourceGroups/mylocal-rg/providers/Microsoft.ExtendedLocation/customLocations/mylocal-cl", |
| 113 | + "type": "CustomLocation" |
| 114 | + }, |
| 115 | + "id": "/subscriptions/<Subscription ID>/resourceGroups/mylocal-rg/providers/Microsoft.AzureStackHCI/galleryImages/mylocal-image", |
| 116 | + "location": "eastus", |
| 117 | + "name": "mylocal-image", |
| 118 | + "properties": { |
| 119 | + "cloudInitDataSource": null, |
| 120 | + "containerId": "/subscriptions/<Subscription ID>/resourceGroups/mylocal-rg/providers/Microsoft.AzureStackHCI/storageContainers/mylocal-storagepath", |
| 121 | + "hyperVGeneration": null, |
| 122 | + "identifier": null, |
| 123 | + "imagePath": null, |
| 124 | + "osType": "Windows", |
| 125 | + "provisioningState": "Succeeded", |
| 126 | + "sourceVirtualMachineId": null, |
| 127 | + "status": { |
| 128 | + "downloadStatus": { |
| 129 | + "downloadSizeInMb": 11482 |
| 130 | + }, |
| 131 | + "errorCode": "", |
| 132 | + "errorMessage": "", |
| 133 | + "progressPercentage": 100, |
| 134 | + "provisioningStatus": { |
| 135 | + "operationId": "00000000-0000-0000-0000-000000000000*0000000000000000000000000000000000000000000000000000000000000000", |
| 136 | + "status": "Succeeded" |
| 137 | + } |
| 138 | + }, |
| 139 | + "version": { |
| 140 | + "name": null, |
| 141 | + "properties": { |
| 142 | + "storageProfile": { |
| 143 | + "osDiskImage": { |
| 144 | + "sizeInMb": 130050 |
| 145 | + } |
| 146 | + } |
| 147 | + } |
| 148 | + }, |
| 149 | + "vmImageRepositoryCredentials": null |
| 150 | + }, |
| 151 | + "resourceGroup": "mylocal-rg", |
| 152 | + "systemData": { |
| 153 | + "createdAt": "2025-05-21T00:44:16.385633+00:00", |
| 154 | + |
| 155 | + "createdByType": "User", |
| 156 | + "lastModifiedAt": "2025-05-21T00:48:34.016113+00:00", |
| 157 | + "lastModifiedBy": "00000000-0000-0000-0000-000000000000", |
| 158 | + "lastModifiedByType": "Application" |
| 159 | + }, |
| 160 | + "tags": null, |
| 161 | + "type": "microsoft.azurestackhci/galleryimages" |
| 162 | + } |
| 163 | + ``` |
| 164 | + |
| 165 | +1. To avoid costs associated with a disk, make sure to delete the managed disk that was used to create this image using the following command: |
| 166 | +
|
| 167 | + ```azurecli |
| 168 | + az disk delete --name $diskName --resource-group $resourceGroupName |
| 169 | + ``` |
| 170 | +
|
| 171 | +## Next steps |
| 172 | +
|
| 173 | +- [Create logical networks](./create-virtual-networks.md) |
0 commit comments