Quickstart: Deploy Azure Firewall with Availability Zones - ARM template

In this quickstart, you use an Azure Resource Manager template (ARM template) to deploy an Azure Firewall in three Availability Zones.

An ARM template is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for your project. The template uses declarative syntax, which lets you state what you intend to deploy without having to write the sequence of programming commands to create it.

The template creates a test network environment with a firewall. The network has one virtual network (VNet) with three subnets: AzureFirewallSubnet, ServersSubnet, and JumpboxSubnet. The ServersSubnet and JumpboxSubnet subnet each have a single, two-core Windows Server virtual machine.

The firewall is in the AzureFirewallSubnet subnet, and has an application rule collection with a single rule that allows access to www.microsoft.com.

A user-defined route points network traffic from the ServersSubnet subnet through the firewall, where the firewall rules are applied.

For more information about Azure Firewall, see Deploy and configure Azure Firewall using the Azure portal.

If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to Azure button. The template will open in the Azure portal.

Deploy to Azure

Prerequisites

Review the template

This template creates an Azure Firewall with Availability Zones, along with the necessary resources to support the Azure Firewall.

The template used in this quickstart is from Azure Quickstart Templates.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "virtualNetworkName": {
      "type": "string",
      "defaultValue": "test-vnet",
      "metadata": {
        "description": "virtual network name"
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the Virtual Machine."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "availabilityZones": {
      "type": "array",
      "defaultValue": [
        "1",
        "2",
        "3"
      ],
      "metadata": {
        "description": "Zone numbers e.g. 1,2,3."
      }
    },
    "numberOfFirewallPublicIPAddresses": {
      "type": "int",
      "defaultValue": 1,
      "minValue": 1,
      "maxValue": 100,
      "metadata": {
        "description": "Number of public IP addresses for the Azure Firewall"
      }
    }
  },
  "variables": {
    "vnetAddressPrefix": "10.0.0.0/16",
    "serversSubnetPrefix": "10.0.2.0/24",
    "azureFirewallSubnetPrefix": "10.0.1.0/24",
    "jumpboxSubnetPrefix": "10.0.0.0/24",
    "nextHopIP": "10.0.1.4",
    "azureFirewallSubnetName": "AzureFirewallSubnet",
    "jumpBoxSubnetName": "JumpboxSubnet",
    "serversSubnetName": "ServersSubnet",
    "jumpBoxPublicIPAddressName": "JumpHostPublicIP",
    "jumpBoxNsgName": "JumpHostNSG",
    "jumpBoxNicName": "JumpHostNic",
    "jumpBoxSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), variables('jumpBoxSubnetName'))]",
    "serverNicName": "ServerNic",
    "serverSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), variables('serversSubnetName'))]",
    "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'sajumpbox')]",
    "azfwRouteTableName": "AzfwRouteTable",
    "firewallName": "firewall1",
    "publicIPNamePrefix": "publicIP",
    "azureFirewallSubnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets',parameters('virtualNetworkName'), variables('azureFirewallSubnetName'))]",
    "azureFirewallPublicIpId": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPNamePrefix'))]",
    "azureFirewallSubnetJSON": "[json(format('{{\"id\": \"{0}\"}}', variables('azureFirewallSubnetId')))]",
    "copy": [
      {
        "name": "azureFirewallIpConfigurations",
        "count": "[parameters('numberOfFirewallPublicIPAddresses')]",
        "input": {
          "name": "[concat('IpConf', copyIndex('azureFirewallIpConfigurations'))]",
          "properties": {
            "subnet": "[if(equals(copyIndex('azureFirewallIpConfigurations'), 0), variables('azureFirewallSubnetJSON'), json('null'))]",
            "publicIPAddress": {
              "id": "[concat(variables('azureFirewallPublicIpId'), add(copyIndex('azureFirewallIpConfigurations'), 1))]"
            }
          }
        }
      }
    ],
    "networkSecurityGroupName": "[concat(variables('serversSubnetName'), '-nsg')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[variables('storageAccountName')]",
      "apiVersion": "2019-04-01",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    },
    {
      "type": "Microsoft.Network/routeTables",
      "name": "[variables('azfwRouteTableName')]",
      "apiVersion": "2019-04-01",
      "location": "[parameters('location')]",
      "properties": {
        "disableBgpRoutePropagation": false,
        "routes": [
          {
            "name": "AzfwDefaultRoute",
            "properties": {
              "addressPrefix": "0.0.0.0/0",
              "nextHopType": "VirtualAppliance",
              "nextHopIpAddress": "[variables('nextHopIP')]"
            }
          }
        ]
      }
    },
    {
      "comments": "Simple Network Security Group for subnet [variables('serversSubnetName')]",
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2019-08-01",
      "name": "[variables('networkSecurityGroupName')]",
      "location": "[parameters('location')]",
      "properties": {}
    },
    {
      "name": "[parameters('virtualNetworkName')]",
      "apiVersion": "2019-04-01",
      "type": "Microsoft.Network/virtualNetworks",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/routeTables', variables('azfwRouteTableName'))]",
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
      ],
      "tags": {
        "displayName": "[parameters('virtualNetworkName')]"
      },
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('vnetAddressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('jumpBoxSubnetName')]",
            "properties": {
              "addressPrefix": "[variables('jumpboxSubnetPrefix')]"
            }
          },
          {
            "name": "[variables('azureFirewallSubnetName')]",
            "properties": {
              "addressPrefix": "[variables('azureFirewallSubnetPrefix')]"
            }
          },
          {
            "name": "[variables('serversSubnetName')]",
            "properties": {
              "addressPrefix": "[variables('serversSubnetPrefix')]",
              "routeTable": {
                "id": "[resourceId('Microsoft.Network/routeTables', variables('azfwRouteTableName'))]"
              },
              "networkSecurityGroup": {
                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
              }
            }
          }
        ]
      }
    },
    {
      "name": "[concat(variables('publicIPNamePrefix'), add(copyIndex(), 1))]",
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2019-04-01",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "copy": {
        "name": "publicIpCopy",
        "count": "[parameters('numberOfFirewallPublicIPAddresses')]"
      },
      "properties": {
        "publicIPAllocationMethod": "Static",
        "publicIPAddressVersion": "IPv4"
      }
    },
    {
      "name": "[variables('jumpBoxPublicIPAddressName')]",
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2019-04-01",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAllocationMethod": "Dynamic"
      }
    },
    {
      "name": "[variables('jumpBoxNsgName')]",
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2019-04-01",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": [
          {
            "name": "myNetworkSecurityGroupRuleRDP",
            "properties": {
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "3389",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 1000,
              "direction": "Inbound"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2019-04-01",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[variables('JumpBoxNicName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses/', variables('jumpBoxPublicIPAddressName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('jumpBoxNsgName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('jumpBoxPublicIPAddressName'))]"
              },
              "subnet": {
                "id": "[variables('jumpBoxSubnetId')]"
              }
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('jumpBoxNsgName'))]"
        }
      }
    },
    {
      "apiVersion": "2019-04-01",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[variables('ServerNicName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('serverSubnetId')]"
              }
            }
          }
        ]
      }
    },
    {
      "name": "JumpBox",
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2019-03-01",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
        "[resourceId('Microsoft.Network/networkInterfaces', variables('JumpBoxNicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "Standard_DS1_v2"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2012-R2-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            "osType": "Windows",
            "createOption": "FromImage",
            "diskSizeGB": 127
          }
        },
        "osProfile": {
          "computerName": "JumpBox",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('JumpBoxNicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
            "enabled": true,
            "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob]"
          }
        }
      }
    },
    {
      "name": "Server",
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2019-03-01",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
        "[resourceId('Microsoft.Network/networkInterfaces', variables('ServerNicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "Standard_DS1_v2"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2012-R2-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            "osType": "Windows",
            "createOption": "FromImage",
            "diskSizeGB": 127
          }
        },
        "osProfile": {
          "computerName": "Server",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('ServerNicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
            "enabled": true,
            "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob]"
          }
        }
      }
    },
    {
      "apiVersion": "2019-04-01",
      "type": "Microsoft.Network/azureFirewalls",
      "name": "[variables('firewallName')]",
      "location": "[parameters('location')]",
      "zones": "[if(equals(length(parameters('availabilityZones')), 0), json('null'), parameters('availabilityZones'))]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
        "publicIpCopy"
      ],
      "properties": {
        "ipConfigurations": "[variables('azureFirewallIpConfigurations')]",
        "applicationRuleCollections": [
          {
            "name": "appRc1",
            "properties": {
              "priority": 101,
              "action": {
                "type": "Allow"
              },
              "rules": [
                {
                  "name": "appRule1",
                  "protocols": [
                    {
                      "port": "80",
                      "protocolType": "http"
                    },
                    {
                      "port": "443",
                      "protocolType": "https"
                    }
                  ],
                  "targetFqdns": [
                    "www.microsoft.com"
                  ],
                  "sourceAddresses": [
                    "10.0.2.0/24"
                  ]
                }
              ]
            }
          }
        ],
        "networkRuleCollections": [
          {
            "name": "netRc1",
            "properties": {
              "priority": 200,
              "action": {
                "type": "Allow"
              },
              "rules": [
                {
                  "name": "netRule1",
                  "protocols": [
                    "TCP"
                  ],
                  "sourceAddresses": [
                    "10.0.2.0/24"
                  ],
                  "destinationAddresses": [
                    "*"
                  ],
                  "destinationPorts": [
                    "8000-8999"
                  ]
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

Multiple Azure resources are defined in the template:

Deploy the template

Deploy the ARM template to Azure:

  1. Select Deploy to Azure to sign in to Azure and open the template. The template creates an Azure Firewall, the network infrastructure, and two virtual machines.

    Deploy to Azure

  2. In the portal, on the Create a sandbox setup of Azure Firewall with Zones page, type or select the following values:

    • Resource group: Select Create new, type a name for the resource group, and select OK.
    • Virtual Network Name: Type a name for the new VNet.
    • Admin Username: Type a username for the administrator user account.
    • Admin Password: Type an administrator password.
  3. Read the terms and conditions, and then select I agree to the terms and conditions stated above and then select Purchase. The deployment can take 10 minutes or longer to complete.

Review deployed resources

Explore the resources that were created with the firewall.

To learn about the JSON syntax and properties for a firewall in a template, see Microsoft.Network/azureFirewalls.

Clean up resources

When you no longer need them, you can remove the resource group, firewall, and all related resources by running the Remove-AzResourceGroup PowerShell command. To remove a resource group named MyResourceGroup, run:

Remove-AzResourceGroup -Name MyResourceGroup

Don't remove the resource group and firewall if you plan to continue on to the firewall monitoring tutorial.

Next steps

Next, you can monitor the Azure Firewall logs.