13/06/2025

Azure Firewall Rules as Code | PowerShell, DevOps and Bicep!

Managing and configuring Azure Firewall rules manually in the portal is not sustainable, repeatable, scalable nor easy to track changes and add approvals for. The ability to deploy Azure Firewall rules and push out these changes via DevOps Pipelines, Bicep and PowerShell makes maintaining and updating Firewall rules a breeze using CSV files to manage your rules! The benefit is that your rules are now captured in source control so it’s easy to revert rules back and you can add relevant environment approval stages to ensure any changes go through the correct processes.

The code can be found on my GitHub here which forks off the great initial work completed by Will Moselhy in his GitHub repository. His PowerShell script for importing and exporting the rules is great so I will provide additional value by demonstrating some new features and updates I have implemented. Please note the script only works for Network and Application Rules:

  • Updated the Azure Bicep to use Azure Verified Modules (AVM)
  • Updated the Azure Bicep to allow for both Basic and Standard SKU Firewall Policies
  • Added an example CSV to demonstrate how the CSV can be maintained as the source of truth of your Firewall Rules with DR capability
  • Within a landing zone, demonstrating how IP Groups can be paired with the code to easily setup inter-VNET traffic
  • Adding in the Azure DevOps YAML Pipeline code

Step 1: Pre-requisites

This blog assumes an Azure Firewall and related Firewall Policy have already been deployed. Before we get started – there are a few elements to get in place/edit:

Existing Firewall

  • If you already have existing rules in your Azure Firewall Policy – I recommend running the export script to build out your rules in the CSV for you. This can be done as follows
.\Export-AzureFirewallPolicyRulesToCsv.ps1 -FirewallPolicyId ${YOURPRIMARYAZUREFIREWALLPOLICYRESOURCEID}
//If you have a DR Firewall, run the following as well
.\Export-AzureFirewallPolicyRulesToCsv.ps1 -FirewallPolicyId ${YOURSECONDARYAZUREFIREWALLPOLICYRESOURCEID} -OutputCSVPath '..\csv\FirewallRulesDR.csv'

Workload Identity Federation Setup

  • Create a Service Connection wif-ado-prod between Azure DevOps and Azure:
    • This can be done from your Azure DevOps Project Settings -> Service Connections -> Azure Resource Manager.
    • Create a Workload Identity Federation to your Subscription which will be used for the Pipeline to deploy the Bicep IaC and PowerShell deployments

Azure DevOps Library Setup

  • Create an Azure DevOps Library called alz and populate with the following values:
    • azureFirewallPrimaryPolicyName: The name of your main Azure Firewall’s Policy
    • primaryHubRGName: The name of the Resource Group containing the Firewall Policy
    • connectivitySubID: The subscription containing the Firewall Policy
    • azureFirewallSecondaryPolicyName: The name of your secondary Azure Firewall’s Policy (If you do not have one, leave the value blank and the pipeline will skip deploying to DR)
    • secondaryHubRGName: The name of the Resource Group containing the Firewall Policy (If you do not have one, leave the value blank and the pipeline will skip deploying to DR)

Firewall Policy Bicep Changes for Basic SKU

  • Due to differences in the functionality between Basic and Standard Firewall Policies, the bicep requires some changes if you are using the Basic SKU.
  • Within the FirewallPolicy.bicep if you are using the Basic SKU, uncomment the commented out section and comment out the Standard SKU section. I will work on a more elegant solution for this.

Step 2: Implement Firewall Rules into the CSVs

  • I’ve uploaded examples of how to define Network Rules and Application Rules in the CSVs in my GitHub. It is relatively straight-forward on how to definerules, but it may take a bit of practice. A good way if you are unsure is to do a few rules in the portal in Azure and run the export script until you are comfortable in writing the rules in the CSV.
  • Define all the rules you want in the FirewallRules.csv and FirewallRulesDR.csv (if you have a DR Firewall). Push the commit to your DevOps repository.
  • I recommend a CSV extension in VSCode which makes editing the rules even easier! The one I use is linked here

Step 3: Create Azure DevOps Pipelines

Create an Azure DevOps Pipeline based off the main.yaml file. In firewallRulesDeploy.yaml the deployment environment is set as Firewall Rules Test – feel free to change and update to a more appropriate environment name for your uses. Remember to set up any approvals and checks to the environment if this is to be used in production!

Step 4: Run the DevOps Pipeline to import the rules

With the pipeline setup, you can now run the pipeline – if everything has been setup correctly both the Primary and Secondary Rules should deploy to the respective Azure Firewall Policy:

As mentioned if you don’t have a DR Azure Firewall and leave azureFirewallSecondaryPolicyName in the DevOps Library clear, the pipeline will skip that deployment.

Results

We can now validate if the rules have successfully deployed:

Primary Azure Firewall Rules

Secondary Azure Firewall Rules

Success, the rules we’ve defined in the two CSV’s have been deployed to each of the Firewall Policies. We can now continue to manage all our rules via the CSV’s and push them our via the Pipeline!

Summary

By implementing this process into your existing Landing Zone deployments or into your Azure Firewall maintenance processes, it can help streamline and add additional governance to firewall changes.

This script has allowed our practice to define a baseline set of Firewall rules following best practice and combined with IP Groups for Inter-VNET traffic means that we can spin up Azure networking super swiftly for customers and in a easy repeatable manner, saving us time and ensuring good standards for our Azure enviroments!

Next Steps

This by itself is a great addition for managing and updating Azure Firewall rules. There are a few additional steps that could be expanded and implemented in future:

  • Implement a Logic App/Automation account that will periodically run the Export Rules script and push the CSV’s into source control. The advantage of this is that then even if changes are done via the portal, this would still keep the CSV’s up to date. At the moment, the Export script would have to be run manually and pushed to source control before updates.
  • Implement functionality for DNAT rules
  • Implement a method to not require the FirewallPolicy.bicep to need to be manually updated if not using Standard SKU