Azure Networking Terraform Guide

Azure DNS Terraform

This page explains how to deploy Azure DNS with Terraform using Azure-specific DNS infrastructure patterns, including public DNS zones, private DNS zones, record sets, alias-ready patterns, and virtual network links for internal name resolution.

Instead of treating this as just a code page, this guide explains how Terraform maps to real Azure DNS architecture, what engineers usually get wrong around public delegation and private resolution, and how to structure reusable DNS infrastructure as code for production environments.

Main Terraform resources

AzureRM provides resources for public DNS zones, private DNS zones, public and private record types, and private DNS virtual network links.

Best fit

Ideal when you want repeatable infrastructure as code for zone hosting, DNS records, private name resolution, and multi-environment DNS consistency in Azure.

Common challenge

Most mistakes come from misunderstanding registrar delegation, mixing public and private DNS designs, or forgetting virtual network links for private zones.

Primary resource set Zones + records + links Terraform models Azure DNS as zones plus record resources and optional VNet links.
Best for Repeatable DNS management Version-controlled public and private DNS deployments across environments.
Key building blocks Public zones and private zones Records, delegation, and virtual network links matter most.
Related services Traffic Manager and Private Resolver These complement DNS zone hosting in broader Azure networking designs.

What is Azure DNS Terraform?

Azure DNS Terraform means defining and deploying Azure DNS zones, records, and private resolution links with infrastructure as code instead of creating them manually in the Azure portal. In Terraform, public Azure DNS and private Azure DNS use different resource families, which reflects the architectural difference between public authoritative DNS and private name resolution inside Azure networks.

In simple terms, Terraform lets you build Azure DNS as code so your zones, record sets, and internal DNS links are reusable, reviewable, auditable, and consistent across environments.
Infrastructure as Code Repeatable DNS deployment Git-controlled changes Public and private DNS Production-ready patterns

Why Terraform is used for Azure DNS

DNS can become messy very quickly when engineers add records manually across multiple environments. Terraform helps teams manage DNS as part of the same platform workflow used for networks, load balancers, private endpoints, and application delivery services.

Consistency

The same DNS structure can be deployed to development, testing, staging, and production without rebuilding records manually.

Reviewability

Teams can review DNS changes such as A records, CNAME records, TXT values, and private zone links before they affect production.

Scalability

Reusable modules help standardize DNS naming, zone patterns, and private network resolution across multiple applications.

Azure DNS Terraform explained with the 5 Ws + How

This structure helps beginners, working engineers, and interview learners quickly understand where Terraform fits inside Azure DNS design.

What

Terraform-based deployment of public Azure DNS zones, private DNS zones, records, and VNet links.

Why

To manage DNS hosting, records, internal name resolution, and environment consistency in a repeatable way.

When

Use it when DNS management must be consistent across environments or integrated into CI/CD and platform workflows.

Where

In Azure for public authoritative zones and internal private zone resolution across virtual networks.

Who

DevOps engineers, cloud engineers, platform teams, and architects responsible for cloud networking and application naming.

How

Terraform defines the Azure DNS resources and Azure applies that desired state through the AzureRM provider.

Prerequisites before writing the Terraform

Azure DNS depends on good naming and ownership planning. Public DNS needs a delegation plan through the registrar. Private DNS needs a network link plan across Azure VNets.

Common prerequisites

  • Azure subscription and Terraform AzureRM provider
  • Resource group
  • Public domain ownership if using public Azure DNS
  • DNS naming standard
  • Virtual network plan if using private DNS
  • Environment structure such as dev, sit, uat, prod

Production planning items

  • Registrar delegation procedure
  • TTL and propagation expectations
  • Private naming convention
  • Which VNets should link to which private zones
  • Record ownership and change workflow
  • Module and repository structure
In public Azure DNS, Terraform can create the zone and records, but your domain still needs delegation from the registrar before the internet will use Azure’s name servers.

Terraform resource model for Azure DNS

Terraform models Azure DNS using zones first and then record resources inside those zones. Private DNS uses a separate set of resources because private zone behavior is different from public authoritative zone hosting.

Terraform resource Azure concept Purpose
azurerm_dns_zone Public DNS zone Hosts a public DNS domain in Azure
azurerm_dns_a_record Public A record Maps a name to an IPv4 address
azurerm_dns_cname_record Public CNAME Maps a name to another hostname
azurerm_dns_txt_record Public TXT record Stores verification or metadata text
azurerm_private_dns_zone Private DNS zone Hosts internal DNS names for private Azure resolution
azurerm_private_dns_a_record Private A record Maps a private name to a private IP
azurerm_private_dns_zone_virtual_network_link Private VNet link Allows linked VNets to resolve names in the private zone

Recommended code structure

For real projects, do not keep all DNS logic in one giant file forever. Start simple, then move toward a reusable structure as your portal and cloud environment grow.

terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── modules/
    └── dns/
        ├── public-zone.tf
        ├── private-zone.tf
        ├── records.tf
        ├── links.tf
        ├── variables.tf
        └── outputs.tf

Root module

Connects shared naming, resource groups, and environment-specific values.

Reusable child module

Encapsulates zone creation, record creation, and private DNS link patterns so environments stay consistent.

Variables and outputs

Keep domain names, record values, private zone names, and VNet IDs cleanly separated.

Terraform examples for Azure DNS

The examples below show both public Azure DNS and private Azure DNS patterns. Together they cover the two main real-world use cases most teams need.

Terraform example for Azure Public DNS

This example shows a practical starter pattern for a public DNS zone with A, CNAME, and TXT records. It is intentionally readable and easy to extend for real internet-facing applications.

Public Azure DNS 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-dns-prod-san-1"
  location = "South Africa North"
}

resource "azurerm_dns_zone" "public_zone" {
  name                = "contoso.com"
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_dns_a_record" "www" {
  name                = "www"
  zone_name           = azurerm_dns_zone.public_zone.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl                 = 300
  records             = ["20.87.240.147"]
}

resource "azurerm_dns_cname_record" "api" {
  name                = "api"
  zone_name           = azurerm_dns_zone.public_zone.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl                 = 300
  record              = "myapp.azurefd.net"
}

resource "azurerm_dns_txt_record" "verification" {
  name                = "_asuid"
  zone_name           = azurerm_dns_zone.public_zone.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl                 = 300

  record {
    value = "example-verification-token"
  }
}
This creates the Azure public DNS zone and records, but it does not automatically change your registrar. You still need to delegate the domain to the Azure-provided name servers for internet resolution to use this zone.

Terraform example for Azure Private DNS

This example shows a private DNS zone, a private A record, a virtual network, and the VNet link that allows private name resolution inside Azure.

Private Azure DNS 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-private-dns-prod-san-1"
  location = "South Africa North"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-app-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_private_dns_zone" "private_zone" {
  name                = "internal.contoso.local"
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_private_dns_a_record" "app" {
  name                = "app"
  zone_name           = azurerm_private_dns_zone.private_zone.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl                 = 300
  records             = ["10.40.1.10"]
}

resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
  name                  = "link-vnet-app-prod"
  resource_group_name   = azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.private_zone.name
  virtual_network_id    = azurerm_virtual_network.vnet.id
  registration_enabled  = false
}
Private zones do not resolve everywhere by default. The VNet link is what makes the private zone available inside the linked virtual network.

How the Terraform code maps to the real Azure service

Many engineers can paste Terraform, but not everyone understands how each block maps to actual Azure DNS behavior. This section makes that relationship clear.

Public zone

azurerm_dns_zone creates the authoritative public DNS zone object in Azure.

Public records

azurerm_dns_a_record, azurerm_dns_cname_record, and similar resources create record sets inside that public zone.

Private zone

azurerm_private_dns_zone creates a private-only zone for internal Azure name resolution.

Private records

azurerm_private_dns_a_record creates a record that internal workloads can resolve if the zone is reachable through a VNet link.

VNet link

azurerm_private_dns_zone_virtual_network_link connects the private zone to a virtual network so resources in that network can resolve names from the zone.

Real effect

Terraform describes the desired DNS state, but internet resolution still depends on registrar delegation for public zones, while internal resolution still depends on VNet linking for private zones.

Real-world Azure DNS Terraform use cases

Practical examples make the page more useful and help avoid generic Terraform content by grounding it in Azure-specific DNS scenarios.

Public application DNS

A platform team manages public application domains, verification records, and service subdomains in Terraform rather than editing them manually in the portal.

Private application naming

Internal applications and services use private DNS zones linked to one or more VNets so workloads resolve internal names cleanly.

Multi-environment DNS standardization

Teams use modules and variables so dev, sit, uat, and prod zones and records follow the same naming, TTL, and change pattern.

Terraform vs manual Azure portal deployment

Both approaches can work, but Terraform becomes more valuable as record count, environment count, and change frequency increase.

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 understand the DNS service once in the portal, then move the final design into Terraform so DNS becomes part of your platform codebase instead of a manual operational dependency.

Best practices

Practical guidance is what makes a DNS Terraform page actually useful to working engineers. With Azure DNS, good practice is mostly about clear ownership, clean separation between public and private DNS, and realistic operational expectations.

Use modules for repeatability

Keep public zone, private zone, record, and VNet link logic reusable instead of copying similar blocks everywhere.

Separate public and private DNS clearly

Do not mix public-domain logic and private internal naming logic in a confusing or undocumented way.

Use clear naming conventions

Zone names, record names, and link names should make ownership and environment intent obvious.

Plan registrar delegation properly

Public Azure DNS does not become active on the internet until the registrar points the domain to Azure name servers.

Keep TTL intentional

Do not use random TTL values. Set them based on application behavior, migration needs, and caching expectations.

Test private resolution paths

Private DNS zones are only useful if linked VNets and workloads can actually resolve the names as expected.

Common mistakes

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

Forgetting delegation

Teams create the public zone and records in Terraform, but forget that the registrar still needs NS record updates for internet use.

No VNet link for private DNS

Engineers create the private zone and records correctly, but workloads still cannot resolve names because the zone is not linked to the required VNet.

Mixing public and private design

Using the wrong DNS model for the problem leads to confusing architecture and unexpected resolution behavior.

Hardcoding too much

Putting every record value, TTL, and zone name directly into one file makes the deployment brittle and hard to reuse.

No module structure

Large hand-written DNS blocks become difficult to maintain as record counts and environment counts increase.

No DNS ownership workflow

DNS often becomes risky when many teams can change records without review, naming standards, or clear approval flow.

Frequently asked questions

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

What Terraform resource is used for Azure public DNS zones?

The main public zone resource is azurerm_dns_zone, and public record types use resources like azurerm_dns_a_record and azurerm_dns_cname_record.

What Terraform resource is used for Azure private DNS zones?

The main private zone resource is azurerm_private_dns_zone, and private record types use resources such as azurerm_private_dns_a_record.

Does Terraform handle public DNS delegation at the registrar?

Terraform can create the Azure DNS zone, but the registrar-side delegation still needs to be handled through your registrar or its own automation mechanism.

Why does private DNS not resolve even though Terraform applied successfully?

A common reason is that the private zone exists, but there is no correct virtual network link connecting that zone to the workloads that need to resolve it.

Should I use one Terraform module for both public and private DNS?

You can, but many teams prefer separate internal logic or submodules because public DNS and private DNS have different operational concerns and dependencies.