Quickstart: Create an Azure Firewall and a firewall policy - Bicep
In this quickstart, you use Bicep to create an Azure Firewall and a firewall policy. The firewall policy has an application rule that allows connections to www.microsoft.com
and a rule that allows connections to Windows Update using the WindowsUpdate FQDN tag. A network rule allows UDP connections to a time server at 13.86.101.172.
Also, IP Groups are used in the rules to define the Source IP addresses.
Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources. It provides concise syntax, reliable type safety, and support for code reuse. Bicep offers the best authoring experience for your infrastructure-as-code solutions in Azure.
For information about Azure Firewall Manager, see What is Azure Firewall Manager?.
For information about Azure Firewall, see What is Azure Firewall?.
Prerequisites
- An Azure account with an active subscription. Create a trial subscription.
Review the Bicep file
This Bicep file creates a hub virtual network, along with the necessary resources to support the scenario.
The Bicep file used in this quickstart is from Azure Quickstart Templates.
@description('Virtual network name')
param virtualNetworkName string = 'vnet${uniqueString(resourceGroup().id)}'
@description('Azure Firewall name')
param firewallName string = 'fw${uniqueString(resourceGroup().id)}'
@description('Number of public IP addresses for the Azure Firewall')
@minValue(1)
@maxValue(100)
param numberOfPublicIPAddresses int = 2
@description('Zone numbers e.g. 1,2,3.')
param availabilityZones array = []
@description('Location for all resources.')
param location string = resourceGroup().location
param infraIpGroupName string = '${location}-infra-ipgroup-${uniqueString(resourceGroup().id)}'
param workloadIpGroupName string = '${location}-workload-ipgroup-${uniqueString(resourceGroup().id)}'
param firewallPolicyName string = '${firewallName}-firewallPolicy'
var vnetAddressPrefix = '10.10.0.0/24'
var azureFirewallSubnetPrefix = '10.10.0.0/25'
var publicIPNamePrefix = 'publicIP'
var azurepublicIpname = publicIPNamePrefix
var azureFirewallSubnetName = 'AzureFirewallSubnet'
var azureFirewallSubnetId = resourceId('Microsoft.Network/virtualNetworks/subnets', virtualNetworkName, azureFirewallSubnetName)
var azureFirewallPublicIpId = resourceId('Microsoft.Network/publicIPAddresses', publicIPNamePrefix)
var azureFirewallIpConfigurations = [for i in range(0, numberOfPublicIPAddresses): {
name: 'IpConf${i}'
properties: {
subnet: ((i == 0) ? json('{"id": "${azureFirewallSubnetId}"}') : json('null'))
publicIPAddress: {
id: '${azureFirewallPublicIpId}${i + 1}'
}
}
}]
resource workloadIpGroup 'Microsoft.Network/ipGroups@2022-01-01' = {
name: workloadIpGroupName
location: location
properties: {
ipAddresses: [
'10.20.0.0/24'
'10.30.0.0/24'
]
}
}
resource infraIpGroup 'Microsoft.Network/ipGroups@2022-01-01' = {
name: infraIpGroupName
location: location
properties: {
ipAddresses: [
'10.40.0.0/24'
'10.50.0.0/24'
]
}
}
resource vnet 'Microsoft.Network/virtualNetworks@2022-01-01' = {
name: virtualNetworkName
location: location
tags: {
displayName: virtualNetworkName
}
properties: {
addressSpace: {
addressPrefixes: [
vnetAddressPrefix
]
}
subnets: [
{
name: azureFirewallSubnetName
properties: {
addressPrefix: azureFirewallSubnetPrefix
}
}
]
enableDdosProtection: false
}
}
resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2022-01-01' = [for i in range(0, numberOfPublicIPAddresses): {
name: '${azurepublicIpname}${i + 1}'
location: location
sku: {
name: 'Standard'
}
properties: {
publicIPAllocationMethod: 'Static'
publicIPAddressVersion: 'IPv4'
}
}]
resource firewallPolicy 'Microsoft.Network/firewallPolicies@2022-01-01'= {
name: firewallPolicyName
location: location
properties: {
threatIntelMode: 'Alert'
}
}
resource networkRuleCollectionGroup 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2022-01-01' = {
parent: firewallPolicy
name: 'DefaultNetworkRuleCollectionGroup'
properties: {
priority: 200
ruleCollections: [
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
action: {
type: 'Allow'
}
name: 'azure-global-services-nrc'
priority: 1250
rules: [
{
ruleType: 'NetworkRule'
name: 'time-windows'
ipProtocols: [
'UDP'
]
destinationAddresses: [
'13.86.101.172'
]
sourceIpGroups: [
workloadIpGroup.id
infraIpGroup.id
]
destinationPorts: [
'123'
]
}
]
}
]
}
}
resource applicationRuleCollectionGroup 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2022-01-01' = {
parent: firewallPolicy
name: 'DefaultApplicationRuleCollectionGroup'
dependsOn: [
networkRuleCollectionGroup
]
properties: {
priority: 300
ruleCollections: [
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
name: 'global-rule-url-arc'
priority: 1000
action: {
type: 'Allow'
}
rules: [
{
ruleType: 'ApplicationRule'
name: 'winupdate-rule-01'
protocols: [
{
protocolType: 'Https'
port: 443
}
{
protocolType: 'Http'
port: 80
}
]
fqdnTags: [
'WindowsUpdate'
]
terminateTLS: false
sourceIpGroups: [
workloadIpGroup.id
infraIpGroup.id
]
}
]
}
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
action: {
type: 'Allow'
}
name: 'Global-rules-arc'
priority: 1202
rules: [
{
ruleType: 'ApplicationRule'
name: 'global-rule-01'
protocols: [
{
protocolType: 'Https'
port: 443
}
]
targetFqdns: [
'www.microsoft.com'
]
terminateTLS: false
sourceIpGroups: [
workloadIpGroup.id
infraIpGroup.id
]
}
]
}
]
}
}
resource firewall 'Microsoft.Network/azureFirewalls@2021-03-01' = {
name: firewallName
location: location
zones: ((length(availabilityZones) == 0) ? null : availabilityZones)
dependsOn: [
vnet
publicIpAddress
workloadIpGroup
infraIpGroup
networkRuleCollectionGroup
applicationRuleCollectionGroup
]
properties: {
ipConfigurations: azureFirewallIpConfigurations
firewallPolicy: {
id: firewallPolicy.id
}
}
}
Multiple Azure resources are defined in the Bicep file:
- Microsoft.Network/ipGroups
- Microsoft.Network/firewallPolicies
- Microsoft.Network/firewallPolicies/ruleCollectionGroups
- Microsoft.Network/azureFirewalls
- Microsoft.Network/virtualNetworks
- Microsoft.Network/publicIPAddresses
Deploy the Bicep file
Save the Bicep file as
main.bicep
to your local computer.Deploy the Bicep file using either Azure CLI or Azure PowerShell.
az group create --name exampleRG --location chinaeast az deployment group create --resource-group exampleRG --template-file main.bicep --parameters firewallName=<firewall-name>
Note
Replace <firewall-name> with the name of the Azure Firewall.
When the deployment finishes, you should see a message indicating the deployment succeeded.
Review deployed resources
Use Azure CLI or Azure PowerShell to review the deployed resources.
az resource list --resource-group exampleRG
Clean up resources
When you no longer need the resources that you created with the firewall, delete the resource group. The firewall and all the related resources are deleted.
az group delete --name exampleRG