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.
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
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.
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"
}
}
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.
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
}
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 |
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.