
Automating Azure Private DNS Zone creation with Terraform can save you a significant amount of time and effort.
To get started, you'll need to have Terraform installed on your system. Terraform is a popular infrastructure as code tool that allows you to manage and provision infrastructure in a consistent and reproducible way.
You can automate Azure Private DNS Zone creation by using Terraform's Azure Provider, which allows you to create and manage Azure resources using Terraform configurations.
Terraform's Azure Provider supports creating private DNS zones in Azure, and you can use Terraform's built-in functions to generate the necessary DNS configuration.
Azure Private DNS Zone
Azure Private DNS Zone is a crucial component in managing private endpoints in Azure. It serves as a logical container for resources deployed on Azure.
You can create an Azure Private DNS Private zone using Terraform by defining a main.tf file with specific key components. This includes a resource group, private DNS zones, and DNS A records.

The resource group block creates a resource group in Azure with a given name and location, which is a logical container for resources deployed on Azure.
Private DNS zones are created with a given name, and the for_each construct is used to create multiple DNS zones based on the dns_zones variable. This allows for the creation of multiple DNS zones with different names.
DNS A records are created using the for_each construct, which is used to create multiple DNS records based on the dns_records variable.
To manage DNS resolution for users of private endpoints, you need to create a private DNS zone and associate it with the Virtual Networks where those clients are. This is known as the "DNS dance".
A private DNS zone cannot be just any domain, but must be a specific zone name for each private endpoint type, as documented in Azure Private Endpoint DNS configuration.
For example, for blob resources in storage accounts, you would create a private DNS zone for privatelink.blob.core.windows.net.
You might be tempted to create an A record for the storage account in that DNS zone, but instead, you can "link" the endpoint with the zone, and the A record will be created for you.
A different take: Terraform Azure Resource Group

This "link" between endpoints and zones is called a "zone group".
Zone groups can be created automatically using Azure Policy, which allows you to automate the linking of private endpoints to DNS zones.
This can be achieved using a special type of Azure Policy called "Deploy If Not Exists", which will look for endpoints without zone groups and connect them automatically to a pre-defined DNS private zone.
Additional reading: Availability Zone Azure
Terraform Configuration
Terraform Configuration is a crucial step in deploying Azure Private DNS zones. The provider.tf file specifies and configures the providers used in your Terraform configuration, including cloud providers like Microsoft Azure.
To work with Azure resources, you need to declare the provider in the provider.tf file, which tells Terraform which provider’s API to use when creating, updating, and deleting resources.
In Terraform, variables are used to make the code more flexible and reusable. The variables.tf file defines the variables used in the main.tf file, including tags, resource_group, dns_zones, and dns_records. These variables can be used to assign tags to resources, specify the name and location of a resource group, and define private DNS zones and DNS records.
Here are the variable types used in Terraform configuration:
- tags: a map of strings
- resource_group: a map with name and location keys
- dns_zones: a list of objects
- dns_records: a list of objects
Implement the Code
To implement the Terraform code, you'll need to create a directory and navigate to it. Create a file named providers.tf and insert the following code, which specifies the required version of Terraform and the providers used.
The providers.tf file is crucial because it tells Terraform which provider's API to use when creating, updating, and deleting resources. This file is used to specify and configure the providers used in your Terraform configuration.
Here's the code to insert in providers.tf:
terraform {
required_version = ">=1.2"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {}
}
Next, create a file named main.tf and insert the code that defines the resources to be created. This includes a random pet resource, an Azure resource group, a random string resource, an Azure DNS zone, and an Azure DNS A record.
You might like: How to Create Terraform from Existing Resources Azure
The main.tf file is where you define the resources that Terraform will create. This includes the Azure resource group, DNS zone, and A record.
Here's the code to insert in main.tf:
resource "random_pet" "rg_name" {
prefix = var.resource_group_name_prefix
}
resource "azurerm_resource_group" "rg" {
name = random_pet.rg_name.id
location = var.resource_group_location
}
resource "random_string" "azurerm_dns_zone_name" {
length = 13
lower = true
numeric = false
special = false
upper = false
}
resource "azurerm_dns_zone" "zone" {
name = (
var.dns_zone_name != null ?
var.dns_zone_name :
"www.${random_string.azurerm_dns_zone_name.result}.azurequickstart.org"
)
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_dns_a_record" "record" {
name = "www"
resource_group_name = azurerm_resource_group.rg.name
zone_name = azurerm_dns_zone.zone.name
ttl = var.dns_ttl
records = var.dns_records
}
Create a file named variables.tf and insert the code that defines the variables used in the Terraform configuration. This includes the resource group location, resource group name prefix, DNS zone name, DNS TTL, and DNS records.
The variables.tf file is where you define the variables that are used in the Terraform configuration. This includes the resource group location, DNS zone name, and DNS records.
Here's the code to insert in variables.tf:
Curious to learn more? Check out: How to Create Terraform from Existing Vm Azure
variable "resource_group_location" {
type = string
default = "eastus"
description = "Location for all resources."
}
variable "resource_group_name_prefix" {
type = string
default = "rg"
description = "Prefix of the resource group name that's combined with a random value so name is unique in your Azure subscription."
}
variable "dns_zone_name" {
type = string
default = null
description = "Name of the DNS zone."
}
variable "dns_ttl" {
type = number
default = 3600
description = "Time To Live (TTL) of the DNS record (in seconds)."
}
variable "dns_records" {
type = list(string)
default = ["1.2.3.4", "1.2.3.5"]
description = "List of IPv4 addresses."
}
Finally, create a file named outputs.tf and insert the code that defines the outputs of the Terraform configuration. This includes the resource group name, DNS zone name, and name servers.
The outputs.tf file is where you define the outputs of the Terraform configuration. This includes the resource group name, DNS zone name, and name servers.
Check this out: Azure Virtual Network Dns Servers
Here's the code to insert in outputs.tf:
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "dns_zone_name" {
value = azurerm_dns_zone.zone.name
}
output "name_servers" {
value = azurerm_dns_zone.zone.name_servers
}
After creating the files, you can run the Terraform code using the following commands:
1. Get the Azure resource group name: $resource_group_name=$(terraform output -raw resource_group_name)
2. Get the DNS zone name: $dns_zone_name=$(terraform output -raw dns_zone_name)
3. Run Get-AzDnsZone to display information about the new service: Get-AzDnsZone -ResourceGroupName $resource_group_name -Name $dns_zone_name
Input Variables
Input Variables are a crucial part of Terraform Configuration, allowing for more flexibility and reusability in the code.
By defining variables in the variables.tf file, you can easily change or update values without having to modify the main.tf file.
The tags variable is a map of strings, used to assign tags to Azure resources being created.
You can use a key-value pair like Terraform = true to indicate that the resource was deployed with Terraform.
The resource_group variable is a map that should include the name and location keys.
This makes it easy to specify the resource group settings without having to hardcode them in the main.tf file.
The dns_zones variable is a list of objects, used to specify the names of the private DNS zones to be created.
Similarly, the dns_records variable is a list of objects, used to specify the settings for the DNS records to be created.
Here's a summary of the variables we've discussed:
- tags: a map of strings for assigning tags to Azure resources
- resource_group: a map with name and location keys
- dns_zones: a list of objects for private DNS zones
- dns_records: a list of objects for DNS record settings
Automatically Creating Zone Groups
You can automate the linking of private endpoints to DNS zones with Azure Policy. This is a game-changer for agile development.
Azure Policy allows you to create a special type of policy called "Deploy If Not Exists" that looks for endpoints without zone groups.
This policy connects them automatically to a pre-defined DNS private zone.
You can even create this policy via Terraform, following cloud best practices using Infrastructure as Code.
The whole process involves creating an Azure Policy that looks for endpoints without zone groups and connects them to a pre-defined DNS private zone.
This is a great way to streamline your development process and reduce the need for manual intervention.
If this caught your attention, see: Azure Development
Supporting Multiple Endpoints
There are 101 documented private endpoint types in Azure Private Endpoint DNS configuration.
You might end up expanding your Terraform code to cover all of these, which can be a daunting task.
At the time of this writing, there are 101 documented private endpoint types in Azure Private Endpoint DNS configuration.
This requires careful planning and organization to ensure your Terraform configuration is accurate and up-to-date.
You might need to add multiple resource blocks to your Terraform configuration to support different endpoint types.
Readers also liked: Azure 101
Dry Code
Dry code is a valuable practice in Terraform configuration, as it helps reduce duplication and makes your code more maintainable. It's achieved by avoiding duplicate code in your Terraform templates.
One way to apply DRY code is by using Terraform modules, which can be reused across different configurations. For example, a Terraform module can be used to create private DNS zones and Azure Policy definitions for various private endpoint types.
The goal of DRY code is to have a single Terraform template that can create all the policies required to manage each private endpoint type. This is demonstrated in the azpolicy-tf repository, which uses Terraform loop mechanisms to generate copies of the same basic policy customized for each private endpoint type.
However, it's essential to note that this approach may not be valid for certain specific types of private endpoints, such as AKS and Azure Batch. These services require region-specific policies, which cannot be covered by a single Terraform template.
To create a DRY Terraform template, you can use a dictionary with endpoint types as keys and the private DNS zones they will be associated with as values. The module will then loop over the items in the dictionary and create the corresponding private DNS zones and Azure Policy definitions.
The list of private endpoint types and their corresponding DNS zones is not exhaustive, but the azpolicy-tf repository provides a starting point for creating your own DRY Terraform template.
Microsoft.Network.PrivateDnsZones
Microsoft.Network.PrivateDnsZones is a great way to manage private DNS zones in Azure using Terraform.
You can create a private DNS zone with a name and a resource group, as shown in the example: `resource "azurerm_private_dns_zone" "example" { name = "example.com" resource_group_name = "example-resource-group" }`.
The private DNS zone can be linked to a virtual network, allowing you to manage DNS settings for your virtual network.
You can also create a private DNS zone with a name and a resource group, and then link it to a virtual network, as shown in the example: `resource "azurerm_private_dns_zone" "example" { name = "example.com" resource_group_name = "example-resource-group" } resource "azurerm_private_dns_zone_virtual_network_link" "example" { name = "example-link" private_dns_zone_id = azurerm_private_dns_zone.example.id virtual_network_id = azurerm_virtual_network.example.id }`.
This allows you to manage DNS settings for your virtual network from within Terraform.
Sources
- https://www.jorgebernhardt.com/terraform-azure-private-dns-zone/
- https://blog.cloudtrooper.net/2023/08/19/dry-terraform-code-for-private-link-and-dns/
- https://learn.microsoft.com/en-us/azure/dns/dns-get-started-terraform
- https://github.com/aztfm/terraform-azurerm-private-dns-zone
- https://learn.microsoft.com/en-us/azure/templates/microsoft.network/privatednszones
Featured Images: pexels.com