How can I use the Hybrid Use Benefit in Azure?

 

There are a few questions about Azure HUB I have been getting asked about with education customers so I put together a quick FAQ on what it is and how to use it:

 

What is the Hybrid Use Benefit (HUB)?

Azure Hybrid Use Benefit is where you can bring your own on premises Windows Server licenses and Windows OS sysprepped image covered with Software Assurance to license Azure hosted Windows Server virtual machines. For each Windows Server 2 processor license with Software Assurance, you can run two virtual machines with up to 8 cores each, or one virtual machine with up to 16 cores.  See more on Azure HUB here.

 

Why would I use Azure HUB?

You would leverage Azure Hybrid Use Benefit to reduce your monthly Azure virtual machine costs since you could eliminate the additional Windows Server license cost when using Windows Server from the Azure gallery. Instead, you would just pay for Azure base compute rate since you are leveraging your on premises Windows Server license.

See example below of the type of virtual machine cost savings that may apply annually with using Azure HUB (BYOL) model on the right column vs. leveraging the Azure based Windows Server license cost on the left column: image_thumb2

 

Can I use Azure HUB with Windows Server licenses if I don’t have Software Assurance or an Enterprise Agreement subscription?

No, Software Assurance or Enterprise Agreement subscription is required for Azure Hybrid Use Benefit to apply.

 

Can I convert my existing ARM VMs to use HUB?

As of January 2018, the answer is now yes. See steps to convert existing VMs to leverage  HUB here.

What are my options to use Azure HUB?

As of 1/20/18 you now have two options:

Option 1 - Build an Image from Marketplace and enable 'Already have a Windows license' on that image or enable via PowerShell or CLI. That toggle will enable HUB on that VM.  

See more on using HUB with Marketplace images here .

Option 2 - Upload your own custom VHD Windows Server image into Azure for use with HUB (requires Software Assurance):

See next section below for steps on option 2.

How can I use Azure HUB with brand new Azure VMs from custom sysprepped VHDs I have uploaded?

For brand new Windows Server ARM VMs where you would like to leverage Azure HUB, you need to first upload a local Windows Server VHD image to Azure storage using something like this:

 

1) Follow the steps for uploading a local Sysprepped Windows Server VHD image to Azure using ARM here.

 

An example PowerShell upload of Sysprepped local Windows Server image VHD (note: must be a VHD file not VHDX) using PowerShell: image

 

2) Next, when creating a Windows Server Azure VM from the custom sysprepped VHD, you need to add in the licenseType with Windows_Server property when using either a JSON template or PowerShell to ensure HUB is enabled. Hybrid Use Benefit will not be enabled without following these options.

note: You first need to update your Azure PowerShell module to 1.2.3 or higher for –licensetype switch to work in PowerShell. See my other post here on how to do that.

 

Option 1 using –licenseType with PowerShell and custom VHD image

Here is an end to end PowerShell example I created which will create the VM from a custom sysprepped and uploaded VHD and set the licenseType flag to enable HUB :

## VM Account# Credentials for Local Admin account you created in the sysprepped (generalized) vhd image$VMLocalAdminUser = "LocalAdminUser"$VMLocalAdminSecurePassword = ConvertTo-SecureString "Password" -AsPlainText -Force## Azure Account$LocationName = "westus"$ResourceGroupName = "MyResourceGroup"# storage account was precreated$StorageAccount = "Mydisk"

## VM
$OSDiskName = "MyClient"
$ComputerName = "MyClientVM"
$OSDiskUri = "https://Mydisk.blob.core.windows.net/disks/MyOSDisk.vhd"
$SourceImageUri = "https://Mydisk.blob.core.windows.net/vhds/MyOSImage.vhd"
$VMName = "MyVM"

# you can pick any VM size. This was for high performance
$VMSize = "Standard_DS3"
$OSDiskCaching = "ReadWrite"
$OSCreateOption = "FromImage"

## Networking
$DNSNameLabel = "mydnsname"  # mydnsname.westus.cloudapp.azure.com
$NetworkName = "MyNet"
$NICName = "MyNIC"
$PublicIPAddressName = "MyPIP"
$SubnetName = "MySubnet"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"

$SingleSubnet = New-AzureRmVirtualNetworkSubnetConfig –Name $SubnetName –AddressPrefix $SubnetAddressPrefix

$Vnet = New-AzureRmVirtualNetwork –Name $NetworkName –ResourceGroupName $ResourceGroupName –Location $LocationName –AddressPrefix $VnetAddressPrefix –Subnet $SingleSubnet

$PIP = New-AzureRmPublicIpAddress –Name $PublicIPAddressName –DomainNameLabel $DNSNameLabel –ResourceGroupName $ResourceGroupName –Location $LocationName -AllocationMethod Dynamic

$NIC = New-AzureRmNetworkInterface –Name $NICName –ResourceGroupName $ResourceGroupName –Location $LocationName –SubnetId $Vnet.Subnets[0].Id –PublicIpAddressId $PIP.Id

$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);

$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -SourceImageUri $SourceImageUri -Caching $OSDiskCaching -CreateOption $OSCreateOption -Windows

New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $LocationName –LicenseType “Windows_Server” -VM $VirtualMachine -Verbose

 

Executing the PowerShell script above with HUB enabled: image

 

If all went well, you will have a new Azure VM server built with the PowerShell script above and HUB will be enabled: image

Here is an excellent video walkthrough of these steps here from my colleague Eric DeBord:

[embed]https://www.youtube.com/watch?v=kxRo85G6yKc[/embed]

 

Option 2 is to add licenseType to your JSON template such as this example:

 

Here is a sample JSON template which can build a VM from an uploaded sysprepped VHD file and I added the enable HUB option with the licenseServer property:

{"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#","contentVersion": "1.0.0.0","parameters": {"userImageStorageAccountName": {"type": "string","metadata": {"description": "This is the name of the your storage account"}},"osDiskVhdUri": {"type": "string","metadata": {"description": "Uri of the your user image"}},"dnsLabelPrefix": {"type": "string","metadata": {"description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."}},"adminUserName": {"type": "string","metadata": {"description": "UserName for the Virtual Machine"}},"adminPassword": {"type": "securestring","metadata": {"description": "Password for the Virtual Machine"}},"osType": {"type": "string","allowedValues": ["Windows","Linux"],"metadata": {"description": "This is the OS that your VM will be running"}},"vmSize": {"type": "string","metadata": {"description": "This is the size of your VM"}}},"variables": {"location": "[resourceGroup().location]","publicIPAddressName": "userImagePublicIP","vmName": "userImageVM","virtualNetworkName": "userImageVNET","nicName": "userImageVMNic","addressPrefix": "10.0.0.0/16","subnet1Name": "Subnet-1","subnet1Prefix": "10.0.0.0/24","publicIPAddressType": "Dynamic","vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]","subnet1Ref": "[concat(variables('vnetID'),'/subnets/',variables('subnet1Name'))]","osDiskVhdName": "[concat('https://',parameters('userImageStorageAccountName'),'.blob.core.windows.net/vhds/',variables('vmName'),'osDisk.vhd')]","apiVersion": "2015-06-15"},"resources": [{"apiVersion": "[variables('apiVersion')]","type": "Microsoft.Network/publicIPAddresses","name": "[variables('publicIPAddressName')]","location": "[variables('location')]","properties": {"publicIPAllocationMethod": "[variables('publicIPAddressType')]","dnsSettings": {"domainNameLabel": "[parameters('dnsLabelPrefix')]"}}},{"apiVersion": "[variables('apiVersion')]","type": "Microsoft.Network/virtualNetworks","name": "[variables('virtualNetworkName')]","location": "[variables('location')]","properties": {"addressSpace": {"addressPrefixes": ["[variables('addressPrefix')]"]},"subnets": [{"name": "[variables('subnet1Name')]","properties": {"addressPrefix": "[variables('subnet1Prefix')]"}}]}},{"apiVersion": "[variables('apiVersion')]","type": "Microsoft.Network/networkInterfaces","name": "[variables('nicName')]","location": "[variables('location')]","dependsOn": ["[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]","[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"],"properties": {"ipConfigurations": [{"name": "ipconfig1","properties": {"privateIPAllocationMethod": "Dynamic","publicIPAddress": {"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"},"subnet": {"id": "[variables('subnet1Ref')]"}}}]}},{"apiVersion": "[variables('apiVersion')]","type": "Microsoft.Compute/virtualMachines","name": "[variables('vmName')]","location": "[variables('location')]","dependsOn": ["[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"],"properties": {"licenseType": "Windows_Server","hardwareProfile": {"vmSize": "[parameters('vmSize')]"},"osProfile": {"computerName": "[variables('vmName')]","adminUsername": "[parameters('adminUsername')]","adminPassword": "[parameters('adminPassword')]"},"storageProfile": {"osDisk": {"name": "[concat(variables('vmName'),'-osDisk')]","osType": "[parameters('osType')]","caching": "ReadWrite","createOption": "FromImage","image": {"uri": "[parameters('osDiskVhdUri')]"},"vhd": {"uri": "[variables('osDiskVhdName')]"}}},"networkProfile": {"networkInterfaces": [{"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"}]},"diagnosticsProfile": {"bootDiagnostics": {"enabled": "true","storageUri": "[concat('https://',parameters('userImageStorageAccountName'),'.blob.core.windows.net')]"}}}}]}

 

Executing the JSON template to enable HUB:

To leverage the JSON template above with HUB, I used this syntax: New-AzureRMResourceGroupDeployment –name XYZdeploy –resourcegroupname samplegroupname –templatefile “c:\filepath\abc.json” image

 

If your JSON template worked, such as above, you will get a Windows VM with HUB enabled: image

 

3) The final step in the HUB process is to verify the licenseType flag is present ensure HUB is in use for the Azure VMs you have created:

 

Option 1: Using PowerShell:

Get-AzureRmVM -ResourceGroupName "ResourceGroup11" -Name "WindowsServer07"

Look for LicenseType : Windows_Server such as below: image

 

Option 2: Using Azure Resource Explorer:

1) Go to https://resources.azure.com

2) Drill down to the VM you created and under properties section you should see “licenseType”: “Windows_Server”, like below on the JSON view:

 

image

 

I hope this walkthrough on how to enable Hybrid Use Benefit was useful.