As per the Microsoft’s standard documentation "Availability Set" refers to two or more Virtual Machines deployed across different Fault Domains to avoid a single point of failure. "Fault Domain" is a collection of servers that share common resources such as power and network connectivity. “Virtual Machine" refers to persistent instance types that can be deployed individually or as part of an Availability Set.
Generally we configure Availability Set to minimize the downtime of our VM and make the application ‘Highly Available’. So to configure this, we need to add minimum two VM into AV Set with same functionality. The VMs in AV Set needs to be in different Fault domain and Update Domain. After this for AV Set VMs we need to configure Load Balancer. Load Balancer helps to distribute the traffic between VMs and make availability of application from running VM.
While creating new VM, you can add it to the Availability Set whether it is existing AV Set or you can create new AV Set for it. But once you created VM without the AV Set then you cannot add it to the Availability Set in Azure portal. You can move VM to the Availability set by using the PowerShell script provided below. So if you have fully configured VM without AV Set and you want to add it into AV Set as it is configuration, then this script will help.
It also have some limitations that we cannot add existing VM directly into AV Set. But if your existing VM have all configurations and you don’t want to create new VM from scratch for adding it into AV Set then this scripts helps you. This is possible by taking snapshot of current Virtual Machine, and create new VM from snapshot and add it into AV Set while creating. It will take 20 to 30 minutes to complete the wholeMake ready your VM to capture the image.
This process will shut down the Virtual Machine, and in portal after some time it will show the status of the Virtual Machine as “Stopped”.
Capture the image of Virtual Machine using PowerShell.
Note: - You need to have the Azure PowerShell Installed on your own machine from where you are going to capture and restore the VM. If you don’t have the Azure PowerShell then use this link to download the latest version of Azure PowerShell (download .msi file and install).
Note: You need to fill your environment specific values wherever the green color text appears.
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId “----your subscription id-------”
Stop-AzureRmVM -ResourceGroupName “YourResourceGroup” -Name “YourWindowsVMName”
After this command the status of the VM will be Stopped (deallocated) from Stopped which we can check in the Azure portal.
Set-AzureRmVm -ResourceGroupName “YourResourceGroup” -Name “YourWindowsVMName” –Generalized
After this command it will generalize the VM and immediate it will not show in the Azure portal. To check that you need to run following commands.
$vm = Get-AzureRmVM -ResourceGroupName “YourResourceGroup” -Name “YourWindowsVMName” –status
$vm.Statuses
Now it will show the status in PowerShell.
Save-AzureRmVMImage -ResourceGroupName “YourResourceGroup” –VMName “YourWindowsVMName” -DestinationContainerName “YourImagesContainerName” -VHDNamePrefix “DestinationStorageName” -Path “Yourlocalfilepath\Filename.json”
This command will take some time and capture the vhd image of you existing VM and save that vhd file into the storage container of the same resource group.
In -Path you need to give the local path and any file name. Then it will create the JSON file with all configuration information with your specified name and then it will save that JSON file to your specified local path.
You can check the captured image VHD path into the JSON file. In JSON file go to the “resources” section into that “storageProfile” and then “image” and into that you can find “uri” and its value i.e. path.
From this path you can easily identify the captured VHD image into Azure portal also. You are now able to create new VMs from this image using following PowerShell commands.
Deploy new VM from captured image. (For same and different Resource Group)
We can deploy the VM from the captured image into same as well as in different Resource Group also.
But for different resource group you have to do some extra work which is shown in the following steps, just follow these steps.
For Same Resource Group.
Login-AzureRmAccount
If you have only one subscription then it’s ok otherwise select you subscription using following command.
Set-AzureRmContext -SubscriptionId “----your subscription id-------”
#Global
$rgName = "your resource group name”
$location = "location"
#Compute
$vmName = "Name for New VM" ##e.g. $vmName = "test-webserver”
$computerName = "Computer Name" ##e.g. $computerName = "WindowsTestVM”
$vmSize = "VM Size" ##e.g. $vmSize = “Standard_A1”
$osDiskName = $vmName + "osDisk" ## let it be like this only
If you don’t have storage account or want to create new storage account for new VM then create new storage account using the Azure portal and get the storage account details using following PowerShell Commands.
$storageName = “Your storage account name”
$storageacc = Get-AzureRmStorageAccount -Name $storageName -ResourceGroupName $rgName
(You can check the configuration of the variable storage account in PowerShell by just typing the variable name. e.g. $storageacc and hit enter, it will display the details)
$vnetName = “Your Virtual Network Name”
$vnet = Get-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
(Create new Availability Set in Azure portal using browser and only supply values here. Ignore this if you have already created or want to add into existing AV Set.)
$avName="Your Availability Set Name"
$avSet = Get-AzureRmAvailabilitySet –Name $avName –ResourceGroupName $rgName
(Supply details of newly created NIC card or you can also use old one by deallocating from old VM)
$nicname = "Your NIC name"
$nic = Get-AzureRmNetworkInterface -Name $nicname -ResourceGroupName $rgName
(You can configure the Public IP Address and Network Security Group after creating new VM)
$cred = Get-Credential
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avset.Id
$vm = Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $computerName –Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
$YourStorageAccountName = “Your storage account name where you want to keep your new OS Disk”
$osDiskUri = “https://$YourStorageAccountName.blob.core.windows.net/container name (like vhds)/$osDiskName.vhd”
Write-Verbose $osDiskUri
$imageUri = "Your Captured image path from JSON file (you can find this path in JSON => resources> storageProfile> image>uri)"
$vm = Set-AzureRmVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri -CreateOption fromImage -SourceImageUri $imageUri –Windows
New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm –Verbose
(It will take some time and you can also see the status in Azure portal.)
For Different Resource Group
The above script will work fine where the Resource Group of captured image VHD and the Resource Group of New VM are same. And this script can capture the image and store only into the same resource group where the existing VM was running.
So if you want to create new VM from that image VHD into new or different resource group then you need to just copy or move that captured VM image VHD into the destination resource group’s storage account and in step number 7.6 (for image Uri value ) just give path of that moved image VHD. (For moving VHD from one resource group storage to another use the tools like Azure Storage Explorer from Microsoft or Cloud Explorer).
I hope, you have understood how to configure Availability Set for your existing VM. Now you will be able to configure your Virtual Machines into Availability Set without recreating it from scratch and without losing any configurations. Also you configure Load Balancer with it for traffic routing.
So, want to configure Availability Set for your existing Virtual Machines? How many of you faced this issue in new Azure Portal? By the way, is anyone getting error with the PowerShell script?
Do let us know your issues in the comments section below.