Skip to content

CloudAstro/terraform-azurerm-private-dns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

4 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

tf-azurerm-private-dns Module

Changelog Notice Apache V2 License OpenTofu Registry

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.

Features

  • 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)

Example Usage

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

Requirements

Name Version
terraform ~> 1.9.0
azurerm >= 4.0.0

Providers

Name Version
azurerm >= 4.0.0

Resources

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

Inputs

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 = {
"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 = {}
}
}
map(object({
name = string
ttl = number
records = list(string)
tags = optional(map(string))
}))
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 = {
"my-aaaa-record-1" = {
name = "record1"
zone_name = "privatelink.blob.core.windows.net"
records = ["2001:0db8:85a3:0000:0000:8a2e:0370:7334"]
ttl = 3600
tags = { "environment" = "dev", "project" = "example" }
}
}
map(object({
name = string
zone_name = optional(string)
ttl = number
records = list(string)
tags = optional(map(string))
}))
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 = {
"my-cname-record-1" = {
name = "record1"
zone_name = "privatelink.blob.core.windows.net"
ttl = 3600
record = "example.com"
tags = { "environment" = "dev", "project" = "example" }
}
}
map(object({
name = string
zone_name = optional(string)
ttl = number
record = string
tags = optional(map(string))
}))
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 = {
"my-mx-record-1" = {
name = "record1"
zone_name = "privatelink.blob.core.windows.net"
record = {
"mx1" = {
preference = 10
exchange = "mail1.example.com"
},
"mx2" = {
preference = 20
exchange = "mail2.example.com"
}
}
ttl = 3600
tags = { "environment" = "dev", "project" = "example" }
}
}
map(object({
name = optional(string, "@")
zone_name = optional(string)
record = map(object({
preference = number
exchange = string
}))
ttl = number
tags = optional(map(string))
}))
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 = {
"my-ptr-record-1" = {
name = "record1"
zone_name = "privatelink.blob.core.windows.net"
ttl = 3600
records = ["ptr.example.com"]
tags = { "environment" = "dev", "project" = "example" }
}
}
map(object({
name = string
zone_name = optional(string)
ttl = number
records = list(string)
tags = optional(map(string))
}))
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 = {
email = "admin.contoso.com"
expire_time = 604800
minimum_ttl = 300
refresh_time = 3600
retry_time = 600
ttl = 3600
}
object({
email = string
expire_time = optional(number)
minimum_ttl = optional(number)
refresh_time = optional(number)
retry_time = optional(number)
ttl = optional(number)
tags = optional(map(string))
})
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 = {
"my-srv-record-1" = {
name = "_sip._tcp.example.com"
zone_name = "privatelink.blob.core.windows.net"
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" }
}
map(object({
name = string
zone_name = optional(string)
ttl = number
record = map(object({
priority = number
weight = number
port = number
target = string
}))
tags = optional(map(string))
}))
null no
tags * tags - (Optional) A mapping of tags to assign to the resource.

Example input:
tags = {
env = prod
region = gwc
}
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 = {
create = "45m"
delete = "30m"
read = "10m"
update = "40m"
}
object({
create = optional(string)
delete = optional(string)
read = optional(string)
update = optional(string)
})
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 characters

Example Input:
txt_records = {
"example-txt" = {
name = "example"
zone_name = "example.com"
ttl = 3600
record = {
"entry1" = {
value = "v=spf1 include:example.com ~all"
},
"entry2" = {
value = "some-other-verification=12345"
}
}
tags = { "environment" = "dev", "project" = "example" }
}
}
map(object({
name = string
zone_name = optional(string)
ttl = number
record = map(object({
value = string
}))
tags = optional(map(string))
}))
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 = {
"vnet-link-1" = {
virtual_network_id = "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/vnet1"
registration_enabled = true
},
"vnet-link-2" = {
virtual_network_id = "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/vnet2"
registration_enabled = false
}
}
map(object({
name = string
virtual_network_id = string
registration_enabled = optional(bool, false)
}))
null no

Outputs

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.

Modules

No modules.

๐ŸŒ Additional Information

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).

๐Ÿ“š Resources

โš ๏ธ Notes

  • 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.

๐Ÿงพ License

This module is released under the MIT License. See the LICENSE file for full details.

About

Terraform Module for private DNS

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages