Azure Virtual Machines - Advanced

Introduction 

 
In this article, we are going through some advanced functionalities in order to take maximum advantage of your Azure Virtual Machines. Each advanced functionality comes with a practical sample and we are going through it, 
  1. Configuring the Availability Set of your Virtual Machine, in order to raise the availability up to 99.99% uptime guaranteed by SLA;
  2. Executing PowerShell script into your Virtual Machine, through the Run Command;
  3. How to migrate existing VHDs, to run on Azure Virtual Machines;  
In order to understand better this article, please check my previous article explaining the basics of Azure Virtual Machines,

Manage the availability of your Azure VMs

 
To take advantage of Azure 99,99% uptime guaranteed SLA you must take some steps as follows,
 
Availability sets
 
Availability sets can protect you from:
  1. System Reboots, to apply updates;
  2. Hardware failures;
  3. Network problems;
  4. Lack of energy.
But... how?
 
One availability set contains a set of update domains and fault domains that run in the same datacenter.
 
Update domains are where redundancy is applied to avoid a system reboot to impact all your Virtual Machines, in the same update domain group, due to updates in the Azure platform.
 
Fault domains are where redundancy is applied to avoid faults(hardware, energy or network problems) on hardware or software to impact all your Virtual Machines running in the same fault domain group.
 
When deploying Virtual Machines into a single Availability Set, the Availability Set is going to distribute your VMs automatically among the Fault & Update Domains as follows: 
 
Azure Virtual Machines - Advanced
 
Availability Zones
 
Availability Zones are Availability Sets running in different datacenter locations in the same Azure Region. It means that they are physically separated within each other, preventing data center failures and raising the guaranteed uptime SLA to 99.99%.`
 
Azure Virtual Machines - Advanced
 

Azure managed disks 

 
Azure Managed Disks are physical disks but virtualized. It brings lots of benefits to your Virtual Machine as follows:
  • Highly available, is designed to have 99,999% uptime having 3 replicas of your data;
  • Highly durable, having a 0% failure rate;
  • Integrated with Availability Sets, to avoid single point failure;
  • Scalability, being able to deploy up to 1.000 VMs per scale set;
  • Azure Backup, managing  and scheduling your backups;
  • Direct upload, being easier to handle your disk data.
 

Manage OS Upgrades with scheduled events

 
With Scheduled Events, you may plan for Virtual Machine maintenance in order to avoid any impact on your clients and services as far as your Virtual Machine will need to go down for a while.
 
Metadata Service API
  • If you have VNet in your Virtual Machine enabled, this is the endpoint at today's date,
    http://169.254.169.254/metadata/scheduledevents?api-version=2019-01-01

  • For Virtual Machines without VNet enabled, you must follow this tutorial to discover your endpoint,
    https://github.com/azure-samples/virtual-machines-python-scheduled-events-discover-endpoint-for-non-vnet-vm
Samples for Querying the API
 
You must make those calls from your Virtual Machine PowerShell
 
Request for Events:
  1. $metadataEndpoint = 'http://169.254.169.254/metadata/scheduledevents?api-version=2019-01-01' 
  2.   
  3. Invoke-RestMethod -Headers @{"Metadata"="true"} -URI $metadataEndpoint -Method get  
Starting an Event:
  1. $metadataEndpoint = 'http://169.254.169.254/metadata/scheduledevents?api-version=2019-01-01'  
  2.   
  3. Invoke-RestMethod -Uri $metadataEndpoint -Headers @{"Metadata"="true"} -Method POST -Body '{"StartRequests": [{"EventId": "<your event id goes here>"}]}'  

Enabling and disabling Scheduled Events

  • Enabled automatically after making a request to the Metadata Service API;
  • Disabled automatically after not making any request to the Metadata Service API for 24 hours.
P.S: Scheduled events are not available in every Azure Region, check region availability:
 

Using a Load Balancer to distribute incoming calls 

 
The Load Balancer is a great tool to distribute your incoming request through your Virtual Machines in order to do not overload any Virtual Machine, distributing requests among your available Virtual Machines according to your needs.
 
Health Probe
 
Health probes are going to constantly run a health check, based on configurations set by you, against your VMs in order to set your VMs to be available or unavailable to receive requests.
 
 
Load Balancer Rules 
 
We create rules in the Load Balancer to define how the incoming traffic flow is going to be distributed among the available Virtual Machines. You may also configure if you want a Health Probe running with your rule in order to do not distribute incoming traffic to your unhealthy VMs.
 
 

Application Tiers

 
Applications that make usage of their software architecture being grouped in tiers may take advantage of Application Tiers, in order to group your tiers in a different group of Virtual Machines. So you're able to separate your application tiers in different availability zones or availability sets.
 
A good practice would be to have each tier of your application in a different Application Tier and having each Application Tier in a different Availability Set/Zone. Remembering that an Availability Set/Zone works better with multiple Virtual Machines.
 
Azure Virtual Machines - Advanced 
https://docs.microsoft.com/en-us/azure/virtual-machines/windows/manage-availability
 

Running PowerShell scripts in your Azure Windows VM

 
You may use the Run Command feature to run PowerShell commands remotely by your VM Agent in your Virtual Machine. It offers a fast and safe way to run commands in your Virtual Machine in order to diagnose, troubleshoot and remediate issues that are affecting your VM.
 
Available commands to run through the run command:
  • RunPowerShellScript, where you may run your custom script;
  • EnableRemotePS, enabling your VM to accept remote PowerShell commands;
  • EnableAdminAccount, enabling admin account;
  • IPConfig, working as normal IPConfig command; 
  • RDPSettings, showing registry and domain policy settings;
  • ResetRDPCert, removing SSL certificate and resetting your RDP listener;
  • SetRDPPort, setting the port number for Remote Desktop Access. 
Running scripts remotely has some limitations, as Microsoft describes:
  • Script Output is limited to the last 4,096 bytes.
  • The minimum time to run a script is about 20 seconds.
  • Scripts run as System on Windows.
  • One script at a time can run.
  • Scripts that prompt for information (interactive mode) are not supported.
  • You can't cancel a running script.
  • The maximum time a script can run is 90 minutes. After that, it will time out.
  • Outbound connectivity from the VM is required to return the results of the script.
 

Migrating existing VHDs to Azure VM

If you have an existing VHD and wants to migrate to Azure Virtual Machine you can migrate it without any problem using PowerShell, as follows:
 
Variables used around code,
  1. $diskName= "sampleDisk"  
  2. $diskLocalPath="C:\myFolder\disk.vhd"  
  3. $imageName="sampleImage"  
  4. $location= "yourLocation"  
  5. $resourceGroup= "sampleResourceGroup"  
  6. $virtualMachineName="sampleVm"  
Upload your VHD,
  1. #grants a temporary write access  
  2. $diskTempAccess = Grant-AzDiskAccess -ResourceGroupName $resourceGroup -DiskName $diskName -DurationInSecond 86400 -Access 'Write'  
  3.   
  4. #copy your disk  
  5. AzCopy.exe copy $diskLocalPath  $diskTempAccess.AccessSAS --blob-type PageBlob  
Create an Image from your VHD,
  1. $disk = Get-AzDisk -ResourceGroupName $resourceGroup -DiskName $diskName  
  2.   
  3.   
  4. $imageConfig = New-AzImageConfig   
  5.    -Location $location  
  6. $imageConfig = Set-AzImageOsDisk   
  7.    -Image $imageConfig   
  8.    -OsState Generalized   
  9.    -OsType Windows   
  10.    -ManagedDiskId $disk.Id  
  11.   
  12.    $image = New-AzImage   
  13.    -ImageName $imageName   
  14.    -ResourceGroupName $resourceGroup   
  15.    -Image $imageConfig  
Create a new Virtual Machine using the copy of your VHD,
  1. New-AzVm `  
  2.     -ResourceGroupName $resourceGroup   
  3.     -Name $virtualMachineName  
  4.     -Image $image.Id   
  5.     -Location $location   
  6.     -VirtualNetworkName "your Vnet"   
  7.     -SubnetName "your subnet"   
  8.     -SecurityGroupName "your security group"   
  9.     -PublicIpAddressName "your ip"   
  10.     -OpenPorts 3389  
Complete code
  1. $diskName= "sampleDisk"  
  2. $diskLocalPath="C:\myFolder\disk.vhd"  
  3. $imageName="sampleImage"  
  4. $location= "yourLocation"  
  5. $resourceGroup= "sampleResourceGroup"  
  6. $virtualMachineName="sampleVm"  
  7.   
  8.   
  9. #upload ------------------------------------------------------  
  10. #grants a temporary write access  
  11. $diskTempAccess = Grant-AzDiskAccess -ResourceGroupName $resourceGroup -DiskName $diskName -DurationInSecond 86400 -Access 'Write'  
  12.   
  13. #copy your disk  
  14. AzCopy.exe copy $diskLocalPath  $diskTempAccess.AccessSAS --blob-type PageBlob  
  15.   
  16.   
  17. #create custom image  -----------------------------------------  
  18. $disk = Get-AzDisk -ResourceGroupName $resourceGroup -DiskName $diskName  
  19.   
  20.   
  21. $imageConfig = New-AzImageConfig   
  22.    -Location $location  
  23. $imageConfig = Set-AzImageOsDisk   
  24.    -Image $imageConfig   
  25.    -OsState Generalized   
  26.    -OsType Windows   
  27.    -ManagedDiskId $disk.Id  
  28.   
  29.    $image = New-AzImage   
  30.    -ImageName $imageName   
  31.    -ResourceGroupName $resourceGroup   
  32.    -Image $imageConfig  
  33.   
  34.   
  35. #create VM  
  36. New-AzVm `  
  37.     -ResourceGroupName $resourceGroup   
  38.     -Name $virtualMachineName  
  39.     -Image $image.Id   
  40.     -Location $location   
  41.     -VirtualNetworkName "your Vnet"   
  42.     -SubnetName "your subnet"   
  43.     -SecurityGroupName "your security group"   
  44.     -PublicIpAddressName "your ip"   
  45.     -OpenPorts 3389  
External References