Private endpoints and private DNS

Microsoft Azure · Advanced · 15 min

Private endpoints are the standard way to take databases, storage and vaults off the public internet.

By default, PaaS services such as Storage, SQL, Key Vault and Cosmos DB have public endpoints. A private endpoint places a network interface with a private IP from your subnet that maps to one specific resource (and sub-resource, such as blob or vault). Traffic from your VNet, peered VNets and connected on-premises networks then stays on the Microsoft backbone, and you can set public network access: disabled on the service.

The hard part is DNS. Clients still use the public name, stordersprod01.blob.core.windows.net. Azure answers with a CNAME to stordersprod01.privatelink.blob.core.windows.net; if that privatelink zone resolves to the private IP for your clients, everything works without code changes. So you:

  • create a Private DNS zone per service (privatelink.blob.core.windows.net, privatelink.vaultcore.azure.net, privatelink.database.windows.net),
  • link it to the VNets that resolve names (in hub-spoke, centrally in the hub),
  • attach a DNS zone group to the endpoint so the A record is managed automatically,
  • for on-premises clients, forward those zones through Azure DNS Private Resolver.

Service endpoints are the older, simpler alternative: traffic leaves from the subnet's identity but the service keeps a public IP. Private endpoints work across peering and VPN and block data exfiltration to other accounts, so they are the default for sensitive data.

Example

SA_ID=$(az storage account show -g rg-data -n stordersprod01 --query id -o tsv)

az network private-endpoint create -g rg-net -n pe-st-blob \
  --vnet-name vnet-app --subnet snet-pe \
  --private-connection-resource-id "$SA_ID" --group-id blob \
  --connection-name st-blob

az network private-dns zone create -g rg-net -n privatelink.blob.core.windows.net
az network private-dns link vnet create -g rg-net -n link-app \
  --zone-name privatelink.blob.core.windows.net --virtual-network vnet-app \
  --registration-enabled false
az network private-endpoint dns-zone-group create -g rg-net \
  --endpoint-name pe-st-blob -n default \
  --private-dns-zone privatelink.blob.core.windows.net --zone-name blob

az storage account update -g rg-data -n stordersprod01 --public-network-access Disabled
# From a VM in vnet-app: nslookup stordersprod01.blob.core.windows.net -> 10.10.4.5

Remember

  • A private endpoint is a NIC with a private IP for one resource
  • Clients keep the public FQDN; DNS must resolve it to the private IP
  • One privatelink DNS zone per service, linked to the resolving VNets
  • Disable public network access once private paths work

Watch out for

  • Creating the endpoint but no private DNS zone link, so clients still resolve the public IP and get blocked.

Check yourself

  1. After adding a private endpoint and disabling public access, a VM in a peered VNet gets 403 because the name resolves to a public IP. What is the likely fix?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview