Skip to content

DNS Private Zones

🎯 Lab Objective

In this hands-on lab, you will learn how to:

  • Create and configure Azure Private DNS Zones for internal name resolution
  • Link Private DNS Zones to Virtual Networks with auto-registration
  • Add custom DNS records (A and CNAME) for application access
  • Validate DNS resolution from client VMs within the network
  • Troubleshoot common DNS issues and implement fixes

Goal: Make http://app.corp.local and http://www.corp.local accessible from the Client VM using Azure Private DNS.


πŸ—οΈ Pre-Provisioned Environment

The following Azure resources have been pre-deployed in your environment:

Resource Overview

Resource TypeResource NameConfigurationPurpose
Resource Grouprg-privdns-labContains all lab resourcesLogical container
Virtual Networkprivdns-lab-vnetPrivate network segmentNetwork foundation
VM-AppUbuntu ServerNGINX on port 80 (internal)Web application server
VM-ClientUbuntu Serverdnsutils & curl installedDNS testing client

Network Architecture

privdns-lab-vnet
β”œβ”€β”€ VM-App (Ubuntu + NGINX)
β”‚ └── Internal web server on port 80
└── VM-Client (Ubuntu + DNS tools)
└── DNS resolution testing

Platform Outputs

The deployment provides these values for your use:

  • vmAppPrivateIp - Private IP of the app server
  • vmClientPrivateIp - Private IP of the client VM
  • vmAppPublicIp - Public IP for SSH access (if enabled)
  • vmClientPublicIp - Public IP for SSH access (if enabled)
  • vmAppName - Application VM hostname
  • vmClientName - Client VM hostname

πŸš€ Lab Exercises

Task 1: Create a Private DNS Zone

Create a private DNS zone named corp.local for internal name resolution.

Terminal window
# Set variables (replace with your actual values)
RG="rg-privdns-lab"
ZONE="corp.local"
# Create the private DNS zone
az network private-dns zone create \
--resource-group "$RG" \
--name "$ZONE"

Verification

Terminal window
# List private DNS zones to confirm creation
az network private-dns zone list \
--resource-group "$RG" \
--output table

πŸ’‘ Key Learning: Private DNS zones are not resolvable from the internetβ€”they only work within linked virtual networks.


Link the private DNS zone to your VNet and enable auto-registration for VM hostnames.

Terminal window
VNET_NAME="privdns-lab-vnet"
LINK_NAME="corp-local-link"
SUB_ID="<your-subscription-id>"
# Create VNet link with auto-registration enabled
az network private-dns link vnet create \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$LINK_NAME" \
--virtual-network "/subscriptions/$SUB_ID/resourceGroups/$RG/providers/Microsoft.Network/virtualNetworks/$VNET_NAME" \
--registration-enabled true

Auto-Registration Check

After approximately 1-2 minutes, verify that VM hostnames are automatically registered:

Terminal window
# List all A records in the zone
az network private-dns record-set a list \
--resource-group "$RG" \
--zone-name "$ZONE" \
--output table

Expected Result: You should see A records for your VMs (e.g., privdns-lab-vm-app.corp.local)

πŸ” What Happened: Auto-registration automatically creates DNS records for VMs in the linked VNet.


Task 3: Add Custom DNS Records

Create user-friendly DNS records for easier application access.

Create A Record for Application

Terminal window
APP_NAME="app"
APP_IP="<vmAppPrivateIp>" # Use the value from deployment outputs
# Create A record: app.corp.local -> VM-App private IP
az network private-dns record-set a add-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$APP_NAME" \
--ipv4-address "$APP_IP"

Create CNAME Alias

Terminal window
WWW_NAME="www"
# Create CNAME record: www.corp.local -> app.corp.local
az network private-dns record-set cname set-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$WWW_NAME" \
--cname "${APP_NAME}.${ZONE}"

Verify Record Creation

Terminal window
# List A records
az network private-dns record-set a show \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$APP_NAME"
# List CNAME records
az network private-dns record-set cname show \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$WWW_NAME"

Task 4: Validate DNS Resolution

Test DNS resolution and connectivity from the client VM.

Connect to Client VM

Terminal window
# SSH to client VM (use appropriate method based on your setup)
ssh azureuser@<vmClientPublicIp>
# If no public IP is available, use Azure Bastion from the portal

Test DNS Resolution

Terminal window
# Test A record resolution
nslookup app.corp.local
# Test CNAME resolution
nslookup www.corp.local
# Alternative using dig (more detailed output)
dig +short app.corp.local
dig +short www.corp.local

Expected Results:

  • app.corp.local β†’ resolves to VM-App’s private IP
  • www.corp.local β†’ resolves to app.corp.local (CNAME)

Test HTTP Connectivity

Terminal window
# Test application access via custom DNS names
curl -s http://app.corp.local | head -n 10
curl -s http://www.corp.local | head -n 10
# Test with verbose output for troubleshooting
curl -v http://app.corp.local

Expected Result: You should see the β€œWelcome to the Internal App” HTML content from NGINX.


Task 5: Troubleshooting Exercise

Practice diagnosing and fixing common DNS issues.

Simulate the Problem:

Terminal window
# Disable auto-registration
az network private-dns link vnet update \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$LINK_NAME" \
--registration-enabled false
# OR completely remove the VNet link
az network private-dns link vnet delete \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$LINK_NAME" \
--yes

Test the Impact:

Terminal window
# From Client VM - these should fail
nslookup app.corp.local
curl http://app.corp.local

Expected Symptoms:

  • DNS resolution fails
  • curl returns β€œcould not resolve host” error

Fix the Issue:

Terminal window
# Recreate the VNet link with auto-registration
az network private-dns link vnet create \
--resource-group "$RG" \
--zone-name "$ZONE" \
--name "$LINK_NAME" \
--virtual-network "/subscriptions/$SUB_ID/resourceGroups/$RG/providers/Microsoft.Network/virtualNetworks/$VNET_NAME" \
--registration-enabled true

Scenario B: Incorrect A Record

Simulate the Problem:

Terminal window
# Remove correct A record
az network private-dns record-set a remove-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$APP_NAME" \
--ipv4-address "$APP_IP"
# Add incorrect A record
az network private-dns record-set a add-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$APP_NAME" \
--ipv4-address "10.10.10.10"

Test the Impact:

Terminal window
# From Client VM
nslookup app.corp.local # This resolves to wrong IP
curl http://app.corp.local # This times out or fails

Expected Symptoms:

  • DNS resolves to incorrect IP address
  • HTTP connection times out or gets β€œconnection refused”

Fix the Issue:

Terminal window
# Remove incorrect record
az network private-dns record-set a remove-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$APP_NAME" \
--ipv4-address "10.10.10.10"
# Add correct record back
az network private-dns record-set a add-record \
--resource-group "$RG" \
--zone-name "$ZONE" \
--record-set-name "$APP_NAME" \
--ipv4-address "$APP_IP"

πŸ”§ Common Troubleshooting

DNS Resolution Issues

IssuePossible CauseSolution
nslookup fails completelyVNet not linked to DNS zoneCreate or fix VNet link
Resolves to wrong IPIncorrect A recordUpdate A record with correct IP
CNAME doesn’t resolveTarget record missingVerify target A record exists
Intermittent failuresDNS cachingWait 30-60 seconds or flush DNS cache

Connectivity Issues

IssuePossible CauseSolution
DNS works, HTTP failsApplication not runningCheck NGINX status on VM-App
Connection timeoutFirewall blocking trafficVerify NSG rules allow port 80
Wrong content returnedResolving to wrong serverVerify A record points to correct IP

πŸ§ͺ Additional Experiments

Try these optional exercises to deepen your understanding:

  1. Multiple Zones: Create additional DNS zones (e.g., dev.local, test.local)
  2. Record Types: Experiment with other record types (TXT, MX, SRV)
  3. Conditional Forwarding: Set up forwarding to external DNS servers
  4. Cross-VNet Resolution: Link multiple VNets to the same DNS zone

πŸŽ“ Key Takeaways

After completing this lab, you should understand:

  • Private DNS Zones provide internal name resolution within Azure VNets
  • VNet linking is required for DNS resolution to work
  • Auto-registration automatically creates records for VMs
  • Custom records (A, CNAME) provide user-friendly application access
  • Troubleshooting DNS involves checking both resolution and connectivity
  • Private DNS is isolated from internet DNS for security

πŸ“š Additional Resources