Architecting Enterprise Network Security: Deploying Azure Firewall via Terraform

Azure Firewall is a managed, cloud-based network security service designed to protect Azure Virtual Network resources by providing stateful inspection and filtering of network traffic. As organizations scale their cloud footprint, managing firewall rules through the Azure Portal becomes an operational liability, leading to configuration drift and visibility gaps. Integrating Azure Firewall with Terraform—an open-source Infrastructure-as-Code (IaC) tool—allows engineers to codify their security posture, ensuring that network boundaries are reproducible, auditable, and version-controlled.

Terraform utilizes HashiCorp Configuration Language (HCL) to define the desired state of the infrastructure. By defining Azure Firewall resources in HCL, DevOps teams can create an execution plan to preview infrastructure changes before they are deployed to production, significantly reducing the risk of accidental outages or security holes.

Core Architecture and SKU Selection

Before deploying an Azure Firewall instance via Terraform, it is critical to select the appropriate SKU based on the throughput requirements and the depth of inspection needed. Azure Firewall offers three distinct tiers tailored to different environment sizes and security needs.

Azure Firewall Service Tiers

SKU Maximum Throughput Key Features Ideal Use Case
Basic 250 Mbps Basic traffic filtering Small environments with limited throughput
Standard 30 Gbps L3-L7 filtering, Threat Intelligence, DNS proxy, Web categories Medium to large enterprises requiring advanced filtering
Premium 30 Gbps TLS inspection, IDPS (Intrusion Detection and Prevention System), URL filtering, Advanced web categories High-security environments requiring deep packet inspection

For organizations utilizing the Premium tier, the addition of IDPS and TLS inspection allows for the detection of malicious patterns within encrypted traffic, providing a layer of security that is indispensable for regulatory compliance and zero-trust architectures.

Environmental Prerequisites

A successful Terraform deployment requires a baseline of local tooling and cloud-side permissions. Without these, the Terraform provider will fail to authenticate or encounter authorization errors when attempting to provision resources in the subscription.

  • Terraform Installation: Version 1.3.0 or later is required to support the latest azurerm provider features.
  • Azure Subscription: An active subscription with Contributor-level access to the target resource group.
  • Azure CLI: The CLI must be installed and authenticated (az login) to provide the necessary credentials to Terraform.
  • Networking Knowledge: A fundamental understanding of Virtual Networks (VNets), subnets, and IP addressing is required.
  • Subscription ID: The specific Azure subscription ID where the firewall will be hosted must be available as a variable.

Implementing the Terraform Provider Configuration

The foundation of any Azure deployment is the provider block. The azurerm provider acts as the translation layer between the HCL code and the Azure Resource Manager (ARM) API.

```hcl
terraform {
requiredversion = ">= 1.3.0"
required
providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}

variable "subscription_id" {
description = "Azure subscription ID where the firewall will be deployed"
type = string
}

provider "azurerm" {
subscriptionid = var.subscriptionid
features {}
}
```

Networking Foundations: The Hub-and-Spoke Model

Azure Firewall is most effective when deployed in a hub-and-spoke topology. In this model, the firewall resides in a central "Hub" virtual network, and all traffic between spokes (application networks) or between the cloud and the internet is routed through this hub.

A critical technical requirement is the creation of a dedicated subnet specifically for the firewall. This subnet must be named exactly AzureFirewallSubnet. If the subnet is named differently, the Azure Firewall resource cannot be associated with it.

```hcl
resource "azurermresourcegroup" "firewall" {
name = "rg-firewall-prod"
location = "eastus"
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}

resource "azurermvirtualnetwork" "hub" {
name = "vnet-hub-prod"
location = azurermresourcegroup.firewall.location
resourcegroupname = azurermresourcegroup.firewall.name
address_space = ["10.0.0.0/16"]
tags = {
Environment = "Production"
}
}

resource "azurermsubnet" "firewallsubnet" {
name = "AzureFirewallSubnet"
resourcegroupname = azurermresourcegroup.firewall.name
virtualnetworkname = azurermvirtualnetwork.hub.name
address_prefixes = ["10.0.1.0/24"]
}
```

Deploying the Azure Firewall Instance

The firewall instance requires a public IP address for management and for receiving inbound traffic (in the case of DNAT rules). When deploying the instance, the sku_tier and sku_name must align with the organization's performance needs.

```hcl
resource "azurermpublicip" "region1-fw01-pip" {
name = "region1-fw01-pip"
resourcegroupname = azurermresourcegroup.firewall.name
location = azurermresourcegroup.firewall.location
allocation_method = "Static"
sku = "Standard"
tags = {
Environment = "Production"
Function = "baselabv1-azurefirewall"
}
}

resource "azurermfirewall" "region1-fw01" {
name = "region1-fw01"
location = azurerm
resourcegroup.firewall.location
resource
groupname = azurermresourcegroup.firewall.name
sku
name = "AZFWVNet"
sku
tier = "Premium"

ipconfiguration {
name = "fw-ipconfig"
subnet
id = azurermsubnet.firewallsubnet.id
publicipaddressid = azurermpublic_ip.region1-fw01-pip.id
}
}
```

Advanced Firewall Policy Configuration

Modern Azure Firewall deployments utilize "Firewall Policies" rather than legacy rules embedded directly in the firewall resource. This separation allows a single policy to be applied to multiple firewall instances across different regions.

Policy Components and Security Features

The azurerm_firewall_policy resource is where the intelligence of the firewall is configured. This includes DNS proxy settings, Threat Intelligence modes, and IDPS configurations.

  • DNS Proxy: When proxy_enabled is true, the firewall acts as a DNS proxy, allowing it to intercept DNS requests and apply filtering based on FQDNs.
  • Threat Intelligence: The threat_intelligence_mode can be set to Alert or DnsProxy. This uses Microsoft's global threat database to block known malicious IPs and domains.
  • IDPS (Intrusion Detection and Prevention System): Available in the Premium SKU, this allows for signature-based detection of network attacks. The mode can be set to Alert or Prevent.

```hcl
resource "azurermfirewallpolicy" "main" {
name = "prod-firewall-policy"
resourcegroupname = azurermresourcegroup.firewall.name
location = azurermresourcegroup.firewall.location
sku = "Premium"

dns {
proxy_enabled = true
servers = ["168.63.129.16"]
}

threatintelligencemode = "Alert"

threatintelligenceallowlist {
ip_addresses = ["192.168.1.0/24"]
fqdns = ["*.microsoft.com"]
}

insights {
enabled = true
defaultloganalyticsworkspaceid = var.loganalyticsworkspaceid
retention
in_days = 30
}

intrusiondetection {
mode = "Alert"
signature
overrides {
id = "123456789"
state = "Alert"
}
trafficbypass {
name = "bypass-rule"
protocol = "TCP"
description = "Test description"
destination
ports = ["80", "443"]
destinationaddresses = ["192.168.1.1"]
source
addresses = ["192.168.1.2"]
}
}

identity {
type = "SystemAssigned"
}

tags = var.tags
}
```

Implementing Granular Rule Sets

Azure Firewall operates on a "Default Deny" principal. Any traffic that does not explicitly match an allow rule is dropped. This requires a disciplined approach to rule creation. Rules are categorized into three types: Network Rules, Application Rules, and Destination NAT (DNAT) rules.

Network Rules

Network rules filter traffic based on IP address, port, and protocol (TCP, UDP, ICMP). These are ideal for low-level traffic control, such as allowing a specific server to reach a time server.

Application Rules

Application rules provide L7 filtering, allowing traffic based on Fully Qualified Domain Names (FQDNs). This is essential for controlling access to web services or cloud APIs without needing to maintain a list of rotating IP addresses.

IP Groups

To avoid repetitive IP lists across multiple rules, IP Groups are used. These act as named collections of IP addresses that can be referenced throughout the policy.

Example Rule Integration

In a production scenario, you might configure a policy to allow the following:
- Application access to www.microsoft.com.
- Windows Update access via the WindowsUpdate FQDN tag.
- UDP traffic to a specific time server at 13.86.101.172.

Terraform Project Structure for Scalability

For production environments, putting all code in a single main.tf file is unsustainable. A modular structure is recommended to separate the firewall instance from the policy and the rule definitions.

text terraform-azure-firewall/ ├── main.tf # Root module calling sub-modules ├── variables.tf # Global variables ├── outputs.tf # Output values (e.g., Firewall Public IP) ├── modules/ │ └── firewall/ │ ├── main.tf # Resource definitions for the FW and Policy │ ├── variables.tf # Module-specific variables │ └── outputs.tf # Module outputs └── policies/ └── rules.json # Externalized rule definitions for automation

By utilizing this structure, teams can reuse the firewall module across different environments (Dev, Test, Prod) while only changing the variable inputs.

Operationalizing the Deployment

The lifecycle of an Azure Firewall deployment involves a specific sequence of operations to ensure the infrastructure is validated before it is live.

  1. Plan Phase: Running terraform plan generates a detailed execution plan. This is the critical point for security reviews to ensure no overly permissive rules (e.g., 0.0.0.0/0 on sensitive ports) are being introduced.
  2. Apply Phase: terraform apply executes the changes in Azure.
  3. Validation Phase: Once deployed, connectivity tests should be performed to verify that the "Implicit Deny" is working and that only the defined allow rules are permitting traffic.
  4. Monitoring: By enabling insights in the firewall policy and linking a Log Analytics Workspace, administrators can monitor traffic patterns and refine rules based on actual usage.

Conclusion

Deploying Azure Firewall via Terraform transforms network security from a manual, error-prone task into a systematic engineering process. By leveraging the hub-and-spoke architecture, dedicated AzureFirewallSubnet configurations, and the separation of firewall instances from their policies, organizations can achieve a high degree of scalability and security. The ability to choose between Basic, Standard, and Premium SKUs ensures that the security controls—ranging from basic L3 filtering to advanced IDPS and TLS inspection—are aligned with the risk profile of the workload. Ultimately, treating the firewall configuration as code ensures that the security perimeter evolves alongside the application code, maintaining a rigorous and auditable security posture in an increasingly complex cloud landscape.

Sources

  1. oneuptime.com/blog/post/2026-02-23-how-to-create-azure-firewall-in-terraform/view
  2. thecloudpanda.com/blog/azure-firewall-terraform/
  3. learn.microsoft.com/en-us/azure/firewall-manager/quick-firewall-policy-terraform
  4. jakewalsh.co.uk/deploying-and-configuring-azure-firewall-using-terraform/
  5. learn.microsoft.com/en-us/azure/firewall/deploy-terraform

Related Posts