Implementing Azure Firewall in Hub-Spoke network topology in Azure
Hi Everyone!
This post is continuation of how to series about Hub-Spoke network topology in Azure. Over the time, I will update this page with links to individual posts :
Connect an on-premises network to a Microsoft Azure - Part 1
Connect an on-premises network to a Microsoft Azure - Part 2
Implementing Hub-Spoke network topology in Azure - Part 1
Implementing Hub-Spoke network topology in Azure - Part 2
Introducing Azure Firewall in Hub-Spoke network topology in Azure
This Post - Implementing Azure Firewall in Hub-Spoke network topology in Azure
Now we are able to connect between Hub and Spokes but there is no communication between Spokes. In this post we are going to see how Intra-Region Spokes VNET routing works.
We will start by creating Azure Firewall. Like gateway subnet, Azure firewall also need dedicated subnet for it. Since azure firewall is shared service, we will put it in hub-vnet. Let’s create a subnet called AzurefirwallSubnet in hub-vnet. Azure Firewall needs a /26 subnet size because it ensures that the firewall has enough IP addresses available to provision more virtual machine instances as it scales.
$LocationName = "centralindia"
$ResourceGroupName = "network-sandbox"
#Create AzureFirewallSubnet in Hub Vnet
$vnetName = "hub-vnet"
$azfirewallvnetAddressSpace = "10.10.10.0/26"
$hubVnet = Get-AzVirtualNetwork `
-Name $vnetName
$azureFirewallSubnet = Add-AzVirtualNetworkSubnetConfig `
-Name "AzureFirewallSubnet" `
-AddressPrefix $azfirewallvnetAddressSpace `
-VirtualNetwork $hubVnet
$updateHubVnet = Set-AzVirtualNetwork `
-VirtualNetwork $hubVnet# Get a Public IP for the firewall
$azFirewallName = "HubAzFirewall"
$firewallPip = New-AzPublicIpAddress `
-ResourceGroupName $ResourceGroupName `
-Location $LocationName `
-AllocationMethod Static `
-Sku Standard `
-Name "$($azFirewallName)-PublicIp"
# Create the firewall
$azFirewall = New-AzFirewall `
-Name $azFirewallName `
-ResourceGroupName $ResourceGroupName `
-Location $LocationName `
-VirtualNetworkName $updateHubVnet.Name`
-PublicIpName $firewallPip.Name#Create route table
$spoke1ToAzFwUdr = New-AzRouteTable `
-Name 'Spoke1ToAzFwUdr' `
-ResourceGroupName $ResourceGroupName `
-location $LocationName
$updatedSpoke1ToAzFwUdr = $spoke1ToAzFwUdr `
| Add-AzRouteConfig `
-Name "ToAzureFirewall" `
-AddressPrefix 0.0.0.0/0 `
-NextHopType "VirtualAppliance" `
-NextHopIpAddress $azFirewall.IpConfigurations.privateipaddress `
| Set-AzRouteTableWorkloadSubnet of spoke1-vnet needs to communicate with WorkloadSubnet of spoke2-vnet. So we will attach newly created UDR to both subnet.
$subNetinspokeVnet ="WorkloadSubnet"
$spoke1VnetName = "spoke1-vnet"
$spoke1Vnet = Get-AzVirtualNetwork `
-Name $spoke1VnetName
$WorkloadSubnetAddressSpaceForSpoke1 = "10.20.1.0/24"
$spoke1Vnet = Set-AzVirtualNetworkSubnetConfig `
-VirtualNetwork $spoke1Vnet `
-Name $subNetinspokeVnet `
-AddressPrefix $WorkloadSubnetAddressSpaceForSpoke1 `
-RouteTable $spokeToAzFwUdr | `
Set-AzVirtualNetwork
$spoke2VnetName = "spoke2-vnet"
$spoke2Vnet = Get-AzVirtualNetwork `
-Name $spoke2VnetName
$WorkloadSubnetAddressSpaceForSpoke2 = "10.30.1.0/24"
$spoke1Vnet = Set-AzVirtualNetworkSubnetConfig `
-VirtualNetwork $spoke2Vnet `
-Name $subNetinspokeVnet `
-AddressPrefix $WorkloadSubnetAddressSpaceForSpoke2 `
-RouteTable $spokeToAzFwUdr | `
Set-AzVirtualNetworkSpok1JumpBox and Spoke2JumpBox is Azure firewall, So we just need to allow the flow from WorkloadSubnet of spoke1-vnet to WorkloadSubnet of spoke2-vnet. To do that, we will create network rule in azure firewall.
$sourceAddress = "10.20.1.0/24"
$destinationAddress ="10.30.1.0/24"
$spoke1ToSpoke2 = New-AzFirewallNetworkRule `
-Name "Allow-Spoke2-Routing" `
-Protocol TCP `
-SourceAddress $sourceAddress `
-DestinationAddress $destinationAddress `
-DestinationPort *
$netRuleCollection = New-AzFirewallNetworkRuleCollection `
-Name "Spoke-to-Spoke" `
-Priority 1000 `
-Rule $spoke1ToSpoke2 `
-ActionType "Allow"
$azFirewall.NetworkRuleCollections.Add($netRuleCollection)
$updatedFirewall = Set-AzFirewall -AzureFirewall $azFirewall
Let’s go to https://www.microsoft.com/ from Spoke1JumpBox. Oops! unable to reach, what happen? As I mentioned earlier, by default all connections are denied from Azure firewall. So, create a application rule to allow google and lets see how it works.
$allowGoogle = New-AzFirewallApplicationRule `
-Name "Allow-Google" `
-SourceAddress $sourceAddress `
-Protocol http, https `
-TargetFqdn www.google.com
$appRuleCollection = New-AzFirewallApplicationRuleCollection `
-Name "Allow-Internet" `
-Priority 2000 `
-ActionType Allow `
-Rule $allowGoogle `
$azFirewall.ApplicationRuleCollections.Add($appRuleCollection)
$updatedFirewall = Set-AzFirewall -AzureFirewall $azFirewall
You can also control inbound internet traffic with Azure Firewall DNAT. Assume, your VPN is not working but you have to access HubJumpBox which only have private ip. So how to access it? One of the way to access it by creating a DNAT rule.
$rdpToHubJumpbox = New-AzFirewallNatRule `
-Name "RDP To HubJumpBox" `
-Protocol "TCP" `
-SourceAddress * `
-DestinationAddress $firewallPip.IpAddress `
-DestinationPort "4500" `
-TranslatedAddress "10.10.1.4" `
-TranslatedPort "3389"
$natRuleCollection = New-AzFirewallNatRuleCollection `
-Name "Allow-RDP-To-HubJumpBox" `
-Priority 500 `
-Rule $rdpToHubJumpbox
$azFirewall.NatRuleCollections.Add($natRuleCollection)
$updatedFirewall = Set-AzFirewall -AzureFirewall $azFirewall4500!
So basically, by introducing azure firewall you just enable more security in whole architecture.
Here is the final architecture, we just implemented -

Ending Note
This whole series is based on single subscription, intra-region vnet communication.This works for small companies but for enterprise, inter-region vnet integration, multiple subscriptions is very common and also Azure Expressroute will be in use for extending On-Premise network and it involves a lot of network appliances, firewall etc. So, basically it is complex but if you get the idea of whole architecture, you good to go!