Book 01 — Azure Networking Deep Dive
Private Link and Private Endpoints
Private Link is the mechanism by which Azure PaaS services — and custom services you publish — are consumed from VNets with private IP addresses rather than public endpoints. Understanding Private Endpoints is essential for any architecture that uses managed PaaS services and has a requirement to prevent data from traversing the public internet.
Service Endpoint vs Private Endpoint
Both mechanisms route PaaS traffic over the Microsoft backbone, but their network models differ fundamentally:
| Aspect | Service Endpoint | Private Endpoint |
|---|---|---|
| IP address | PaaS retains public IP | PaaS gets private IP in your VNet |
| DNS change | Not required | Required (privatelink FQDN) |
| NSG filtering | Not supported on SE traffic | Supported (with policy enabled) |
| Cross-region | Not supported | Yes (GA 2024) |
| Cost | Free | Per-hour + data processing |
| Granularity | Entire service type | Specific resource instance |
Tip
Use Private Endpoints for any workload where data security, compliance, or network isolation is a requirement. Service Endpoints are simpler but do not truly isolate the PaaS resource — the storage account still listens on a public IP, and other consumers on the same subnet can reach any storage account globally unless you configure a firewall rule.
Private Endpoint Anatomy
NIC and Subnet
A Private Endpoint allocates a NIC in your VNet subnet with a static private IP. This NIC is the target IP that your VMs connect to. The NIC is linked to a specific PaaS resource and sub-resource type via a Private Link connection.
The subnet hosting the PE must have PrivateEndpointNetworkPolicies set appropriately. Prior to 2023, this had to be Disabled for PE creation. Since 2023, NSG enforcement on PE subnets is supported by setting the value to NetworkSecurityGroupEnabled or Enabled.
# Enable NSG enforcement on PE subnet (allows NSG rules to filter PE traffic)
az network vnet subnet update \
--name snet-pe --resource-group rg-hub \
--vnet-name vnet-hub-001 \
--private-endpoint-network-policies NetworkSecurityGroupEnabled
Private DNS Zone Integration
DNS Resolution Flow
When a VM resolves a PaaS FQDN like sacorpdata.blob.core.windows.net, the resolution chain works as follows:
- VM queries its configured DNS (Azure DNS at 168.63.129.16)
- Azure DNS returns a CNAME:
sacorpdata.privatelink.blob.core.windows.net - The Private DNS Zone
privatelink.blob.core.windows.net(linked to VNet) resolves this to the PE's private IP - VM connects to the private IP — traffic stays inside the VNet
# Create Private DNS Zone, link to VNet, attach privateDnsZoneGroup to PE
az network private-dns zone create \
--resource-group rg-hub \
--name "privatelink.blob.core.windows.net"
az network private-dns link vnet create \
--resource-group rg-hub \
--zone-name "privatelink.blob.core.windows.net" \
--name lnk-hub-vnet \
--virtual-network vnet-hub-001 \
--registration-enabled false
az network private-endpoint dns-zone-group create \
--resource-group rg-hub \
--endpoint-name pe-sa-corp-blob \
--name zonegroup-blob \
--private-dns-zone "privatelink.blob.core.windows.net" \
--zone-name blob
Private Link Service
Private Link Service lets you expose an ILB-fronted service to consumers in other VNets or subscriptions without peering. The consumer creates a Private Endpoint pointing to your PLS alias. Traffic flows through NAT IP addresses assigned from a dedicated subnet.
Note
Private Link Service requires a subnet dedicated to NAT IPs (--private-link-service-network-policies Disabled on the PLS subnet). The PLS subnet provides NAT IPs for the connection; you need one NAT IP per 8 simultaneous connections. Plan /28 or larger for PLS subnets.
Lab: Storage Account Private Endpoint
Deploy Storage Private Endpoint with DNS Integration (CE-18)
# CE-18: Private Endpoint with DNS Zone for storage blob
RG="rg-lab-ch07"; LOC="eastus2"
az group create --name "$RG" --location "$LOC"
az network vnet create --name vnet-lab --resource-group "$RG" \
--address-prefixes 10.0.0.0/24 --subnet-name snet-vms \
--subnet-prefixes 10.0.0.0/27 --location "$LOC"
az network vnet subnet create --name snet-pe \
--resource-group "$RG" --vnet-name vnet-lab \
--address-prefix 10.0.0.32/28
az network vnet subnet update --name snet-pe \
--resource-group "$RG" --vnet-name vnet-lab \
--private-endpoint-network-policies Disabled
SA_NAME="salabch07$RANDOM"
az storage account create --name "$SA_NAME" \
--resource-group "$RG" --location "$LOC" \
--sku Standard_LRS --public-network-access Disabled
SA_ID=$(az storage account show --name "$SA_NAME" -g "$RG" --query id -o tsv)
az network private-endpoint create \
--name pe-sa-blob --resource-group "$RG" \
--vnet-name vnet-lab --subnet snet-pe \
--private-connection-resource-id "$SA_ID" \
--group-id blob --connection-name conn-sa-blob
az network private-dns zone create --resource-group "$RG" \
--name "privatelink.blob.core.windows.net"
az network private-dns link vnet create \
--resource-group "$RG" \
--zone-name "privatelink.blob.core.windows.net" \
--name lnk-vnet --virtual-network vnet-lab \
--registration-enabled false
az network private-endpoint dns-zone-group create \
--resource-group "$RG" --endpoint-name pe-sa-blob \
--name zg-blob \
--private-dns-zone "privatelink.blob.core.windows.net" \
--zone-name blob
# Verify A record was auto-created
az network private-dns record-set a list \
--resource-group "$RG" \
--zone-name "privatelink.blob.core.windows.net" \
--output table
az group delete --name "$RG" --yes --no-wait
Summary
| Concept | Key Fact |
|---|---|
| PE vs SE | PE assigns private IP; SE keeps public IP with backbone routing |
| Subnet policy | PrivateEndpointNetworkPolicies: Disabled (legacy); or NSGEnabled for NSG enforcement |
| privateDnsZoneGroup | Auto-registers/removes A record in Private DNS Zone |
| DNS zone link | Must link Private DNS Zone to VNet for VMs to resolve private IP |
| group-id | Sub-resource: blob, sqlServer, vault, sites |
| Private Link Service | Expose ILB-fronted service; uses PLS subnet NAT IPs |
| Cross-region PE | GA 2024; PE in one region, PaaS in another via backbone |
Chapter 8 covers Application Delivery — Azure Load Balancer (L4) and Application Gateway (L7 with WAF), including URL path routing and SSL offload.
Chapter: 7 of 12 | Status: v0.1 Draft |