Infrastructure as Code: Azure Edition

Since I’ve been using AWS as a hobbyist for about a decade it is the public cloud I am most comfortable with. Lately to expand my horizons I’ve been learning about Microsoft’s take on it with Azure. I hope I’m not too bias since its easier for me to favor AWS since I’ve been using it for so long however my initial take on Azure is not positive. It is slow. I’m working on a comparison in terms of speed between AWS and Azure with the goal of standing up a 2 node load balanced IIS cluster. While I continue to work on making a good comparison write-up here is the code that deploys out the Azure resources. It is written in PowerShell and includes a function that measures completion time.

Import-Module Az
function elapsedTime {
    $CurrentTime = $(get-date)
    $elapsedTime = $CurrentTime - $StartTime
    $elapsedTime = [math]::Round($elapsedTime.TotalSeconds,2)
    Write-Host "Elapsed time in seconds: " $elapsedTime -BackgroundColor Green
}
#Run this to connect to Azure account if needed
#Connect-AzAccount
#Captures start time for script elapsed time measurement
$StartTime = $(get-date)
#Sets "Constants" to be used throughout script
$resourceGroup = "DisposableLab"
$location = Get-AzLocation | Where-Object {$_.DisplayName -like "North Central US"}
$vnet = "vnet1"
$subnet = "default"
$securityGroup = "DisposableLabSecurityGroup"
$secpasswd = ConvertTo-SecureString "password" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
$lbname = "WebAppWinLB"
$availSetName = "WinWebappAvailabilitySet"
#Creates Availability Set to allow both servers to be load balanced
New-AzAvailabilitySet `
   -Location $location.Location `
   -Name $availSetName `
   -ResourceGroupName $resourceGroup `
   -Sku aligned `
   -PlatformFaultDomainCount 2 `
   -PlatformUpdateDomainCount 2

$publicIp = New-AzPublicIpAddress -Name 'LB1PublicIP' -ResourceGroupName $resourceGroup -AllocationMethod Static -Location $location.Location
#sets up the inbound IP pool for the load balancer
$feip = New-AzLoadBalancerFrontendIpConfig -Name 'myFrontEndPool' -PublicIpAddress $publicIp
$bepool = New-AzLoadBalancerBackendAddressPoolConfig -Name 'myBackEndPool' 
#creates health check for load balancer
$probe = New-AzLoadBalancerProbeConfig `
 -Name 'myHealthProbe' `
 -Protocol Http -Port 80 `
 -RequestPath / -IntervalInSeconds 360 -ProbeCount 5
#creates load balancing rule
$rule = New-AzLoadBalancerRuleConfig `
  -Name 'webInbound' -Protocol Tcp `
  -Probe $probe -FrontendPort 80 -BackendPort 80 `
  -FrontendIpConfiguration $feip `
  -BackendAddressPool $bepool
#creates new LB from settings gathered so far
 $lb = New-AzLoadBalancer `
  -ResourceGroupName $ResourceGroup `
  -Name $lbname `
  -Location $location.Location `
  -FrontendIpConfiguration $feip `
  -BackendAddressPool $bepool `
  -Probe $probe `
  -LoadBalancingRule $rule 

elapsedTime

$serversCount = 2
for ($i=1; $i -le $serversCount; $i++) {
  elapsedTime
$VMName = "WebappWin" + $i
Write-Host "Creating VM " + $VMName
#Generates new public IP for the new load balancer to be created
$VM = Get-AzVM -Name $VMName
$NIC = Get-AzNetworkInterface -Name $VMName
#creates new VM
New-AzVm `
    -Credential $credential `
    -ResourceGroupName $resourceGroup `
    -Name $VMName `
    -Location $location.Location `
    -VirtualNetworkName $vnet `
    -SubnetName $subnet `
    -SecurityGroupName $securityGroup `
    -PublicIpAddressName "$($VMName)PublicIP" `
    -AvailabilitySetName $availSetName
Write-Host "VM $($VMName) has been created"
elapsedTime
Write-Host "Installing IIS for " + $VMName
$PublicSettings = '{"commandToExecute":"powershell Add-WindowsFeature Web-Server"}'
#Waits a few seconds for the VM to become available to recieve 
Start-Sleep -Seconds 5
Set-AzVMExtension -ExtensionName "IIS" -ResourceGroupName $resourceGroup -VMName $vmName `
  -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion 1.4 `
  -SettingString $PublicSettings -Location $location.location
Write-Host "IIS Installed for $($VMName)"
elapsedTime
Write-Host "Deploying website for " + $VMName

Invoke-AzVMRunCommand -ResourceGroupName $resourceGroup -VMName $VMName -CommandId "RunPowerShellScript" -ScriptPath "C:\pathhere\WebsiteTest\deployWebsite.ps1"
Write-Host "Website deployed on $($VMname)"
elapsedTime
#Gets load balancer object based on name
$lb = Get-AzLoadBalancer -Name $lbname
$backendConfig = Get-AzLoadBalancerBackendAddressPoolConfig -LoadBalancer $lb
#Get's NIC from virtual machine
$NIC = Get-AzNetworkInterface -Name $VMName
#Removes VM from LB
#$nic.Ipconfigurations[0].LoadBalancerBackendAddressPools=$null
#Adds VM to LB
Write-Host "Adding $($VMName) to Loadbalancer " + $lbname
$nic.IpConfigurations[0].LoadBalancerBackendAddressPools=$lb.BackendAddressPools[0]
Set-AzNetworkInterface -NetworkInterface $nic
Write-Host "VM $($VMName) added to the load balancer"
elapsedTime
}

Write-Host "Script completed" -BackgroundColor Blue
elapsedTime

Leave a Reply

Your email address will not be published. Required fields are marked *