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.
- Connect to your virtual machine through Remote Desktop Connection by using the public IP address or just go to Azure portal and select your VM and then click “Connect”.
- Use your credentials to login to VM. Then go to the Command Prompt and right click on it and select “Run as administrator”
- In CMD go to the directory “C:\Windows\System32\Sysprep> “then type “exe” and hit enter.
- It will open the System Preparation Tool window.
- Then select the System Cleanup Action as “Enter System Out-of-Box Experience (OOBE)”, and make “Generalize” option checked and select Shutdown option as “Shutdown” and finally select “Ok” to save the setting.
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.
- Open the Azure PowerShell (Open as administrator) and login to the Azure portal(Administrator account) using the following command
Login-AzureRmAccount
- If you have single subscription under this account then default it will select that subscription, and if you have multiple subscription under this account then select the specific subscription where your VM’s are running.
To select the specific subscription use following command
Set-AzureRmContext -SubscriptionId “----your subscription id-------”
- Then you need to deallocate the Virtual Machine’s all resources such as NIC, public IP and Security Group etc. by using the following command
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.
- You need to generalize the VM again in the Azure portal and we can do this by using following command. (However we did this by using the sysprep tool but we need to Generalize it from azure also, so we need to execute the following command).
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.
- Now capture the Virtual Machine image into the storage container.
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.
- Open the Azure PowerShell as Administrator and run following command to login to Azure.
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-------”
- Set the values of global variable.
If you want to create everything into new Resource Group then Crete new resource Group in Azure portal and also create new Network Interface Card, Availability set into Azure portal for ease and supply only values here then it will retrieve the details of it.
#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.
- Get the Storage account details
$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)
- Get the details of the Virtual Network
$vnetName = “Your Virtual Network Name”
$vnet = Get-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
- Get the details of the Availability Set.
(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
- Get the details of the Network Interface.
(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)
- Set up the configuration for new VM.
- Get the Credentials for new VM using following command (You need to supply values).
$cred = Get-Credential
- Save the configuration into the VM object
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avset.Id
- Set the OS configuration and Credentials
$vm = Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $computerName –Credential $cred -ProvisionVMAgent -EnableAutoUpdate
- Add Network Interface Configuration
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
- Set the OS Disk URI for new VM. (In the destination storage account there need to be the container named “VHDs”. If you have another container then replace the name of that container into osDiskUri path where VHD is there)
$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
- Set the path of the Captured image.
$imageUri = "Your Captured image path from JSON file (you can find this path in JSON => resources> storageProfile> image>uri)"
- Save the configuration for creating new VM from image
$vm = Set-AzureRmVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri -CreateOption fromImage -SourceImageUri $imageUri –Windows
- Finally create the VM from your configuration. (Before executing this command you can check the VMs all configuration by ruing the command “$vm” and enter. It will display the configurations.)
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.