Skip to main content

Azure Firewall Standard to Premium Migration - Part 1

· 4 min read
Hasan Gural

In this article series, I will write about how we can migrate Azure Firewall Standard to Premium sku using PowerShell or Azure Resource Manageer Template. If you are using Azure Cloud, You are probably using Azure Firewall Standard in your Hub and Spoke topogolty to protect ingress and egress traffic for your services.

This article guides you with the required steps to manually migrate your Standard firewall and policy to Premium.

Before you start the migration, understand the migration tasks and plan ahead for the required maintenance window. Typical down time of 20-30 minutes is expected.

The following general steps are required for a successful migration:

  1. Create new Premium policy based on your existing Standard policy or classic rules. By the end of this step your new premium policy will include all your existing rules and policy settings.
    • Migrate Classic rules to Standard policy
    • Migrate an existing policy using Azure PowerShell
  2. Migrate Azure Firewall from Standard to Premium using stop/start
  3. Attach the newly created Premium policy to your Premium Firewall

🚀Migrate an existing policy using Azure PowerShell

Transform-Policy.ps1 is an Azure PowerShell script that creates a new Premium policy from an existing Standard policy.

Given a standard firewall policy ID, the script transforms it to a Premium Azure firewall policy. The script first connects to your Azure account, pulls the policy, transforms/adds various parameters, and then uploads a new Premium policy. The new premium policy is named <previous_policy_name>_premium. If it's a child policy transformation, a link to the parent policy will remain.

Usage example:

Transform-Policy -PolicyId /subscriptions/XXXXX-XXXXXX-XXXXX/resourceGroups/some-resource-group/providers/Microsoft.Network/firewallPolicies/policy-name

caution

The script doesn't migrate Threat Intelligence and SNAT private ranges settings. You'll need to note those settings before proceeding and migrate them manually. Otherwise, you might encounter inconsistent traffic filtering with your new upgraded firewall.

This script requires the latest Azure PowerShell. Run Get-Module -ListAvailable Az to see which versions are installed.

<#
.SYNOPSIS
Given an Azure firewall policy id the script will transform it to a Premium Azure firewall policy.
The script will first pull the policy, transform/add various parameters and then upload a new premium policy.
The created policy will be named <previous_policy_name>_premium if no new name provided else new policy will be named as the parameter passed.
.Example
Transform-Policy -PolicyId /subscriptions/XXXXX-XXXXXX-XXXXX/resourceGroups/some-resource-group/providers/Microsoft.Network/firewallPolicies/policy-name -NewPolicyName <optional param for the new policy name>
#>

param (
#Resource id of the azure firewall policy.
[Parameter(Mandatory=$true)]
[string]
$PolicyId,

#new filewallpolicy name, if not specified will be the previous name with the '_premium' suffix
[Parameter(Mandatory=$false)]
[string]
$NewPolicyName = ""
)
$ErrorActionPreference = "Stop"
$script:PolicyId = $PolicyId
$script:PolicyName = $NewPolicyName

function ValidatePolicy {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[Object]
$Policy
)

Write-Host "Validating resource is as expected"

if ($null -eq $Policy) {
Write-Error "Recived null policy"
exit(1)
}
if ($Policy.GetType().Name -ne "PSAzureFirewallPolicy") {
Write-Host "Resource must be of type Microsoft.Network/firewallPolicies" -ForegroundColor Red
exit(1)
}

if ($Policy.Sku.Tier -eq "Premium") {
Write-Host "Policy is already premium"
exit(1)
}
}

function GetPolicyNewName {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[Microsoft.Azure.Commands.Network.Models.PSAzureFirewallPolicy]
$Policy
)

if (-not [string]::IsNullOrEmpty($script:PolicyName)) {
return $script:PolicyName
}

return $Policy.Name + "_premium"
}

function TransformPolicyToPremium {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[Microsoft.Azure.Commands.Network.Models.PSAzureFirewallPolicy]
$Policy
)
$NewPolicyParameters = @{
Name = (GetPolicyNewName -Policy $Policy)
ResourceGroupName = $Policy.ResourceGroupName
Location = $Policy.Location
ThreatIntelMode = $Policy.ThreatIntelMode
BasePolicy = $Policy.BasePolicy.Id
DnsSetting = $Policy.DnsSettings
Tag = $Policy.Tag
SkuTier = "Premium"
}

Write-Host "Creating new policy"
$premiumPolicy = New-AzFirewallPolicy @NewPolicyParameters

Write-Host "Populating rules in new policy"
foreach ($ruleCollectionGroup in $Policy.RuleCollectionGroups) {
$ruleResource = Get-AzResource -ResourceId $ruleCollectionGroup.Id
$ruleToTransfom = Get-AzFirewallPolicyRuleCollectionGroup -AzureFirewallPolicy $Policy -Name $ruleResource.Name
$ruleCollectionGroup = @{
FirewallPolicyObject = $premiumPolicy
Priority = $ruleToTransfom.Properties.Priority
Name = $ruleToTransfom.Name
}

if ($ruleToTransfom.Properties.RuleCollection.Count) {
$ruleCollectionGroup["RuleCollection"] = $ruleToTransfom.Properties.RuleCollection
}

Set-AzFirewallPolicyRuleCollectionGroup @ruleCollectionGroup
}
}

function ValidateAzNetworkModuleExists {
Write-Host "Validating needed module exists"
$networkModule = Get-InstalledModule -Name "Az.Network" -MinimumVersion 4.5 -ErrorAction SilentlyContinue
if ($null -eq $networkModule) {
Write-Host "Please install Az.Network module version 4.5.0 or higher, see instructions: https://github.com/Azure/azure-powershell#installation"
exit(1)
}
$resourceModule = Get-InstalledModule -Name "Az.Resources" -MinimumVersion 4.2 -ErrorAction SilentlyContinue
if ($null -eq $resourceModule) {
Write-Host "Please install Az.Resources module version 4.2.0 or higher, see instructions: https://github.com/Azure/azure-powershell#installation"
exit(1)
}
Import-Module Az.Network -MinimumVersion 4.5.0
Import-Module Az.Resources -MinimumVersion 4.2.0
}

ValidateAzNetworkModuleExists
$policy = Get-AzFirewallPolicy -ResourceId $script:PolicyId
ValidatePolicy -Policy $policy
TransformPolicyToPremium -Policy $policy