This module is designed to manage an Azure Private DNS zone, including its creation, linking it to one or more virtual networks, and managing various types of DNS records.
- Private DNS Zone: Creates a private DNS zone within the specified resource group.
- Virtual Network Links: Dynamically links the DNS zone to one or more virtual networks, with optional auto-registration of DNS records.
- DNS Records: Supports the creation of:
- A records (IPv4 addresses)
- AAAA records (IPv6 addresses)
- CNAME records (canonical names)
- MX records (mail exchange)
- PTR records (reverse DNS)
- SRV records (service location)
- TXT records (text data)
- SOA records (start of authority โ configurable contact, TTLs, and retry/refresh policies)
This example demonstrates how to use the tf-azurerm-private-dns module to create a private DNS zone and configure supported records.
resource "azurerm_resource_group" "rg" {
name = "rg-private-dns-example"
location = "germanywestcentral"
}
module "vnet" {
source = "CloudAstro/virtual-network/azurerm"
name = "vnet-example"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
module "private_dns_zone" {
source = "../.."
name = "mydomain.com"
resource_group_name = azurerm_resource_group.rg.name
soa_record = {
email = "admin.contoso.com"
expire_time = 604800
minimum_ttl = 300
refresh_time = 3600
retry_time = 600
ttl = 3600
tags = { "environment" = "dev", "project" = "example" }
}
a_records = {
"my-a-record-1" = {
name = "record1"
ttl = 3600
records = ["10.0.0.4", "10.0.0.5"]
tags = { "environment" = "dev", "project" = "example" }
},
"my-a-record-2" = {
name = "record2"
ttl = 7200
records = ["10.0.1.4"]
tags = { "environment" = "dev", "project" = "example" }
}
}
aaaa_records = {
"my-aaaa-record-1" = {
name = "record1"
records = ["2001:0db8:85a3:0000:0000:8a2e:0370:7334"]
ttl = 3600
tags = { "environment" = "dev", "project" = "example" }
}
}
cname_records = {
"my-cname-record-1" = {
name = "record1"
ttl = 3600
record = "example.com"
tags = { "environment" = "dev", "project" = "example" }
}
}
mx_records = {
"my-mx-record-1" = {
name = "record1"
record = {
"mx1" = {
preference = 10
exchange = "mail1.example.com"
},
"mx2" = {
preference = 20
exchange = "mail2.example.com"
}
}
ttl = 3600
tags = { "environment" = "dev", "project" = "example" }
}
}
ptr_records = {
"my-ptr-record-1" = {
name = "record1"
ttl = 3600
records = ["ptr.example.com"]
tags = { "environment" = "dev", "project" = "example" }
}
}
srv_records = {
"my-srv-record-1" = {
name = "_sip._tcp.example.com"
ttl = 3600
record = {
"srv1" = {
priority = 10
weight = 5
port = 5060
target = "sipserver.example.com"
},
"srv2" = {
priority = 20
weight = 10
port = 5060
target = "sipbackup.example.com"
}
}
tags = { "environment" = "dev", "project" = "example" }
}
}
txt_records = {
"example-txt" = {
name = "example"
ttl = 3600
record = {
"entry1" = {
value = "v=spf1 include:example.com ~all"
},
"entry2" = {
value = "some-other-verification=12345"
}
}
tags = { "environment" = "dev", "project" = "example" }
}
}
vnet_links = {
"vnet-link-1" = {
name = "con-example-vnet"
virtual_network_id = module.vnet.virtual_network.id
registration_enabled = true
}
}
tags = {
env = "dev"
region = "gwc"
}
}| Name | Version |
|---|---|
| terraform | ~> 1.9.0 |
| azurerm | >= 4.0.0 |
| Name | Version |
|---|---|
| azurerm | >= 4.0.0 |
| Name | Type |
|---|---|
| azurerm_private_dns_a_record.a_records | resource |
| azurerm_private_dns_aaaa_record.aaaa_records | resource |
| azurerm_private_dns_cname_record.cname_records | resource |
| azurerm_private_dns_mx_record.mx_records | resource |
| azurerm_private_dns_ptr_record.ptr_records | resource |
| azurerm_private_dns_srv_record.srv_records | resource |
| azurerm_private_dns_txt_record.txt_records | resource |
| azurerm_private_dns_zone.private_dns | resource |
| azurerm_private_dns_zone_virtual_network_link.vnet_links | resource |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| name | * name - (Required) The name of the Private DNS Zone. Must be a valid domain name. Changing this forces a new resource to be created.* -> NOTE: If you are going to be using the Private DNS Zone with a Private Endpoint the name of the Private DNS Zone must follow the Private DNS Zone name schema in the product documentation in order for the two resources to be connected successfully. Example Input: name = "privatelink.blob.core.windows.net" |
string |
n/a | yes |
| resource_group_name | * resource_group_name - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created.Example Input: resource_group_name = "rg-private-dns-dev" |
string |
n/a | yes |
| a_records | * name - (Required) The name of the DNS A Record. Changing this forces a new resource to be created.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* records - (Required) List of IPv4 Addresses.* tags - (Optional) A mapping of tags to assign to the resource.Example Input: a_records = { |
map(object({ |
null |
no |
| aaaa_records | A map of objects where each object contains information to create a AAAA record. The following arguments are supported: * name - (Required) The name of the DNS A Record. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* records - (Required) A list of IPv6 Addresses.* tags - (Optional) A mapping of tags to assign to the resource.Example Input: aaaa_records = { |
map(object({ |
null |
no |
| cname_records | A map of objects where each object contains information to create a CNAME record. The following arguments are supported: * name - (Required) The name of the DNS CNAME Record. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds. Possible values are between 0 and 2147483647.* record - (Required) The target of the CNAME.* tags - (Optional) A mapping of tags to assign to the resource.Example Input: cname_records = { |
map(object({ |
null |
no |
| mx_records | A map of objects where each object contains information to create a MX record. The following arguments are supported: * name - (Optional) The name of the DNS MX Record. Changing this forces a new resource to be created. Default to '@' for root zone entry.* resource_group_name - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* record - (Required) One or more record blocks as defined below.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* tags - (Optional) A mapping of tags to assign to the resource.A record block supports the following: * preference - (Required) The preference of the MX record.* exchange - (Required) The FQDN of the exchange to MX record points to.Example Input: mx_records = { |
map(object({ |
null |
no |
| ptr_records | A map of objects where each object contains information to create a PTR record. The following arguments are supported: * name - (Required) The name of the DNS PTR Record. Changing this forces a new resource to be created.* resource_group_name - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* records - (Required) List of Fully Qualified Domain Names.* tags - (Optional) A mapping of tags to assign to the resource.Example Input: ptr_records = { |
map(object({ |
null |
no |
| soa_record | * email - (Required) The email contact for the SOA record.* expire_time - (Optional) The expire time for the SOA record. Defaults to 2419200.* minimum_ttl - (Optional) The minimum Time To Live for the SOA record. By convention, it is used to determine the negative caching duration. Defaults to 10.* refresh_time - (Optional) The refresh time for the SOA record. Defaults to 3600.* retry_time - (Optional) The retry time for the SOA record. Defaults to 300.* ttl - (Optional) The Time To Live of the SOA Record in seconds. Defaults to 3600.* tags - (Optional) A mapping of tags to assign to the Record Set.Example Input: soa_record = { |
object({ |
null |
no |
| srv_records | A map of objects where each object contains information to create a SRV record.. The following arguments are supported: * name - (Required) The name of the DNS PTR Record. Changing this forces a new resource to be created.* resource_group_name - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* record - (Required) List of Fully Qualified Domain Names.* tags - (Optional) A mapping of tags to assign to the resource.A record block supports the following: * priority - (Required) The priority of the SRV record.* weight - (Required) The Weight of the SRV record.* port - (Required) The Port the service is listening on.* target - (Required) The FQDN of the service.Example Input: srv_records = { |
map(object({ |
null |
no |
| tags | * tags - (Optional) A mapping of tags to assign to the resource.Example input: tags = { |
map(string) |
null |
no |
| timeouts | * timeouts - The timeouts block allows you to specify timeouts for certain actions:* create - (Defaults to 30 minutes) Used when creating the Container App.* delete - (Defaults to 30 minutes) Used when deleting the Container App.* read - (Defaults to 5 minutes) Used when retrieving the Container App.* update - (Defaults to 30 minutes) Used when updating the Container App.Example Input: container_app_timeouts = { |
object({ |
null |
no |
| txt_records | A map of objects where each object contains information to create a TXT record. The following arguments are supported: * name - (Required) The name of the DNS TXT Record. Changing this forces a new resource to be created.* resource_group_name - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created.* zone_name - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created.* record - (Required) One or more record blocks as defined below.* ttl - (Required) The Time To Live (TTL) of the DNS record in seconds.* tags - (Optional) A mapping of tags to assign to the resource.A record block supports the following: * value - (Required) The value of the TXT record. Max length: 1024 charactersExample Input: txt_records = { |
map(object({ |
null |
no |
| vnet_links | Dynamically links the DNS zone to one or more virtual link networks with optional auto-registration of DNS records. The following arguments are supported: * name - (Required) The name of the Private DNS Zone Virtual Network Link. Changing this forces a new resource to be created.* virtual_network_id - (Required) The ID of the Virtual Network that should be linked to the DNS Zone. Changing this forces a new resource to be created.* registration_enabled - (Optional) Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled? Defaults to false.Example input: vnet_links = { |
map(object({ |
null |
no |
| Name | Description |
|---|---|
| a_records | Blocks containing configuration of each A record. |
| aaaa_records | Blocks containing configuration of each AAAA record. |
| cname_records | Blocks containing configuration of each CNAME record. |
| mx_records | Blocks containing configuration of each MX record. |
| private_dns | * name - The name of the Private DNS Zone.* resource_group_name - The name of the resource group in which the DNS zone is created.* id - The resource ID of the Private DNS Zone.* tags - A mapping of tags assigned to the Private DNS Zone.Example output usage: output "private_dns_zone_name" { value = module.module_name.private_dns.name } |
| ptr_records | Blocks containing configuration of each PTR record. |
| srv_records | Blocks containing configuration of each SRV record. |
| txt_records | Blocks containing configuration of each TXT record. |
| virtual_network_link_id | Virtual network link id. |
No modules.
For comprehensive guidance on Azure Private DNS and configuration scenarios, refer to the Azure Private DNS documentation.
This module helps you manage a Private DNS zone and dynamically link it to one or more virtual networks (via virtual network links).
- A single Private DNS zone can be linked to multiple virtual networks, enabling cross-VNet name resolution.
- Billing is based on the number of Private DNS zones, queries, and virtual network links.
- Always validate and test your Terraform plans to ensure resources are provisioned and linked correctly.
This module is released under the MIT License. See the LICENSE file for full details.