Azure Resource Manager – Multiple VMs behind a load balancer

This post is part 4 of a small series and stems from this post https://marckean.com/2016/05/17/azure-resource-groups-networks/

This post focuses on creating a two virtual machines into the Internal subnet of the target example architecture diagram below. These VMs will utilise inbound NAT rules from the load balancer. Remember, that the subnet based NSG rule/s will also be applied as the NICs of both machines will live on the Internal subnet which has an NSG attached to it.

ShowNetwork

The PowerShell below, just simply edit / check the variables to suit before running it.

#Log into both old and new Azure
Login-AzureRmAccount
 
#Choose subscription 'new' Azure
$subscription = (Get-AzureRmSubscription | Out-GridView -Title "Select the Azure subscription that you want to use ..." -PassThru).SubscriptionName
Select-AzureRmSubscription -SubscriptionName $subscription
 
$RGName = "Show-Internal_VMs"
$location = "australiaeast"
 
####################### | Create the Resource Group | ####################### | @marckean
cls
Write-Host "`n`tCreating the target resource group $RGName (if it don't exist already)..." -ForegroundColor Cyan
#region
if(!(Get-AzureRmResourceGroup -Name $RGName -Location $location -ErrorAction SilentlyContinue)){
New-AzureRmResourceGroup -Name $RGName -Location $location -Force}
 
####################### | Variable Settings | ####################### | @marckean
$date = "20160512"
$random = Get-Random -Minimum 10 -Maximum 999
$publisher = "MicrosoftWindowsServer"
$offer = "WindowsServer"
$sku = "2012-R2-Datacenter"
$version = "latest"
#Storage
$StorageAccountName = $date + "stg" + $random # Storage account name must be between 3 and 24 characters in length and use numbers and lower-case letters only
$StorageType = "Standard_LRS"
#Virtual Machine
$AVSetName = "AVSet"
$VMName = "Demo-VM"
$VMSize = "Standard_A2"
$cred = Get-Credential -Message "Type the name and password for the local administrator account."
#Virtual Network
$vNetName = "Demo-vNet"
$vNetRGName = "Show-vNet"
$subnetName = "Internal"
#PIP
$PIPName = "Demo-PIP"
$PublicPIPName = "demopip" + $random  # Name must conform to the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$
#NIC
$NICName = "Demo-NIC"
#NLB
$ALBName = "Demo-ALB"
$beAddressPoolName = "Demo-BEAP"
$HealProbeName = "Demo-HP"
 
### Create Public IP Address
$pip = New-AzureRmPublicIpAddress -ResourceGroupName $RGName -Name $PIPName -Location $location -AllocationMethod Dynamic -DomainNameLabel $PublicPIPName
 
### Frontend IP Configuration
$feIpConfig = New-AzureRmLoadBalancerFrontendIpConfig -Name $RGName -PublicIpAddress $pip
 
### Inbound NAT rules
$inboundNatRule1 = New-AzureRmLoadBalancerInboundNatRuleConfig -Name "RDP1" `
    -FrontendIpConfiguration $feIpConfig `
    -Protocol TCP -FrontendPort 3441 -BackendPort 3389
 
$inboundNatRule2 = New-AzureRmLoadBalancerInboundNatRuleConfig -Name "RDP2" `
    -FrontendIpConfiguration $feIpConfig `
    -Protocol TCP -FrontendPort 3442 -BackendPort 3389
 
### Backend Address Pool
$beAddressPool = New-AzureRmLoadBalancerBackendAddressPoolConfig -Name $beAddressPoolName
 
$healthProbe = New-AzureRmLoadBalancerProbeConfig -Name $HealProbeName `
   -RequestPath "HealthProbe.aspx" -Protocol http -Port 80 `
   -IntervalInSeconds 15 -ProbeCount 2
 
### Load Balancer Rules
$lbrule = New-AzureRmLoadBalancerRuleConfig -Name "HTTP" `
   -FrontendIpConfiguration $feIpConfig -BackendAddressPool $beAddressPool `
   -Probe $healthProbe -Protocol Tcp -FrontendPort 80 -BackendPort 80
 
### Create Azure Load Balancer
$alb = New-AzureRmLoadBalancer -ResourceGroupName $RGName `
   -Name $ALBName -Location $location -FrontendIpConfiguration $feIpConfig `
   -InboundNatRule $inboundNatRule1,$inboundNatRule2 `
   -LoadBalancingRule $lbrule -BackendAddressPool $beAddressPool `
   -Probe $healthProbe
 
### Create NICs
$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $vnet
 
$nic1 = New-AzureRmNetworkInterface -ResourceGroupName $RGName `
   -Name "$NICName-1" -Subnet $subnet -Location $location `
   -LoadBalancerInboundNatRule $alb.InboundNatRules[0] `
   -LoadBalancerBackendAddressPool $alb.BackendAddressPools[0]
 
$nic2 = New-AzureRmNetworkInterface -ResourceGroupName $RGName `
   -Name "$NICName-2" -Subnet $subnet -Location $location `
   -LoadBalancerInboundNatRule $alb.InboundNatRules[1] `
   -LoadBalancerBackendAddressPool $alb.BackendAddressPools[0]
 
### Create Availability Set
New-AzureRmAvailabilitySet -ResourceGroupName $RGName -Name $AVSetName -Location $location
 
$avset = Get-AzureRmAvailabilitySet -ResourceGroupName $RGName -Name $AVSetName
 
### Create Storage Account
New-AzureRmStorageAccount -ResourceGroupName $RGName -Name $StorageAccountName -Location $location -Type $StorageType
 
[array]$nics = @($nic1,$nic2)
 
For ($i=0; $i -le 1; $i++)  {
        
    $vmName2 = "$VMName-w$i"
 
    $vmConfig = New-AzureRmVMConfig -VMName $vmName2 -VMSize "Standard_A1" `
       -AvailabilitySetId $avSet.Id |
 
        Set-AzureRmVMOperatingSystem -Windows -ComputerName $vmName2 -Credential $cred -ProvisionVMAgent -EnableAutoUpdate  |
 
        Set-AzureRmVMSourceImage -PublisherName $publisher -Offer $offer -Skus $sku -Version $version |
 
        Set-AzureRmVMOSDisk -Name $vmName2 -VhdUri "https://$StorageAccountName.blob.core.windows.net/vhds/$RGName-$Int-os-$i.vhd" `
           -Caching ReadWrite -CreateOption fromImage  |
 
        Add-AzureRmVMNetworkInterface -Id $nics[$i].Id
 
    New-AzureRmVM -ResourceGroupName $RGName -Location $location -VM $vmConfig
}