Azure IaaS Lab – Hub Base Build

This post is part of a series, for the series contents see:

For the code listed in this post please see:

Breaking down the high-level diagram and eating the elephant in small bites I’ll build up the hub first of all:


The red crosses indicate pieces of the build that will be picked up later:

  • Logs Storage Account – I’ll implement this when setting up diagnostics.
  • Backups Storage Account – Surprisingly, this will be sorted out when I setup backups.
  • UDR – I’ll setup user defined routing once I have implemented vnet peering and a firewall.
  • NSG – I’ll probably tackle network security groups last to mop up any security holes that remain.

On top of the omissions above I’ve already found my first mistake in the high-level design.  My point-to-site VPN client address pool stupidly overlaps with the hub vnet range, when it needs to be separate, so I’ve changed that to be

First up I’ll build up the resource group and the network:

#Login to Azure and resource manager

#Just in case you have multiple subscriptions check which one you're working in

#If you need to select your test subscription use:
#Set-AzureSubscription -SubscriptionName <name>

#Build up the hub
#First the resource group
$RGName = "hub-rg"
$Location = "North Europe"
New-AzureRmResourceGroup -Name $RGName -Location $Location

#Now the hub network
New-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name hub-vnet `
-AddressPrefix -Location $Location

$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name hub-vnet

Add-AzureRmVirtualNetworkSubnetConfig -Name mgmt-subnet `
-VirtualNetwork $vnet -AddressPrefix

#Annoyling the gateway subnet has to be called GatewaySubnet, ruining my naming convention!
Add-AzureRmVirtualNetworkSubnetConfig -Name GatewaySubnet `
-VirtualNetwork $vnet -AddressPrefix

Set-AzureRmVirtualNetwork -VirtualNetwork $vnet

Next I’ll setup a point-to-site VPN which,  as I’m not exposing any of the VMs with a public IP, will be how I manage everything from my machine.

Because I’m cheap the VPN will be setup using self-signed certs which I’ll create following these useful steps from Microsoft.

#Create Point-to-Site VPN

#Set basic variables for our VPN gateway
$GWName = "hub-gw"
$GWIPName = "hub-gw-pip"
$GWIPconfName = "hub-gw-conf"
$VPNClientAddressPool = ""

#Get the VPN gateway subnet details. First you need to get the recently set vnet details again
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name hub-vnet
$GWsubnet = Get-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet

#Public IP for the VPN gateway
$GWPIP = New-AzureRmPublicIpAddress -Name $GWIPName -ResourceGroupName $RGName -Location $Location -AllocationMethod Dynamic

#Create the VPN gateway config
$GWIPConfig = New-AzureRmVirtualNetworkGatewayIpConfig -Name $GWIPconfName -SubnetId $GWsubnet.Id -PublicIpAddressId $GWPIP.Id

#Finally create the VPN Gateway
#This takes ages to run!
$GW = New-AzureRmVirtualNetworkGateway -Location $Location -Name $GWName -ResourceGroupName $RGName `
-GatewayType Vpn -IpConfigurations $GWIPConfig -VpnType RouteBased `
-EnableBgp $false -GatewaySku Standard

#Now set extra VPN gateway settings
Set-AzureRmVirtualNetworkGatewayVpnClientConfig -VirtualNetworkGateway $GW -VpnClientAddressPool $VPNClientAddressPool

#Create the self-signed root and client cert using the guide below:

#Get the cert imported into Azure (substitute your own path/name)
$P2SRootCertName = "AzureLabP2SRootCert.cer"
$FilePathForCert = "C:\SSL\AzureLabP2SRootCert.cer"
$Cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2($FilePathForCert)
$CertBase64 = [system.convert]::ToBase64String($Cert.RawData)
$P2SRootCert = Add-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName $P2SRootCertName -PublicCertData $CertBase64 -VirtualNetworkGatewayName $GW.Name -ResourceGroupName $RGName

#Finally get URL for VPN client
$PackageUrl = Get-AzureRmVpnClientPackage -ResourceGroupName $RGName -VirtualNetworkGatewayName $GW.Name -ProcessorArchitecture Amd64

#Display the URL path and download the .exe from here

Finally, I want to build up my management VM which will be a Windows Server 2016 box, for no better reason than it’s new and I want to play around with it 🙂

Since I’ll be building up a few VMs for this lab it’s a good opportunity to use Azure Key Vault to store a default password for provisioning.

#Create an Azure Key Vault
New-AzureRmKeyVault -VaultName lab-vault -ResourceGroupName $RGName -Location $Location

#Add a secret (password) to that vault
#The secret (password) has to be in a secure string format so you'll need to covert it first

#Convert to secure string
$Password = ConvertTo-SecureString -String '<your_password>' -AsPlainText -Force

#Add the password as a secret
Set-AzureKeyVaultSecret -VaultName 'lab-vault' -Name 'ProvisionPassword' -SecretValue $Password

It’s all very well that I’ve setup my Azure Key Vault and stored a password there for VM provisioning, but how do I access it?

Digging around the various blog posts and Microsoft docs on using Key Vault I found that nearly everything was geared towards two use cases:

  1. ARM Templates
  2. App passwords for Azure Applications

Neither of those was any use to me so I should probably take the hint that those are the correct use cases, but I indulged myself and got the value out of the vault and into a PSCredential object with:

#First setup default credentials to use in provisioning by retrieving and decrypting our Key Vault password

$Username = "adminuser"
$SecurePwd = Get-AzureKeyVaultSecret -VaultName 'lab-vault' -Name 'ProvisionPassword'
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $SecurePwd.SecretValue

It was as simple as getting the secret and then accessing the .SecretValue parameter which, conveniently,  is in the secure string format that a PSCredential password needs.  Admittedly, I did stumble at first by getting the .SecretValueText parameter instead!

That means we have everything needed to build up my management VM:

#Create a hub storage account which we'll use for VM storage
New-AzureRmStorageAccount -ResourceGroupName $RGName -AccountName "hubvmstr" -Location $Location -Type "Standard_LRS"

#Define Management VM basics
$VMName = "mgmt-vm"
$VMSize = "Standard_A1"
$OSDiskName = $VMName + "OSDisk"
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName $RGName -Name hubvmstr
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name hub-vnet

#Define Management VM network details
#This will statically assign an IP to the VM. is the next IP available as .0-3 are reserved by Azure
$NIC1 = New-AzureRmNetworkInterface -Name "mgmt-vm-eth0" -ResourceGroupName $RGName -Location $Location -SubnetId $vnet.Subnets[0].Id -PrivateIpAddress
Set-AzureRmNetworkInterface -NetworkInterface $NIC1

#Define the Management VM config
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -ComputerName $VMName -Windows -Credential $Credential
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "Windows-Server-Technical-Preview" -Version "latest"
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id
$OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd"
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage

#Create the Management VM
New-AzureRmVM -ResourceGroupName $RGName -Location $Location -VM $VirtualMachine


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: