Azure DNS Setup Guide
Set up Azure DNS zones, configure records, and integrate with App Service custom domains.
Prerequisites
- Azure subscription
- A registered domain name
- Basic understanding of DNS records (A, CNAME, TXT, MX)
Azure DNS Setup Guide
Azure DNS lets you host your DNS domains on Azure infrastructure, providing high-performance name resolution using Microsoft's global network of anycast DNS servers. Whether you need public DNS for your websites and APIs, private DNS for internal service discovery and Private Endpoint resolution, or both, Azure DNS integrates seamlessly with other Azure services and provides features not available in standard DNS like alias records and automatic Private Endpoint registration.
This guide walks through setting up public DNS zones, managing record types, configuring alias records for zone apex support, creating and linking private DNS zones, implementing hybrid DNS resolution with Azure Private DNS Resolver, and applying best practices for DNS management at scale. DNS is often treated as an afterthought, but it is one of the most critical infrastructure components. When DNS breaks, everything breaks.
Public DNS Zones
A public DNS zone hosts DNS records that are resolvable from the internet. When you create a zone in Azure DNS, Azure provides four authoritative name servers distributed across different top-level domains (com, net, org, info) for redundancy. You configure these name servers at your domain registrar to delegate DNS authority to Azure.
# Create a public DNS zone
az network dns zone create \
--resource-group dns-rg \
--name example.com
# View the assigned name servers (configure these at your registrar)
az network dns zone show \
--resource-group dns-rg \
--name example.com \
--query nameServers \
--output tsv
# Output:
# ns1-04.azure-dns.com.
# ns2-04.azure-dns.net.
# ns3-04.azure-dns.org.
# ns4-04.azure-dns.info.
# Add an A record pointing to your web server
az network dns record-set a add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name www \
--ipv4-address 20.30.40.50
# Add a CNAME for API subdomain pointing to App Service
az network dns record-set cname set-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name api \
--cname myapp-api.azurewebsites.net
# Add a CNAME for CDN endpoint
az network dns record-set cname set-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name cdn \
--cname myapp-cdn.azureedge.net
# Add an MX record for email routing
az network dns record-set mx add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--exchange mail.example.com \
--preference 10
# Add a TXT record for SPF (email sender verification)
az network dns record-set txt add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--value "v=spf1 include:spf.protection.outlook.com -all"
# Add a TXT record for domain verification (e.g., for App Service)
az network dns record-set txt add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name asuid.www \
--value "AbC123dEf456..."
# Set TTL for a record set (in seconds)
az network dns record-set a update \
--resource-group dns-rg \
--zone-name example.com \
--name www \
--set ttl=300NS Record Delegation
After creating the zone, you must update the NS records at your domain registrar to point to Azure's name servers. This delegation step is required for Azure DNS to serve queries for your domain. DNS propagation typically completes within a few hours but can take up to 48 hours depending on cached TTLs across the internet. Verify delegation is working using nslookup -type=NS example.com ordig NS example.com before configuring application records.
DNS Record Types
Understanding the purpose and behavior of each record type is essential for configuring DNS correctly. Using the wrong record type can cause resolution failures, email delivery problems, or security certificate issues.
| Record Type | Purpose | Example | Key Considerations |
|---|---|---|---|
| A | Maps hostname to IPv4 address | www → 20.30.40.50 | Use alias records for Azure resource IPs that may change |
| AAAA | Maps hostname to IPv6 address | www → 2001:db8::1 | Required for IPv6-enabled services |
| CNAME | Alias to another hostname (canonical name) | api → myapp.azurewebsites.net | Cannot be used at zone apex (@) per RFC |
| MX | Mail server routing with priority | @ → mail.example.com (priority 10) | Lower priority number = higher preference |
| TXT | Text data (SPF, DKIM, domain verification) | @ → “v=spf1 include:...” | Max 255 chars per string; multiple strings concatenated |
| SRV | Service location with priority, weight, port | _sip._tcp → sip.example.com:5060 | Used by SIP, XMPP, and service discovery protocols |
| CAA | Certificate authority authorization | @ → 0 issue “letsencrypt.org” | Controls which CAs can issue certificates for your domain |
| NS | Name server delegation | @ → ns1-04.azure-dns.com | Created automatically when zone is created; used for subdomain delegation |
| SOA | Start of authority (zone metadata) | Serial, refresh, retry, expire timers | Auto-managed by Azure DNS; controls zone transfer behavior |
Alias Records
Azure DNS alias records are a powerful feature not available in standard DNS. An alias record points directly to an Azure resource (Public IP, Traffic Manager profile, Front Door, or CDN endpoint) instead of a static IP or hostname. When the resource's underlying IP changes, the DNS record updates automatically, eliminating stale records and the need for manual DNS updates.
Why Alias Records Matter
- Zone apex CNAME problem: Standard DNS prohibits CNAME records at the zone apex (example.com without www). Alias records solve this by pointing the apex A record directly to an Azure resource, enabling routing of naked domains to Front Door, Traffic Manager, or a public IP.
- Dynamic IP tracking: If you use a Public IP resource that gets a new address after being deleted and recreated, an alias record automatically resolves to the new IP. A traditional A record would point to the old, now-invalid IP.
- Built-in health checks: Alias records to Traffic Manager profiles inherit health monitoring, so DNS only returns healthy endpoints.
# Alias A record at zone apex pointing to Azure Public IP resource
# (Automatically updates if the IP changes)
az network dns record-set a create \
--resource-group dns-rg \
--zone-name example.com \
--name @ \
--target-resource /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/publicIPAddresses/myPublicIP
# Alias A record at zone apex pointing to Traffic Manager
# (Solves the CNAME-at-apex problem for multi-region routing)
az network dns record-set a create \
--resource-group dns-rg \
--zone-name example.com \
--name @ \
--target-resource /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/trafficManagerProfiles/myTMProfile
# Alias A record pointing to Front Door endpoint
az network dns record-set a create \
--resource-group dns-rg \
--zone-name example.com \
--name @ \
--target-resource /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Cdn/profiles/myFrontDoor/afdEndpoints/myEndpoint
# Regular CNAME for www subdomain (standard approach)
az network dns record-set cname set-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name www \
--cname example.com
# www.example.com -> example.com -> (alias to Front Door/TM)Zone Apex Best Practice
For production websites, use an alias record at the zone apex (@) pointing to Azure Front Door or Traffic Manager, and a CNAME for the www subdomain pointing to the apex domain. This gives you: naked domain support (example.com), www support (www.example.com), global load balancing, and automatic failover, all with a simple two-record setup. Add a redirect from www to the apex (or vice versa) in your application or Front Door rules for a consistent URL.
Subdomain Delegation
For large organizations, you may want to delegate subdomains to different teams or Azure subscriptions. Subdomain delegation creates NS records in the parent zone that point to a separate DNS zone for the subdomain.
# Create a new zone for the subdomain (can be in a different subscription)
az network dns zone create \
--resource-group team-a-dns-rg \
--name api.example.com
# Get the name servers for the new subdomain zone
az network dns zone show \
--resource-group team-a-dns-rg \
--name api.example.com \
--query nameServers \
--output tsv
# In the PARENT zone (example.com), create NS records for the subdomain
az network dns record-set ns add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name api \
--nsdname ns1-08.azure-dns.com.
az network dns record-set ns add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name api \
--nsdname ns2-08.azure-dns.net.
# Now Team A can manage all records under api.example.com independently
az network dns record-set a add-record \
--resource-group team-a-dns-rg \
--zone-name api.example.com \
--record-set-name v1 \
--ipv4-address 10.1.2.3
# Creates: v1.api.example.com -> 10.1.2.3Private DNS Zones
Private DNS zones provide name resolution within your Azure virtual networks without exposing records to the internet. They are essential for three primary scenarios: Private Endpoint name resolution, internal service discovery, and split-horizon DNS (where the same domain name resolves differently on the internet vs within your VNets).
Setting Up Private DNS for Private Endpoints
When you create a Private Endpoint for an Azure PaaS service, the service gets a private IP address in your VNet. However, the service's public FQDN (e.g.,mystorageaccount.blob.core.windows.net) still resolves to the public IP by default. Private DNS Zones solve this by providing a CNAME chain that redirects resolution to the private IP.
# Create private DNS zones for common Azure services
az network private-dns zone create --resource-group dns-rg --name privatelink.blob.core.windows.net
az network private-dns zone create --resource-group dns-rg --name privatelink.file.core.windows.net
az network private-dns zone create --resource-group dns-rg --name privatelink.database.windows.net
az network private-dns zone create --resource-group dns-rg --name privatelink.vaultcore.azure.net
az network private-dns zone create --resource-group dns-rg --name privatelink.azurecr.io
az network private-dns zone create --resource-group dns-rg --name privatelink.documents.azure.com
az network private-dns zone create --resource-group dns-rg --name privatelink.servicebus.windows.net
az network private-dns zone create --resource-group dns-rg --name privatelink.redis.cache.windows.net
# Link each zone to the hub VNet (enables resolution from hub)
az network private-dns link vnet create \
--resource-group dns-rg \
--zone-name privatelink.blob.core.windows.net \
--name hub-link \
--virtual-network /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/hub-vnet \
--registration-enabled false
# Link to each spoke VNet that needs Private Endpoint resolution
az network private-dns link vnet create \
--resource-group dns-rg \
--zone-name privatelink.blob.core.windows.net \
--name prod-spoke-link \
--virtual-network /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/prod-spoke-vnet \
--registration-enabled false
# When you create a Private Endpoint with auto DNS registration,
# Azure adds an A record to the private DNS zone:
# mystorageaccount.privatelink.blob.core.windows.net -> 10.1.4.5
# The DNS resolution chain becomes:
# mystorageaccount.blob.core.windows.net
# -> CNAME: mystorageaccount.privatelink.blob.core.windows.net
# -> A: 10.1.4.5 (from Private DNS Zone)Common Private DNS Zones for Azure Services
| Azure Service | Private DNS Zone Name | Group ID |
|---|---|---|
| Storage (Blob) | privatelink.blob.core.windows.net | blob |
| Storage (File) | privatelink.file.core.windows.net | file |
| Storage (Table) | privatelink.table.core.windows.net | table |
| Storage (Queue) | privatelink.queue.core.windows.net | queue |
| Azure SQL Database | privatelink.database.windows.net | sqlServer |
| Cosmos DB (SQL API) | privatelink.documents.azure.com | SQL |
| Key Vault | privatelink.vaultcore.azure.net | vault |
| Container Registry | privatelink.azurecr.io | registry |
| Event Hubs | privatelink.servicebus.windows.net | namespace |
| Azure Cache for Redis | privatelink.redis.cache.windows.net | redisCache |
| Azure Monitor (Log Analytics) | privatelink.oms.opinsights.azure.com | azuremonitor |
Automate DNS Zone Management with Azure Policy
As your Azure footprint grows, manually creating and linking private DNS zones becomes error-prone and unsustainable. Use Azure Policy with the DeployIfNotExistseffect to automatically create private DNS zone groups when Private Endpoints are created. This ensures every Private Endpoint gets the correct DNS configuration without manual intervention, even when created by teams that are not aware of the DNS requirements.
Hybrid DNS with Azure Private DNS Resolver
In hybrid environments (Azure + on-premises), DNS resolution must work bidirectionally: Azure resources must resolve on-premises hostnames, and on-premises clients must resolve Azure Private Endpoint hostnames. Azure Private DNS Resolver is a managed service that handles this forwarding without requiring custom DNS servers on VMs.
Hybrid DNS Architecture
On-Premises Client resolving Azure Private Endpoint:
1. Client queries: mystorageaccount.blob.core.windows.net
2. On-premises DNS server has conditional forwarder:
*.blob.core.windows.net -> Azure DNS Resolver Inbound IP (10.0.11.4)
3. Resolver queries Azure Private DNS Zone
4. Returns: 10.1.4.5 (private endpoint IP)
5. Client connects via VPN/ExpressRoute to 10.1.4.5
Azure VM resolving on-premises hostname:
1. VM queries: db.corp.contoso.com
2. Azure DNS forwards to DNS Resolver
3. Resolver has forwarding rule:
corp.contoso.com -> On-premises DNS (192.168.1.10)
4. On-premises DNS returns: 192.168.1.100
5. VM connects via VPN/ExpressRoute to 192.168.1.100
Required forwarding rules:
On-Premises DNS (conditional forwarders to Azure Resolver Inbound):
*.privatelink.blob.core.windows.net
*.privatelink.database.windows.net
*.privatelink.vaultcore.azure.net
(one per Private DNS Zone)
Azure DNS Resolver (forwarding rules to on-premises DNS):
corp.contoso.com -> 192.168.1.10, 192.168.1.11
legacy.internal -> 192.168.1.10, 192.168.1.11# Create the Private DNS Resolver
az dns-resolver create \
--name hub-dns-resolver \
--resource-group dns-rg \
--location eastus2 \
--id /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/hub-vnet
# Create inbound endpoint (receives queries from on-premises)
az dns-resolver inbound-endpoint create \
--name inbound-from-onprem \
--dns-resolver-name hub-dns-resolver \
--resource-group dns-rg \
--location eastus2 \
--ip-configurations '[{"id": "/subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/hub-vnet/subnets/DNSResolverInbound", "private-ip-allocation-method": "Dynamic"}]'
# Create outbound endpoint (forwards queries to on-premises)
az dns-resolver outbound-endpoint create \
--name outbound-to-onprem \
--dns-resolver-name hub-dns-resolver \
--resource-group dns-rg \
--location eastus2 \
--id /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/hub-vnet/subnets/DNSResolverOutbound
# Create forwarding ruleset
az dns-resolver forwarding-ruleset create \
--name onprem-forwarding \
--resource-group dns-rg \
--location eastus2 \
--outbound-endpoints '[{"id": "/subscriptions/<sub-id>/resourceGroups/dns-rg/providers/Microsoft.Network/dnsResolvers/hub-dns-resolver/outboundEndpoints/outbound-to-onprem"}]'
# Forward on-premises domain queries
az dns-resolver forwarding-rule create \
--name forward-corp-contoso \
--ruleset-name onprem-forwarding \
--resource-group dns-rg \
--domain-name "corp.contoso.com." \
--target-dns-servers '[{"ip-address": "192.168.1.10", "port": 53}, {"ip-address": "192.168.1.11", "port": 53}]'
# Link the forwarding ruleset to spoke VNets
az dns-resolver vnet-link create \
--name prod-spoke-link \
--ruleset-name onprem-forwarding \
--resource-group dns-rg \
--id /subscriptions/<sub-id>/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/prod-spoke-vnetDNS Security
DNS security is often overlooked but is critical for protecting your domain and users from phishing, email spoofing, and man-in-the-middle attacks.
Essential DNS Security Records
# SPF record (Sender Policy Framework) - controls who can send email from your domain
az network dns record-set txt add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--value "v=spf1 include:spf.protection.outlook.com include:_spf.google.com -all"
# DKIM record (DomainKeys Identified Mail) - email signing verification
az network dns record-set cname set-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name selector1._domainkey \
--cname selector1-example-com._domainkey.example.onmicrosoft.com
# DMARC record (Domain-based Message Authentication) - email auth policy
az network dns record-set txt add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name _dmarc \
--value "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100"
# CAA record (Certificate Authority Authorization) - restrict CA issuance
az network dns record-set caa add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--flags 0 \
--tag "issue" \
--value "letsencrypt.org"
az network dns record-set caa add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--flags 0 \
--tag "issue" \
--value "digicert.com"
# Report unauthorized issuance attempts
az network dns record-set caa add-record \
--resource-group dns-rg \
--zone-name example.com \
--record-set-name @ \
--flags 0 \
--tag "iodef" \
--value "mailto:security@example.com"Always Set CAA Records
CAA records are the most commonly missing DNS security control. Without CAA records, any certificate authority can issue certificates for your domain, including those controlled by attackers who have compromised a CA. Set CAA records to only authorize the CAs you actually use (e.g., Let's Encrypt, DigiCert). This is a free security control that takes minutes to implement and significantly reduces the risk of fraudulent certificate issuance.
Best Practices
- Centralize DNS zones in a dedicated subscription or resource group. This simplifies management, RBAC, and avoids scattered zones across teams.
- Use Infrastructure as Code for DNS records. Manage zone records in Bicep or Terraform alongside the resources they reference. This prevents configuration drift and provides audit trails.
- Set appropriate TTLs. Use low TTLs (60-300 seconds) for records that may change during failover scenarios. Use higher TTLs (3600-86400 seconds) for stable records to improve caching and reduce query volume.
- Enable diagnostic logging on DNS zones to track query volumes, record changes, and troubleshoot resolution issues. Forward logs to Log Analytics for analysis.
- Use CAA records to restrict which certificate authorities can issue certificates for your domain.
- Automate Private DNS Zone management with Azure Policy to ensure every Private Endpoint gets correct DNS configuration automatically.
- Implement DMARC, SPF, and DKIM to protect your domain from email spoofing and phishing attacks.
- Plan hybrid DNS before deploying Private Endpoints. Retrofitting DNS forwarding across an existing multi-VNet environment is significantly more complex.
Key Takeaways
- 1Azure DNS hosts DNS zones with globally distributed name servers for high availability.
- 2Alias records point to Azure resources and automatically update when IPs change.
- 3Private DNS zones enable name resolution within VNets without public exposure.
- 4Azure DNS integrates with App Service for automatic custom domain verification.
- 5DNSSEC is supported for domain validation and security.
- 6DNS zone delegation from your registrar requires updating NS records to Azure name servers.
Frequently Asked Questions
How do I delegate my domain to Azure DNS?
What is the difference between public and private DNS zones?
How do I set up a custom domain for an Azure App Service?
Does Azure DNS support DNSSEC?
How much does Azure DNS cost?
Written by CloudToolStack Team
Cloud engineers and architects with hands-on experience across AWS, Azure, and GCP. We write guides based on real-world production patterns, not just documentation rewrites.
Disclaimer: This guide is for educational purposes. Cloud services change frequently; always refer to official documentation for the latest information. AWS, Azure, and GCP are trademarks of their respective owners.