Skip to main content

Challenge 05: Azure DNS Private Resolver

Estimated time and cost

90-120 minutes | ~$0.18/hour per endpoint | Exam weight: 15-20%

Scenario

Contoso has a hybrid environment with on-premises DNS servers (Active Directory DNS at 10.1.0.4 and 10.1.0.5) and Azure workloads using Azure Private DNS zones. Currently, conditional forwarders on the on-prem DNS servers point to a pair of IaaS DNS forwarder VMs in the hub VNet. The team wants to eliminate these VMs and replace them with Azure DNS Private Resolver for bidirectional DNS resolution between on-premises and Azure.

The architecture requires:

  • On-premises clients resolving Azure Private DNS zone records (such as db.contoso.internal linked to a private endpoint) via the inbound endpoint
  • Azure workloads in spoke VNets resolving on-premises Active Directory domains (such as corp.contoso.com) via the outbound endpoint and forwarding rules

Learning objectives

After completing this challenge you will be able to:

  • Deploy an Azure DNS Private Resolver in a hub virtual network
  • Configure an inbound endpoint for on-premises to Azure DNS resolution
  • Configure an outbound endpoint for Azure to on-premises DNS resolution
  • Create DNS forwarding rulesets and rules targeting on-premises DNS servers
  • Link forwarding rulesets to spoke virtual networks
  • Validate bidirectional hybrid DNS resolution

Prerequisites

  • An Azure subscription with Contributor access
  • Azure CLI installed and authenticated (az login)
  • The dns-resolver CLI extension (auto-installs on first use, requires CLI version 2.75.0+)
  • A resource group and hub VNet (or permission to create them)
  • Understanding of Azure Private DNS zones and hybrid DNS concepts
  • (Optional) On-premises DNS servers reachable via ExpressRoute or VPN for end-to-end testing

Task 1: Create the hub VNet with dedicated resolver subnets

The DNS Private Resolver requires two dedicated subnets (one for inbound, one for outbound), each with a minimum size of /28 and delegated to Microsoft.Network/dnsResolvers.

Step 1: Create the resource group

az group create \
--name rg-dns-resolver-lab \
--location eastus2

Step 2: Create the hub virtual network

az network vnet create \
--resource-group rg-dns-resolver-lab \
--name vnet-hub \
--address-prefixes 10.0.0.0/16 \
--location eastus2

Step 3: Create the inbound endpoint subnet with delegation

az network vnet subnet create \
--resource-group rg-dns-resolver-lab \
--vnet-name vnet-hub \
--name snet-dns-inbound \
--address-prefixes 10.0.0.0/28 \
--delegations Microsoft.Network/dnsResolvers

Step 4: Create the outbound endpoint subnet with delegation

az network vnet subnet create \
--resource-group rg-dns-resolver-lab \
--vnet-name vnet-hub \
--name snet-dns-outbound \
--address-prefixes 10.0.0.16/28 \
--delegations Microsoft.Network/dnsResolvers
Exam note

Both subnets must be delegated to Microsoft.Network/dnsResolvers. You cannot use the same subnet for both inbound and outbound endpoints. The minimum subnet size is /28 (16 addresses). No other resources can reside in these delegated subnets.

Step 5: Create a spoke VNet (for later ruleset linking)

az network vnet create \
--resource-group rg-dns-resolver-lab \
--name vnet-spoke-01 \
--address-prefixes 10.1.0.0/16 \
--subnet-name snet-workload \
--subnet-prefixes 10.1.1.0/24 \
--location eastus2

Task 2: Deploy the Azure DNS Private Resolver

Create the DNS Private Resolver resource in the hub VNet.

Step 1: Create the DNS Private Resolver

az dns-resolver create \
--name dnspr-hub-eastus2 \
--resource-group rg-dns-resolver-lab \
--location eastus2 \
--id "/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-hub"

The --id parameter specifies the virtual network resource ID where the resolver will be deployed.

note

Replace <subscription-id> with your actual Azure subscription ID. You can retrieve it with az account show --query id --output tsv.

Step 2: Verify the resolver was created

az dns-resolver show \
--name dnspr-hub-eastus2 \
--resource-group rg-dns-resolver-lab \
--output table
![Challenge 05 - Network Topology](/img/az-700/challenge-05-topology.svg)


The `--ip-configurations` parameter accepts a JSON array specifying the subnet and IP allocation method. Use `Dynamic` to let Azure assign an available IP from the subnet, or `Static` with a `private-ip-address` field to pin a specific address.

### Step 2: Retrieve the assigned IP address

```bash
az dns-resolver inbound-endpoint show \
--dns-resolver-name dnspr-hub-eastus2 \
--name ie-inbound \
--resource-group rg-dns-resolver-lab \
--query "ipConfigurations[0].privateIpAddress" \
--output tsv

Record this IP address (for example, 10.0.0.4). This is the address that on-premises conditional forwarders must target instead of the old IaaS forwarder VMs.

Step 3: (Optional) Create with a static IP

If you need a predictable IP address for firewall rules or DNS configuration:

az dns-resolver inbound-endpoint create \
--dns-resolver-name dnspr-hub-eastus2 \
--name ie-inbound-static \
--resource-group rg-dns-resolver-lab \
--location eastus2 \
--ip-configurations "[{private-ip-address:10.0.0.10,private-ip-allocation-method:Static,id:/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-hub/subnets/snet-dns-inbound}]"
Exam note

The inbound endpoint IP is what you configure on your on-premises DNS servers as the conditional forwarder target for Azure Private DNS zones. After deployment, update your on-prem DNS conditional forwarders to point to this IP instead of the legacy IaaS forwarder VMs.


Task 4: Configure the outbound endpoint

The outbound endpoint allows the resolver to forward queries from Azure VNets to external DNS servers (such as on-premises Active Directory DNS).

Step 1: Create the outbound endpoint

az dns-resolver outbound-endpoint create \
--dns-resolver-name dnspr-hub-eastus2 \
--name oe-outbound \
--resource-group rg-dns-resolver-lab \
--location eastus2 \
--id "/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-hub/subnets/snet-dns-outbound"

The --id parameter for the outbound endpoint specifies the subnet resource ID (not the VNet ID as with the resolver itself).

Step 2: Verify the outbound endpoint

az dns-resolver outbound-endpoint show \
--dns-resolver-name dnspr-hub-eastus2 \
--name oe-outbound \
--resource-group rg-dns-resolver-lab \
--output table
Important

The outbound endpoint subnet must have network connectivity to the target DNS servers. If the on-premises DNS servers are reachable via ExpressRoute or site-to-site VPN, ensure the route table and network security groups on the outbound subnet permit UDP/TCP port 53 traffic to those servers.


Task 5: Create a DNS forwarding ruleset and rules

A forwarding ruleset contains rules that define which domain queries are forwarded to which target DNS servers. The ruleset is associated with one or more outbound endpoints.

Step 1: Create the forwarding ruleset

az dns-resolver forwarding-ruleset create \
--name frs-contoso-onprem \
--resource-group rg-dns-resolver-lab \
--location eastus2 \
--outbound-endpoints "[{id:/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/dnsResolvers/dnspr-hub-eastus2/outboundEndpoints/oe-outbound}]"

The --outbound-endpoints parameter accepts a JSON array of outbound endpoint resource IDs. You can reference multiple outbound endpoints for redundancy.

Step 2: Create a forwarding rule for the on-premises AD domain

az dns-resolver forwarding-rule create \
--ruleset-name frs-contoso-onprem \
--name rule-corp-contoso \
--resource-group rg-dns-resolver-lab \
--domain-name "corp.contoso.com." \
--forwarding-rule-state "Enabled" \
--target-dns-servers "[{ip-address:10.1.0.4,port:53},{ip-address:10.1.0.5,port:53}]"

Step 3: Create a forwarding rule for reverse DNS (PTR records)

For on-premises reverse lookups (useful when Azure VMs need to resolve PTR records for on-prem IPs):

az dns-resolver forwarding-rule create \
--ruleset-name frs-contoso-onprem \
--name rule-reverse-10 \
--resource-group rg-dns-resolver-lab \
--domain-name "1.10.in-addr.arpa." \
--forwarding-rule-state "Enabled" \
--target-dns-servers "[{ip-address:10.1.0.4,port:53},{ip-address:10.1.0.5,port:53}]"

Step 4: Verify the rules

az dns-resolver forwarding-rule list \
--ruleset-name frs-contoso-onprem \
--resource-group rg-dns-resolver-lab \
--output table
Exam note

The domain name in a forwarding rule must end with a trailing dot (e.g., corp.contoso.com.). This is standard DNS notation indicating a fully qualified domain name. The rule matches all queries for the specified domain and its subdomains. Target DNS servers are specified as an array of IP address and port pairs.


Linking a ruleset to a VNet enables all DNS queries originating from that VNet to be evaluated against the forwarding rules. Without this link, Azure workloads in the spoke VNet will use default Azure DNS resolution and cannot reach on-premises resources by name.

az dns-resolver vnet-link create \
--ruleset-name frs-contoso-onprem \
--name vnetlink-spoke-01 \
--resource-group rg-dns-resolver-lab \
--id "/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-spoke-01"

The --id parameter specifies the virtual network resource ID to link.

az dns-resolver vnet-link create \
--ruleset-name frs-contoso-onprem \
--name vnetlink-hub \
--resource-group rg-dns-resolver-lab \
--id "/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-hub"
az dns-resolver vnet-link list \
--ruleset-name frs-contoso-onprem \
--resource-group rg-dns-resolver-lab \
--output table
Important

A virtual network can be linked to a maximum of two DNS forwarding rulesets. If more rulesets need to apply, consolidate rules into fewer rulesets. A ruleset can be linked to up to 500 virtual networks.


Task 7: Verify end-to-end resolution

Azure to on-premises (outbound path)

From an Azure VM in the spoke VNet, verify that queries for on-premises domains are forwarded correctly:

# From an Azure VM in vnet-spoke-01
nslookup dc01.corp.contoso.com

Expected result: resolves to the on-premises domain controller IP (e.g., 10.1.0.4).

The resolution path is: Azure VM -> Azure DNS (168.63.129.16) -> forwarding ruleset matches corp.contoso.com. -> outbound endpoint forwards to 10.1.0.4:53 and 10.1.0.5:53.

On-premises to Azure (inbound path)

From an on-premises server (after updating conditional forwarders to the inbound endpoint IP):

# From an on-premises server
nslookup db.contoso.internal 10.0.0.4

Expected result: resolves to the private endpoint IP linked to the Azure Private DNS zone.

The resolution path is: on-prem DNS server -> conditional forwarder -> inbound endpoint (10.0.0.4) -> Azure DNS resolves the Private DNS zone record.

Verify using dig (Linux)

# Test outbound forwarding from Azure VM
dig dc01.corp.contoso.com

# Test inbound resolution from on-prem (specifying the inbound endpoint IP)
dig @10.0.0.4 db.contoso.internal

Break & fix

Scenario 1: Inbound endpoint subnet without proper delegation

Symptom: Deploying the inbound endpoint fails with an error stating the subnet is not delegated correctly.

(SubnetMissingDelegation) The subnet 'snet-dns-inbound' must have a delegation
to 'Microsoft.Network/dnsResolvers' to be used by a DNS resolver.

Root cause: The subnet was created without the --delegations Microsoft.Network/dnsResolvers parameter. The DNS Private Resolver service requires this delegation to inject its endpoint resources into the subnet.

Fix: Update the subnet to add the delegation:

az network vnet subnet update \
--resource-group rg-dns-resolver-lab \
--vnet-name vnet-hub \
--name snet-dns-inbound \
--delegations Microsoft.Network/dnsResolvers

Scenario 2: Forwarding rule with wrong target DNS server IP

Symptom: Azure VMs in the spoke VNet cannot resolve dc01.corp.contoso.com. Queries time out rather than returning NXDOMAIN.

Root cause: The target DNS server IP in the forwarding rule is incorrect (for example, 10.1.0.100 instead of 10.1.0.4). The outbound endpoint attempts to reach a server that either does not exist or is not running DNS.

Fix: Update the forwarding rule with the correct target:

az dns-resolver forwarding-rule update \
--ruleset-name frs-contoso-onprem \
--name rule-corp-contoso \
--resource-group rg-dns-resolver-lab \
--target-dns-servers "[{ip-address:10.1.0.4,port:53},{ip-address:10.1.0.5,port:53}]"

Also verify that NSGs on the outbound subnet allow outbound UDP/TCP 53 to the target IP range.

Scenario 3: Ruleset not linked to spoke VNet

Symptom: Azure VMs in vnet-spoke-01 can resolve public DNS and Azure Private DNS zones, but queries for corp.contoso.com return NXDOMAIN from the Azure recursive resolver.

Root cause: The forwarding ruleset exists and contains the correct rule, but was never linked to the spoke VNet. Without the VNet link, DNS queries from that VNet are not evaluated against the forwarding rules.

Fix: Create the missing VNet link:

az dns-resolver vnet-link create \
--ruleset-name frs-contoso-onprem \
--name vnetlink-spoke-01 \
--resource-group rg-dns-resolver-lab \
--id "/subscriptions/<subscription-id>/resourceGroups/rg-dns-resolver-lab/providers/Microsoft.Network/virtualNetworks/vnet-spoke-01"

After linking, queries for corp.contoso.com from the spoke VNet will match the forwarding rule and be sent to the on-premises DNS servers.


Clean up resources

az group delete --name rg-dns-resolver-lab --yes --no-wait

Key concepts summary

ConceptDetail
DNS Private ResolverManaged service replacing IaaS DNS forwarder VMs for hybrid DNS
Inbound endpointProvides a private IP for on-prem DNS to forward queries into Azure
Outbound endpointEnables Azure DNS to forward queries to external (on-prem) DNS servers
Forwarding rulesetCollection of domain-based rules defining where queries are forwarded
Forwarding ruleMatches a domain suffix and specifies target DNS servers (IP + port)
VNet linkAssociates a forwarding ruleset with a VNet to activate rule evaluation
Subnet delegationRequired on both endpoint subnets; Microsoft.Network/dnsResolvers
Minimum subnet size/28 (16 addresses); dedicated, no other resources allowed
Maximum rulesets per VNet2 forwarding rulesets can be linked to a single VNet
Domain name formatMust end with a trailing dot (e.g., contoso.com.)

Knowledge check

1. What is the minimum subnet size required for an Azure DNS Private Resolver endpoint?

2. On-premises clients need to resolve records in an Azure Private DNS zone. Which DNS Private Resolver component provides the IP address that on-prem conditional forwarders should target?

3. Azure VMs in a spoke VNet cannot resolve on-premises Active Directory domain names. The forwarding ruleset and rule are correctly configured. What is the most likely missing step?

4. Which parameter format is correct for specifying target DNS servers in an 'az dns-resolver forwarding-rule create' command?

5. What is the maximum number of DNS forwarding rulesets that can be linked to a single virtual network?

6. Contoso wants to replace their IaaS DNS forwarder VMs in Azure with a managed solution. After deploying the DNS Private Resolver with an inbound endpoint, what must be updated on the on-premises DNS infrastructure?


Additional resources