Friday, June 30, 2023

Azure Firewall with availability zones and forced tunneling - ARM template

 This firewall has a fairly specific configuration that aligns to a set of client requirements. First of all it's set up for forced tunneling. There is not a requirement to configure a default route to point towards on-prem as the default route can be advertised via BGP (in a case where you have ExpressRoute or VPN to on-prem configured as well). For this to work, 'propagate gateway routes' must be enabled on the AzureFirewallSubnet, see here for more info. 

This setup requires a secondary subnet, AzureFirewallGatewaySubnet to be deployed (with a /26 size) and this subnet must have a default route pointing to the Internet.

In a default setup the firewall will have two public IP addresses but for security purposes one of those two IP addresses has been removed. The remaining public IP on the management interface is a technical requirement for internal communications with Microsoft and it can't be removed.

The ARM template, referenced below, deploys two resources. The firewall itself and one public IP. Both resources are deployed into three availability zones (AZ) (note that only certain Azure Regions support three AZs). 

If you want an official firewall w. AZs bicep file from MS, see this link.

ARM template on Github:

Friday, June 16, 2023

Installing VS Code, PowerShell, Azure PowerShell, and AZ CLI on macOS

 It's relatively simple to get these tools installed on a Mac so you can start working with Azure and ARM templates via code.

This article just collects the relevant information and puts it in order:

Visual Studio Code

This can be installed as a regular app in macOS, follow the link: 


Homebrew is a package manager for macOS and Microsoft's recommended way af installing PowerShell and other tools.

The commands to run for Homebrew are:

/bin/bash -c "$(curl -fsSL"

When Homebrew has been installed, it will ask you to run two additional commands (to add Homebrew to you PATH), these are:

(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/<REPLACE WITH USER>/.zprofile

eval "$(/opt/homebrew/bin/brew shellenv)"


To install PowerShell follow the same link as above:

Or run the following commands:

brew install --cask powershell

And to run PowerShell from the terminal:


Azure PowerShell

To install Azure PowerShell, follow this link:

Or run this command:

Install-Module -Name Az -Repository PSGallery -Force

This will give you the Azure related commands such as:

Connect-AzAccount, Get-AzContext, Set-AzContext, etc 


To install, follow this link:

Or run:

brew update && brew install azure-cli

This gives you all the AZ commands. A separate Az login is required to use the Az commands in Azure.


To install, see link or run below two commands:

brew tap hashicorp/tap

brew install hashicorp/tap/terraform

Thursday, June 15, 2023

Azure: ARM template for simple Win2k22 server for testing purposes

I have previously posted and article with a Win2k19 simple server using a key vault, see here. This current post will describe a simple Win2k22 server using a regular username and password set in the paremeters file of the ARM template.

The VM is deployed with tcp port 3389 opened locally on the VM, but no public IP is added. If you need to RDP to the VM from the internet, a public IP should be added and associated with the vNIC post deployment. 

The ARM template files can be found here:

Remember to update the parameters file with relevant information.

See here (the README file) for deployment information via PowerShell.

This VM has automatic shutdown configured at 19.00 hrs. UTC, daily.

Monday, June 12, 2023

Azure: Deploy a key vault with a private endpoint

 This post describes an ARM template that deploys a key vault, with a private endpoint, into an existing VNet and subnet. The key vault does not have to be placed in the same resource group as the VNet.

It requires the following to already be deployed:

  • VNet
  • Subnet
  • Resource group (for the key vault and private endpoint)
  • Private DNS zone (

The key vault will be configured to use RBAC and will allow ARM templates to retrieve content (in this case it is to allow an ARM template that deploys a VM to retrieve a secret from the key vault), see below:

For the Network settings, all public access is disabled. With a private endpoint you'll be able to create and read secrets from the key vault in the Azure Portal via internal routing. 

The "Allow trusted Microsoft services to bypass the firewall" setting is checked. This allows Azure DevOps, via a pipeline, to deploy an ARM template that deploys a VM that retrieves the secret from the KV which typically is the local admin password for the VM, see below:

The private endpoint (PE) can be found under, Networking -> Private endpoint connections.

A local IP from the specified subnet will be dynamically assigned to the PE.

Note that this template will not create the A record in the private DNS zone for the private endpoint. This is usually automated via Azure Policy, see here for more info under point 3.

The ARM template and parameters file can be found on Github. There's also a README with a bit more info. For more info on the format of the subnet ID string, see here.

Wednesday, June 7, 2023

Azure Policy - Allow only specified IP ranges and regions for VNets

 At current client we had a request to apply a policy to enforce that only VNets using specified IP address ranges and regions will be allowed. So for example, if you create a VNet in West Europe, then it must be within the IP address space and if in North Europe it must be within and And anything outside that must be denied.

There is no built-in policy for this. It was possible to find simpler versions online of the above but we couldn't find anything that fit all the requirements.

The closest we got was a slimmed down version of this policy from AzPolicyAdvertizer named "Address space must be pre-allocated for region".

However, it didn't take into account extended VNets. So if you have a VNet consisting of two or more IP address ranges, it will show as non-compliant.

We raised a ticket with Microsoft support and after a few days they came back with an updated policy that works.

The functioning policy can be found here on Github. The only thing that needs to be updated is the content of the "spokeAllocations" array.