Skip to main content
Jorge Bernhardt Jorge Bernhardt
  1. Posts/

Terraform - Creating Azure Private DNS Zones and Records

·1122 words·6 mins· 100 views · 5 likes ·
Terraform Microsoft Azure Azure Private DNS IaC

Hi everyone! Today I want to share how I use Terraform to implement your private DNS zones in Azure. Also, I’ll show you how to create ‘A’ records in these zones.

It’s important to underscore the power of automation. By leveraging Terraform to deploy Azure private DNS zones, we’re not just simplifying the process but also drastically reducing the likelihood of human errors. This results in an operation that is more efficient and significantly smoother.


Prerequisites #

  • You need Terraform CLI on your local machine, if you’re new to using Terraform to deploy Microsoft Azure resources, then I recommend you check out this link.
  • A text editor or IDE of your choice (Visual Studio Code with Terraform extension is my recommendation)
Declare Azure Provider in Terraform>

Declare Azure Provider in Terraform #

The file in Terraform is used to specify and configure the providers used in your Terraform configuration. A provider is a service or platform where the resources will be managed. This could be a cloud provider like Microsoft Azure, AWS, Google Cloud, etc.

This file is important because it tells Terraform which provider’s API to use when creating, updating, and deleting resources. Without it, Terraform wouldn’t know where to manage your resources.

provider "azurerm" {
  features {}
Create an Azure DNS Private zone using Terraform>

Create an Azure DNS Private zone using Terraform #

In the case of Azure private zone deployment, the file contains the following key components:

  • Resource group: This block creates a resource group in Azure with the given name and location. Resource groups in Azure serve as a logical container for resources deployed on Azure.
  • Private DNS zones: This block creates private DNS zones with the given name. The for_each construct is used to create multiple DNS zones based on the dns_zones variable.
  • DNS A records: This block creates DNS A records. Again, the for_each construct is used to create multiple DNS records based on the dns_records variable.
// Resource group
resource "azurerm_resource_group" "rg" {
  name     =
  location = var.resource_group.location
  tags     = var.tags

// Private DNS zones
resource "azurerm_private_dns_zone" "priv_dns_zone" {
  for_each = { for zone in var.dns_zones : zone.zone_name => zone }

  name                = each.value.zone_name
  resource_group_name =
  tags                = var.tags

// DNS A records
resource "azurerm_private_dns_a_record" "dns_a_record" {
  for_each = { for rec in var.dns_records : "${rec.zone_name}-${rec.record_name}" => rec }

  name                = each.value.record_name
  zone_name           = each.value.zone_name
  resource_group_name =
  ttl                 = each.value.ttl
  records             = [each.value.ip]
  tags                = var.tags
  depends_on          = [azurerm_private_dns_zone.priv_dns_zone]

Declaration of input variables>

Declaration of input variables #

The file in Terraform defines the variables I will use in the file. These variables allow for more flexibility and reusability in the code. In this example, the variables are defined in the include:

  • tags: This block declares a variable named tags, which is a map of strings. It is used to assign tags to the Azure resources being created. For example, you can use a key-value pair such as Terraform = true to indicate that the resource was deployed with Terraform.

  • resource_group: In this section, a map variable called resource_group is declared. It should include the name and location keys.

  • dns_zones: This block declares a variable named dns_zones, which is a list of objects. It is used to specify the names of the private DNS zones to be created.

  • dns_records: This section declares a variable named dns_records, which is a list of objects. It is used to specify the settings for the DNS records to be created.

// Variable for tags
variable "tags" {
  description = "Common tags for all resources"
  type = object({
    Environment = string
    Terraform   = string
  default = {
    Environment = ""
    Terraform   = "true"

// Variable for Azure Resource Group settings
variable "resource_group" {
  description = "Azure Resource Group settings"
  type = object({
    name     = string
    location = string

// Variable for private DNS zones
variable "dns_zones" {
  description = "Settings for private DNS zones"
  type = list(object({
    zone_name = string

// Variable for DNS records
variable "dns_records" {
  description = "Settings for DNS records"
  type = list(object({
    zone_name   = string
    record_name = string
    ttl         = number
    ip          = string
Declaration of output values>

Declaration of output values #

The file in Terraform extracts and displays information about the resources created or managed by your Terraform configuration. These outputs are defined using the output keyword and can be used to return information that can be useful for the user, for other Terraform configurations, or for programmatically using the information in scripts or other tools.

In this example, the file returns information about the resource group, the private DNS zones, and the DNS A records that were created.

Once Terraform has finished applying your configuration, it will display the defined outputs.

// Output for the created resource group
output "resource_group" {
  description = "The created resource group"
  value       = azurerm_resource_group.rg

// Output for the created private DNS zones
output "private_dns_zones" {
  description = "The created private DNS zones"
  value       = [for zone in azurerm_private_dns_zone.priv_dns_zone : zone]

// Output for the created private DNS A records
output "private_dns_a_records" {
  description = "Information about the DNS A records that were created"
  value = { for rec in azurerm_private_dns_a_record.dns_a_record : "${rec.zone_name}-${}" => rec }
Executing the Terraform Deployment>

Executing the Terraform Deployment #

Now that you’ve declared the resources correctly, it’s time to take the following steps to deploy them in your Azure environment.

  • Initialization: To begin, execute the terraform init command. This will initialize your working directory that holds the .tf files and download the provider specified in the file, and configure the Terraform backend. I suggest looking at this link if you’re curious about the process.

  • Planning: Next, execute the terraform plan. This command creates an execution plan and shows Terraform’s actions to achieve the desired state defined in your .tf files. This gives you a chance to review the changes before applying them.

  • Apply: When you’re satisfied with the plan, execute the terraform apply command. This will implement the required modifications to attain the intended infrastructure state. Before making any changes, you will be asked to confirm your decision.

  • Inspection: After applying the changes, you can use terraform show command to see the current state of your infrastructure.

  • Destroy (optional): when a project is no longer needed or when resources have become outdated. You can use the terraform destroy command. This will remove all the resources that Terraform has created.

References and useful links #

Thank you for taking the time to read my post. I sincerely hope that you find it helpful.