Azure Networking Terraform Guide

Azure Application Gateway Terraform

This page explains how to deploy Azure Application Gateway with Terraform using Azure-specific design patterns, including frontend IPs, listeners, backend pools, probes, routing rules, TLS settings, and WAF-ready structure.

Instead of treating this as just a code snippet page, this guide explains how the Terraform resource maps to the real Azure Application Gateway architecture, what engineers commonly get wrong, and how to structure reusable production code.

Main Terraform resource

The core resource is azurerm_application_gateway, where you define frontend IPs, ports, listeners, backend pools, probes, routing, and optional WAF configuration.

Best fit

Ideal when you want repeatable infrastructure-as-code for secure web traffic entry and want Azure networking and application routing fully version controlled.

Common challenge

Most mistakes come from wrong subnet planning, broken listener-to-rule mapping, incorrect probe paths, or backend HTTP settings that do not match the real application behavior.

Primary resource azurerm_application_gateway Main Terraform object for Azure Application Gateway deployment.
Best for Repeatable deployments Version-controlled web entry, routing, probes, TLS, and WAF.
Key building blocks Listeners, probes, rules Terraform mirrors the real Azure Application Gateway design.
Related services VNet, NSG, Public IP These resources often support the gateway deployment.

What is Azure Application Gateway Terraform?

Azure Application Gateway Terraform means defining and deploying Azure Application Gateway with infrastructure as code instead of clicking through the Azure portal manually. The main Terraform resource is azurerm_application_gateway, and it allows you to describe listeners, frontend IPs, frontend ports, backend pools, probes, backend HTTP settings, redirect rules, URL path maps, and WAF-related configuration in a repeatable way.

In simple terms, Terraform lets you build Azure Application Gateway as code, so the design is reusable, auditable, reviewable, and consistent across environments.
Infrastructure as Code Repeatable deployments Git-controlled changes Azure-specific web routing Production-ready patterns

Why Terraform is used for Azure Application Gateway

Application Gateway configurations can become large and error-prone when teams manage them manually. Terraform helps engineering teams standardize how listeners, pools, probes, certificates, and routing rules are created across development, test, and production environments.

Consistency

The same architecture can be deployed across multiple environments without rebuilding the gateway by hand.

Reviewability

Engineers can review Application Gateway changes through pull requests before they reach production.

Scalability

Teams can build reusable modules so multiple services use the same routing and security standards.

Azure Application Gateway Terraform explained with the 5 Ws + How

This keeps the page useful for beginners, engineers building the service, and interview learners looking for practical understanding.

What

Terraform-based deployment of Azure Application Gateway using AzureRM provider resources.

Why

To manage listeners, probes, backend pools, routing rules, and WAF-ready design in a repeatable way.

When

Use it when application delivery infrastructure must be consistent across environments or managed through CI/CD.

Where

Inside Azure VNets, usually with supporting resources like subnet, public IP, NSG, and backend application services.

Who

DevOps engineers, platform teams, cloud engineers, and security-conscious infrastructure teams.

How

Terraform defines Azure resources declaratively, and the Azure provider creates the Application Gateway based on that desired state.

Prerequisites before writing the Terraform

Azure Application Gateway usually depends on supporting infrastructure. A clean design starts with knowing what must already exist and what should be created together.

Common prerequisites

  • Azure subscription and Terraform AzureRM provider
  • Resource group
  • Virtual network
  • Dedicated subnet for Application Gateway
  • Public IP if internet-facing
  • Backend targets such as VMs, VM Scale Sets, private services, or ingress endpoints

Production planning items

  • Frontend hostname and DNS plan
  • TLS certificate approach
  • Probe path design
  • NSG and route table review
  • WAF decision
  • Environment naming conventions
Azure Application Gateway needs its own subnet design attention. Many deployment issues happen because teams treat the subnet as an afterthought instead of a first-class requirement.

Terraform resource model for Azure Application Gateway

One reason this resource feels complex is that many real Azure Application Gateway parts are nested inside a single Terraform resource. Understanding the mapping makes the code easier to maintain.

Terraform block Azure concept Purpose
gateway_ip_configuration Gateway subnet attachment Places the gateway into the correct subnet
frontend_ip_configuration Frontend IP Defines public or private entry IP
frontend_port Port listener entry Usually 80 or 443
backend_address_pool Backend pool Defines where traffic is sent
backend_http_settings Backend connection settings Defines protocol, port, affinity, timeout
probe Health probe Checks backend application health
http_listener Listener Accepts frontend HTTP/HTTPS traffic
request_routing_rule Routing rule Maps listener to backend target and behavior
ssl_certificate TLS certificate Used for HTTPS termination
waf_configuration WAF settings Enables application-layer security features

Recommended code structure

For real projects, do not keep everything in one giant Terraform file forever. Start simple, but grow toward a reusable layout.

terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── modules/
    └── application-gateway/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

Root module

Connects shared network resources, naming, and environment-specific values.

Reusable child module

Encapsulates the Application Gateway logic so multiple environments stay consistent.

Variables and outputs

Keep certificate values, backend IPs, ports, names, and environment settings cleanly separated.

Terraform example for Azure Application Gateway

This example shows a practical starter pattern for Azure Application Gateway using Terraform. It is intentionally readable and structured to help engineers understand how Azure concepts map into code.

Terraform starter example
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.100.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "rg-appgw-prod-san-1"
  location = "South Africa North"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-appgw-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space       = ["10.40.0.0/16"]
}

resource "azurerm_subnet" "appgw_subnet" {
  name                 = "snet-appgw-prod-san-1"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.40.10.0/24"]
}

resource "azurerm_public_ip" "appgw_pip" {
  name                = "pip-appgw-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  allocation_method   = "Static"
  sku                 = "Standard"
}

resource "azurerm_application_gateway" "appgw" {
  name                = "appgw-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "gateway-ip-config"
    subnet_id = azurerm_subnet.appgw_subnet.id
  }

  frontend_port {
    name = "frontend-https"
    port = 443
  }

  frontend_ip_configuration {
    name                 = "frontend-public"
    public_ip_address_id = azurerm_public_ip.appgw_pip.id
  }

  backend_address_pool {
    name         = "backend-pool-web"
    ip_addresses = ["10.40.20.10", "10.40.20.11"]
  }

  probe {
    name                                      = "probe-https"
    protocol                                  = "Https"
    path                                      = "/health"
    host                                      = "app.example.com"
    interval                                  = 30
    timeout                                   = 30
    unhealthy_threshold                       = 3
    pick_host_name_from_backend_http_settings = false
    minimum_servers                           = 0

    match {
      status_code = ["200-399"]
    }
  }

  backend_http_settings {
    name                                = "backend-https-settings"
    cookie_based_affinity               = "Disabled"
    path                                = "/"
    port                                = 443
    protocol                            = "Https"
    request_timeout                     = 60
    probe_name                          = "probe-https"
    pick_host_name_from_backend_address = false
    host_name                           = "app.example.com"
  }

  ssl_certificate {
    name     = "tls-cert"
    data     = filebase64("certificate.pfx")
    password = var.pfx_password
  }

  http_listener {
    name                           = "listener-https"
    frontend_ip_configuration_name = "frontend-public"
    frontend_port_name             = "frontend-https"
    protocol                       = "Https"
    ssl_certificate_name           = "tls-cert"
    host_name                      = "app.example.com"
  }

  request_routing_rule {
    name                       = "rule-https-basic"
    rule_type                  = "Basic"
    http_listener_name         = "listener-https"
    backend_address_pool_name  = "backend-pool-web"
    backend_http_settings_name = "backend-https-settings"
    priority                   = 100
  }

  waf_configuration {
    enabled          = true
    firewall_mode    = "Prevention"
    rule_set_type    = "OWASP"
    rule_set_version = "3.2"
  }
}

variable "pfx_password" {
  description = "Password for the PFX certificate"
  type        = string
  sensitive   = true
}

How the Terraform code maps to the real Azure service

Many engineers can paste Terraform, but not everyone understands how each section maps to the running Application Gateway. This section makes that relationship clear.

Network placement

azurerm_subnet.appgw_subnet and gateway_ip_configuration together place the gateway inside the correct Azure subnet.

Public entry

azurerm_public_ip.appgw_pip and frontend_ip_configuration expose the entry point to clients.

Traffic intake

frontend_port plus http_listener define how HTTPS traffic is accepted and which hostname and certificate are used.

Backend routing

backend_address_pool, backend_http_settings, and request_routing_rule define where traffic goes and how.

Health

probe checks the actual application health path so unhealthy backends stop receiving traffic.

Security

waf_configuration and ssl_certificate add application-layer protection and HTTPS support.

Real-world Azure Application Gateway Terraform use cases

Practical examples make this page more useful and help avoid duplicate, generic Terraform content.

Multi-environment rollout

A platform team deploys the same Application Gateway pattern to dev, sit, uat, and prod using environment variables and module reuse.

AKS north-south entry

Terraform provisions a consistent application entry layer in front of Kubernetes-hosted services while keeping the design reviewable in Git.

Centralized WAF deployment

Security teams standardize WAF-enabled gateways and ensure listeners, TLS settings, and backend health patterns are applied uniformly.

Terraform vs manual Azure portal deployment

Both approaches can work, but Terraform becomes more valuable as environments and rule complexity grow.

Approach Best for Strength Weakness
Terraform Repeatable production deployments Version control, consistency, reviewable changes More setup and structure required at the start
Azure Portal One-off testing or learning Easy for quick initial exploration Hard to reproduce accurately across environments
A strong engineering pattern is to learn the resource once in the portal, then move it into Terraform so the final design is managed as code.

Best practices

Practical guidance is one of the things that makes a page feel premium and useful to working engineers.

Use a module for repeatability

Keep the Application Gateway logic reusable instead of copying and editing large blocks in every environment.

Name blocks clearly

Use consistent names for listeners, probes, ports, and pools so rule mapping stays readable.

Match probes to real health endpoints

Probe the application health path, not just the root page, if your service has a proper readiness endpoint.

Keep certificate handling deliberate

Document where the certificate comes from, how it is rotated, and whether the gateway terminates or re-encrypts TLS.

Separate variables from code

Use variables and tfvars for environment-specific values like hostnames, backend IPs, and passwords.

Validate supporting network design

Subnet, NSG, route table, DNS, and backend reachability must all be correct or the gateway will appear broken.

Common mistakes

Provider-specific mistakes help avoid thin, duplicate content and make the page practical in the Azure context.

Wrong subnet assumptions

Engineers often forget that Application Gateway subnet planning matters and cannot just be treated like any random subnet.

Probe misconfiguration

A wrong host header, path, port, or protocol can make healthy applications look unhealthy.

Listener-rule mismatch

If listeners, ports, backend settings, and routing rules do not align, traffic does not flow as expected.

Hardcoding too much

Putting all names, backend IPs, and certificate assumptions directly in one file makes the deployment brittle.

Ignoring backend HTTP settings

Timeout, protocol, affinity, and host header settings are easy to overlook but often cause real failures.

No internal structure

Large hand-written blocks without module design become difficult to manage as soon as multiple apps share the gateway.

Frequently asked questions

FAQ sections help capture real search intent and make the resource page more complete.

What Terraform resource is used for Azure Application Gateway?

The main resource is azurerm_application_gateway.

Can I deploy WAF with Azure Application Gateway in Terraform?

Yes. WAF-related settings can be defined inside the Application Gateway configuration, depending on the design and provider support.

Do I need a dedicated subnet for Azure Application Gateway?

Application Gateway subnet planning is important, and teams should design it intentionally rather than placing the resource without network review.

Should I use Terraform modules for Application Gateway?

Yes, especially when you have multiple environments or similar gateway patterns across teams.

What usually breaks first in Application Gateway Terraform deployments?

Probes, listener mappings, backend settings, subnet assumptions, and certificate handling are the most common problem areas.