Step-by-Step Guide to Automate Azure Firewall Backup

Azure Firewall is a managed, cloud-based network security service that protects your Azure Virtual Network resources. The service is fully integrated with Azure Monitor for logging and analytics.

Must read 👉 How to Backup and Restore Azure Firewall using Azure PowerShell Commands?

Automate Backing up Firewall in Azure

Automate Azure firewall backup to storage account using Azure Automation account runbook on scheduled time.

Pre-requisites to Automate Azure Firewall Backup:

  • Azure Firewall resource
  • Azure Storage account
  • Azure Automation account
  • Contributor access on deployment resources

Create an Azure Storage Account:

Create a storage account from Azure Portal to store azure firewall back-up created in storage blob containers.  Go to azure global search bar and type in Storage account >> Create a Storage account with cool access tier.

Import the required Modules in Azure Automation Account:

Step 1: Access Automation account

Step 2: From left pane select Shared Resources >> Modules

Step 3: Search for the following modules
  • Az.Accounts
  • Az.Network
  • Az.Resources

Create an Azure Runbook in Azure Automation Account:

Step 1: Access Automation account

Step 2: From left pane select Process Automation >> Runbooks

Step 3: From Runbook section, Click on Create a runbook

Step 4: Fill up the runbook details and click on create button.

Step 5: After creating a runbook >> open the runbook which you have created >>  Click on edit runbook

Step 6: copy the below Azure PowerShell script in the runbook as it is without changes.

Azure PowerShell Automation Runbook Script:

<#
****************************************************************************************************************************
This Azure Automation runbook automates Azure Firewall backups. It takes snap shots at different instances or schedule and 
saves it to a Blob storage container. It also deletes old backups from blob storage.
 ***************************************************************************************************************************

.DESCRIPTION
	You should use this Runbook if you want to manage Azure Firewall backups in Blob storage or just want to export the current configuration. It
    works as a power runbook.
#>

param(
	[parameter(Mandatory=$true)]
	[String] $FirewallSubscriptionName,
    [parameter(Mandatory=$true)]
	[String] $ResourceGroupName,
    [parameter(Mandatory=$true)]
	[String] $AzureFirewallName,
    [parameter(Mandatory=$true)]
    [String]$StorageAccountName,
    [parameter(Mandatory=$true)]
    [String]$StorageKey,
	[parameter(Mandatory=$true)]
    [string]$BlobContainerName,
	[parameter(Mandatory=$true)]
    [Int32]$RetentionDays
)

$ErrorActionPreference = 'stop'

function Login() {
	$connectionName = "AzureRunAsConnection"
	try
	{
		$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName         

		Write-Verbose "Logging in to Azure..." -Verbose

		Add-AzAccount `
			-ServicePrincipal `
			-TenantId $servicePrincipalConnection.TenantId `
			-ApplicationId $servicePrincipalConnection.ApplicationId `
			-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint

	}
	catch {
		if (!$servicePrincipalConnection)
		{
			$ErrorMessage = "Connection $connectionName not established."
			throw $ErrorMessage
		} else{
			Write-Error -Message $_.Exception
			throw $_.Exception
		}
	}
}

function Create-newContainer([string]$blobContainerName, $storageContext) {
	Write-Verbose "Creating '$blobContainerName' blob container space for storage..." -Verbose
	if (Get-AzureStorageContainer -ErrorAction "Stop" -Context $storageContext | Where-Object { $_.Name -eq $blobContainerName }) {
		Write-Verbose "Container '$blobContainerName' already exists" -Verbose
	} else {
		New-AzureStorageContainer -ErrorAction "Stop" -Name $blobContainerName -Permission Off -Context $storageContext
		Write-Verbose "Container '$blobContainerName' created" -Verbose
	}
}

function Export-To-Storageaccount([string]$resourceGroupName, [string]$AzureFirewallName, [string]$storageKey, [string]$blobContainerName,$storageContext) {
	Write-Verbose "Starting Azure Firewall current configuration export in json..." -Verbose
    try
    {
        $BackupFilename = $AzureFirewallName + (Get-Date).ToString("yyyyMMddHHmm") + ".json"
        $BackupFilePath = ($env:TEMP + "\" + $BackupFilename)
        $AzureFirewallId = (Get-AzFirewall -Name $AzureFirewallName -ResourceGroupName $resourceGroupName).id 
        <# $FirewallPolicyID = (Get-AzFirewallPolicy -Name $AzureFirewallPolicy -ResourceGroupName $resourceGroupName).id #>
        Export-AzResourceGroup -ResourceGroupName $resourceGroupName -SkipAllParameterization -Resource $AzureFirewallId -Path $BackupFilePath
		#Export value and store with name created
        Write-Output "Submitting request to dump Azure Firewall configuration"
        $blobname = $BackupFilename
        $output = Set-AzureStorageBlobContent -File $BackupFilePath -Blob $blobname -Container $blobContainerName -Context $storageContext -Force -ErrorAction stop


    }
	#send out message if backup fails
    catch {
		   $ErrorMessage = "BackUp not created. Please check the input values."
           throw $ErrorMessage
    }
}

function Remove-Older-Backups([int]$retentionDays, [string]$blobContainerName, $storageContext) {
	Write-Output "Removing backups older than '$retentionDays' days from blob: '$blobContainerName'"
	$isOldDate = [DateTime]::UtcNow.AddDays(-$retentionDays)
	$blobs = Get-AzureStorageBlob -Container $blobContainerName -Context $storageContext
	foreach ($blob in ($blobs | Where-Object { $_.LastModified.UtcDateTime -lt $isOldDate -and $_.BlobType -eq "BlockBlob" })) {
		Write-Verbose ("Removing blob: " + $blob.Name) -Verbose
		Remove-AzureStorageBlob -Blob $blob.Name -Container $blobContainerName -Context $storageContext
	}
}

Write-Verbose "Starting database backup..." -Verbose

$StorageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageKey

#Login to azure
Login
Import-Module Az.Network
Import-Module Az.Resources

Set-AzContext -SubscriptionName "$FirewallSubscriptionName"
Create-newContainer `
	-blobContainerName $blobContainerName `
	-storageContext $storageContext
	
Export-To-Storageaccount `
	-resourceGroupName $ResourceGroupName `
	-AzureFirewallName $AzureFirewallName `
	-storageKey $StorageKey `
	-blobContainerName $BlobContainerName `
	-storageContext $storageContext
	
Remove-Older-Backups `
	-retentionDays $RetentionDays `
	-storageContext $StorageContext `
	-blobContainerName $BlobContainerName
	
Write-Verbose "Azure Firewall current configuration back up completed." -Verbose

Azure Firewall Backup Script Explanation:

Script consists of four functions namely Login(), Create-newContainer(), Export-To-Storageaccount(), Remove-Older-Backups()

  • Login() -Automation account Login
  • Create-newContainer() -Use/Create Storage Container
  • Export-To-Storageaccount() -Export the Firewall configuration, and save to storage container as blob.
  • Remove-Older-Backups() -Purge the older backups based on retention.

Validate Azure Firewall Backup Jobs:

Step 1: Click on Test Pane from your azure runbook

Step 2: Enter or fill up the Azure Firewall Backup configuration details.

Step 3: after filling up the required configuration details >> click on Start to test the backup runs.

Step 4: If backup job is successful then save your runbook and click on Publish.

Schedule Azure Firewall Backup Runbook

After successful testing, create or link a schedule to trigger backup on time.

Microsoft Docs: 👉 Runbook to manage Azure Firewall Back ups

Find Azure Firewall Zones using PowerShell:

Set-AzContext -SubscriptionName "" | Out-Null

Get-AzFirewall -ResourceGroupName "" -Name "" | Select-Object -Property *

Get-AzFirewall -Name "" | Select-Object -Property Zones

Find Azure Firewall Zones using AZ CLI:

az network firewall show --resource-group "prd-qia-connectivity-weu-rg" --name "prd-qia-connectivity-weu-fw"