Daniel W.
Daniel W.

Reputation: 1198

How to create a VM scale set from a Snapshot

I want to create a VM Scale set and use a snapshot as base for my windows VMs. As the Set-AzureRmVmssStorageProfile only accepts images my first try was to convert the snapshot to an image by use:

$rgName = #...
$location = #...
$snapshotName = "mySnapshot"
$imageName = "myImage"

$snapshot = Get-AzureRmSnapshot -ResourceGroupName $rgName -SnapshotName $snapshotName

$imageConfig = New-AzureRmImageConfig -Location $location
$imageConfig = Set-AzureRmImageOsDisk -Image $imageConfig -OsState Generalized -OsType Windows -SnapshotId $snapshot.Id

New-AzureRmImage -ImageName $imageName -ResourceGroupName $rgName -Image $imageConfig

But in this case the image that is created has no Source Blob URI:

enter image description here

what gives me the error:

New-AzureRmVmss : The URI Microsoft.Azure.Commands.Compute.Automation.Models.PSImage does not look to be correct blob URI.

On my deploy commands for azure:

$vmss = New-AzureRmVmssConfig -Location $loc -SkuCapacity 2 -SkuName "Standard_DS1_v2" -UpgradePolicyMode "manual" -ErrorAction Stop

Add-AzureRmVmssNetworkInterfaceConfiguration -VirtualMachineScaleSet $vmss -Name "vmssNetwork" -Primary $true -IPConfiguration $ipConfig 
Set-AzureRmVmssStorageProfile -VirtualMachineScaleSet $vmss -OsDiskCreateOption "FromImage" -OsDiskCaching "None" `
            -Image $ImgRef -OsDiskOsType Windows -OsDiskName "C"
Set-AzureRmVmssOSProfile -ComputerNamePrefix $vmNamePrefix -AdminUsername $adminUsername -AdminPassword $adminPassword -VirtualMachineScaleSet $vmss

New-AzureRmVmss -ResourceGroupName $currentrg -Name $vmssName -VirtualMachineScaleSet $vmss -Verbose -ErrorAction Stop;

Is there a other way to create the image or set a source blob uri? Or is it possible to use a snapshot for creating an VM Scale Set?

-- Edit 1 --

Afer the hint from Charles Xu I changhed the image creation to first create a dik, but I still get the same error. New Code is:

$rgName = #...
$location = #...
$snapshotName = "mySnapshot"
$imageName = "myImage"
$storageType = 'Standard_LRS'
$diskName = "myDisk"

$snapshot = Get-AzureRmSnapshot -ResourceGroupName $rgName -SnapshotName $snapshotName

$diskConfig = New-AzureRmDiskConfig -AccountType $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id
$disk = New-AzureRmDisk -Disk $diskConfig -ResourceGroupName $rgName -DiskName $diskName

$imageConfig = New-AzureRmImageConfig -Location $location
$imageConfig = Set-AzureRmImageOsDisk -Image $imageConfig -OsState Generalized -OsType Windows -ManagedDiskId $disk.Id     

New-AzureRmImage -ImageName $imageName -ResourceGroupName $rgName -Image $imageConfig

Upvotes: 1

Views: 2586

Answers (2)

dave zhou
dave zhou

Reputation: 89

folks. So what about create a "Virtual Machine in Scale Set" from a customized snapshot. Is this possible or one scale set could only have one base image and all vms under this scale set could only reimaged to the same baseline ?

Upvotes: 0

Charles Xu
Charles Xu

Reputation: 31404

You can create an image from an Azure VM. For example, you can create a windows image from the windows VM through PowerShell, see Create and use a custom image for virtual machine scale sets with Azure PowerShell. When the image is OK, Just create the VMSS like this:

New-AzureRmVmss `
  -ResourceGroupName "myResourceGroup" `
  -Location "EastUS" `
  -VMScaleSetName "myScaleSet" `
  -VirtualNetworkName "myVnet" `
  -SubnetName "mySubnet" `
  -PublicIpAddressName "myPublicIPAddress" `
  -LoadBalancerName "myLoadBalancer" `
  -UpgradePolicyMode "Automatic" `
  -ImageName "yourImage"

Also, the snapshot is OK, but you should create the image from the snapshot first. And then create the VMSS from the image. With the command New-AzureRmImage, the image should be a managed image, so you cannot see the URI. Just use the managed image Id in the command like this:

Set-AzureRmVmssStorageProfile -VirtualMachineScaleSet $vmss -OsDiskCreateOption "FromImage" -OsDiskCaching "None" -ImageReferenceId yourImageId -OsDiskOsType Windows -OsDiskName "C"

And just talk about how to create images, I would suggest you the Packer and there is an example here.

Update

I assume that your custom image is prepared. And the PowerShell script like this:

#Get the custom image 
$image = Get-AzureRmImage -ResourceGroupName charlesTerraform -ImageName myPackerImage

# Get the existing Vnet
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName charlesTerraform -Name pakcerVnet

#IP configuration
$ipName = "ipConfig"

#create the IP configuration
$ipConfig = New-AzureRmVmssIpConfig -Name $ipName -LoadBalancerBackendAddressPoolsId $null -SubnetId $vnet.Subnets[0].Id

#create vmss configuration
$vmss = New-AzureRmVmssConfig -Location "East US" -SkuCapacity 2 -SkuName "Standard_DS1_v2" -UpgradePolicyMode "manual" -ErrorAction Stop

##Add the network interface configuration to the scale set configuration
Add-AzureRmVmssNetworkInterfaceConfiguration -VirtualMachineScaleSet $vmss -Name "vmssNetwork" -Primary $true -IPConfiguration $ipConfig 

# set the stroage profile 
Set-AzureRmVmssStorageProfile -VirtualMachineScaleSet $vmss -OsDiskCreateOption "FromImage" -OsDiskCaching "None" -ImageReferenceId $image.Id -OsDiskOsType Linux 

#set the os profile
Set-AzureRmVmssOSProfile -ComputerNamePrefix "Test" -AdminUsername "azureuser" -AdminPassword "azureuser@2018" -VirtualMachineScaleSet $vmss

#create the vmss
New-AzureRmVmss -ResourceGroupName charlesTerraform -Name TestVmss -VirtualMachineScaleSet $vmss

Upvotes: 1

Related Questions