How to Deploy an Azure Firewall Premium using Terraform

Si Thu Ye Aung
5 min readApr 27, 2023

--

Azure Firewall is a cloud-based network security service that provides firewall capabilities to protect Azure Virtual Network resources. It is a fully managed service that allows you to create, enforce, and log application and network connectivity policies across multiple subscriptions and virtual networks. With Azure Firewall, you can centrally manage your network security policies and provide secure access to your applications and data.

In this article, we will learn how to deploy an Azure Firewall (Premium) and Azure Firewall Policy (Premium) using Terraform.

Prerequisite lists are following us.

  1. Pre-installed Terrafrom on your local machine.
  2. azure service principal account. ( contributor role in your subscription)

1. Create the terraform provided .

We required to create the Terrafrom file called provider.tf and add the following code:

terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.53.0"
}
}
provider "azurerm" {
skip_provider_registration = "true"
features {}
subscription_id = "your_subscription_id"
tenant_id = "your_tenant_id"
client_id = "client_id"
client_secret = "client_secret"
}

2. Creating the necessary resources in Azure.

We required to create two Terrafrom file called main.tf and variables.tf. And then add the following code:

First, we add the code to variables.tf file.

variable "group_name" {
description = "A name to use for most resource group."
default = "rg-afw-nonprod-001"
}

variable "vnet_name" {
description = "A name to use for most resource group."
default = "vnet-afw-nonprod-001"
}

variable "location" {
description = "The location where to deploy the firewall."
default = "Southeast Asia"
}

variable "address_space" {
description = "A list of network addresses."
default = ["10.0.0.0/16"]
}

variable "subnet_name" {
description = "A name to use for subnet name"
default = "AzureFirewallSubnet"
}

variable "address_prefix" {
description = "A list of addresse prefixes."
default = ["10.0.1.0/24"]
}

variable "pip_name" {
description = "A name to use for public ip name"
default = "pip-afw-nonprod-001"
}

variable "fw_name" {
description = "A lame to use for firewall name"
default = "fw-afw-nonprod-001"
}

variable "fwp_name" {
description = "A name to use for firewall policy name"
default = "fw-afwp-nonprod-001"
}

Second, we add the code to main.tf file.

1.1 Create the resource group as per following block.

resource "azurerm_resource_group" "default" {
name = var.group_name
location = var.location
}

1.2 Create the VNET, Sub-net and address-prefix as per following block.

variable "address_space" {
description = "A list of network addresses."
default = ["10.0.0.0/16"]
}

variable "subnet_name" {
description = "A name to use for subnet name"
default = "AzureFirewallSubnet"
}

variable "address_prefix" {
description = "A list of addresse prefixes."
default = ["10.0.1.0/24"]
}

1.3. Create the public IP address as per following block.

resource "azurerm_public_ip" "default" {
name = var.pip_name
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
allocation_method = "Static"
sku = "Standard"
}

Note: there is only support “Standard” SKU.

1.4. Create the Azure Firewall (Premium SKU) as per following block.

resource "azurerm_firewall" "default" {
name = var.fw_name
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
sku_name = "AZFW_VNet"
sku_tier = "Premium"
firewall_policy_id = azurerm_firewall_policy.default.id
ip_configuration {
name = "configuration"
subnet_id = azurerm_subnet.default.id
public_ip_address_id = azurerm_public_ip.default.id
}
}

Let’s start to create the Azure Firewall Policy (Premium SKU) and associate with Azure Firewall.

3. Create Terrafrom file called afwp.tf as per following block.

We created Azure Firewall Policy (Premium) and enabled following feature.

  1. Threat intelligence.
  2. IDS/IPS.
  3. TLS Inspection.
  4. Logs Analytics.
  5. SKU (Premium)
resource "azurerm_firewall_policy" "default" {
name = var.fwp_name
resource_group_name = azurerm_resource_group.default.name
location = azurerm_resource_group.default.location
sku = "Premium"
threat_intelligence_mode = "Alert"
#threat_intelligence_allowlist {
# fqdns = ["*.microsoft.com"]
# ip_addresses = ["8.8.8.8"]
#}
intrusion_detection {
mode = "Alert"
}
identity {
identity_ids = [
"/subscriptions/ec27316e-9920-1236-82ed-1674b5a40e9ef/resourceGroups/rg-afw-nonprod-001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/fw-cert-id-Kzk2-kdfaid"
]
type = "UserAssigned"
}
tls_certificate {
key_vault_secret_id = "https://fw-cert-kv-ulnijfromwxid.vault.azure.net/secrets/fw-cert-ULNIJfROMwxid/f6d557e0337d472k06fk9391"
name = "fw-cert-id-Kzk2-kdfaid"
}
insights {
default_log_analytics_workspace_id = "/subscriptions/ec27316e-9920-1236-82ed-1674b5a40e9ef/resourceGroups/rg-log-001/providers/Microsoft.OperationalInsights/workspaces/log-nonprod-fw-001
enabled = true
retention_in_days = 30
log_analytics_workspace {
firewall_location = "southeastasia"
id = "/subscriptions/ec27316e-9920-1236-82ed-1674b5a40e9eff/resourceGroups/rg-log-shared-sea-001/providers/Microsoft.OperationalInsights/workspaces/log-nonprod-fw-001"
}
}
}

Now, All are ready ( VNet, Subnet, Public IP address, Firewall , Firewall policy and Logs ) .

It is time to create Firewall rules.

First thing First create the D-NAT Rules. As per following block.

resource "azurerm_firewall_policy_rule_collection_group" "dnat" {
name = "FW-DNAT-GROUP"
firewall_policy_id = azurerm_firewall_policy.default.id
priority = 300

nat_rule_collection {
name = "Allow_HTTPS"
priority = 200
action = "Dnat"
rule {
name = "Allow_HTTPS"
protocols = ["TCP"]
source_addresses = ["*"]
destination_address = azurerm_public_ip.default.ip_address //module.firewall_publicip.public_ip[0].ip_address
destination_ports = ["443"]
translated_address = "10.71.134.4"
translated_port = "443"
}
}
nat_rule_collection {
name = "Allow_HTTP"
priority = 205
action = "Dnat"
rule {
name = "Allow_HTTP"
protocols = ["TCP","UDP"]
source_addresses = ["*"]
destination_address = azurerm_public_ip.default.ip_address //module.firewall_publicip.public_ip[0].ip_address
destination_ports = ["80"]
translated_address = "10.71.134.5"
translated_port = "80"
}
}
nat_rule_collection {
name = "Allow_RDP"
priority = 210
action = "Dnat"
rule {
name = "Allow_RDP"
protocols = ["TCP","UDP"]
source_addresses = ["*"]
destination_address = azurerm_public_ip.default.ip_address //module.firewall_publicip.public_ip[0].ip_address
destination_ports = ["3389"]
translated_address = "10.0.3.4"
translated_port = "3389"
}
}
}

Here is the Ref URL: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy_rule_collection_group

Next , Create a Application Rule group and Rules as per following.

resource "azurerm_firewall_policy_rule_collection_group" "app" {
name = "FW-APP-GROUP"
firewall_policy_id = azurerm_firewall_policy.default.id
priority = 300
application_rule_collection {
name = "allow_whitelist"
priority = 200
action = "Allow"
rule {
name = "allow_whitelist"
protocols {
type = "Http"
port = 80
}
protocols {
type = "Https"
port = 443
}
source_addresses = ["10.0.2.4"]
terminate_tls = "false"
destination_fqdns = ["*.microsoft.com"]
}
}
application_rule_collection {
name = "allow_google"
priority = 205
action = "Allow"
rule {
name = "allow_google"
protocols {
type = "Http"
port = 80
}
protocols {
type = "Https"
port = 443
}
source_addresses = ["10.0.2.4"]
terminate_tls = "false"
destination_fqdns = ["*.google.com"]
}
}
}

Finally, we create the Network rule group and Rules.

resource "azurerm_firewall_policy_rule_collection_group" "net" {
name = "FW-NET-GROUP"
firewall_policy_id = azurerm_firewall_policy.default.id
priority = 300
network_rule_collection {
name = "allow_rdp_from_office"
priority = 200
action = "Allow"
rule {
name = "allow_rdp_from_office"
protocols = ["TCP", "UDP"]
source_addresses = ["*"]
destination_addresses = ["10.0.2.4"]
destination_ports = ["80", "443", "3389"]
}
}

network_rule_collection {
name = "allow_icmp"
priority = 205
action = "Allow"
rule {
name = "allow_icmp"
protocols = ["TCP", "UDP"]
source_addresses = ["*"]
destination_addresses = ["10.0.2.4"]
destination_ports = ["*"]
}
}

}

--

--

Si Thu Ye Aung

Azure Solutions Architect Expert| CKA | RHCSA| RHCE |Terraform |VMware Certified Professional 6 | CCNA |Certificate of Cloud Security (CCSK v3)