The order that avoids outages
- DNS architecture
- Private endpoints added (public access still on)
- Clients moved to private paths and verified
- Public network access disabled
- Policy to keep it that way
Teams that start with step 4 cause the outage this plan is meant to avoid.
1. DNS first
- Create the
privatelink.*zones you need (one per service type:privatelink.blob.core.windows.net,privatelink.database.windows.net,privatelink.vaultcore.azure.net, …) in a central resource group. - Link them to the hub VNet where your DNS resolver lives and to any VNet that uses Azure-provided DNS.
- On-premises: conditional forwarders for the public zone names (
blob.core.windows.netetc.) to an Azure DNS Private Resolver inbound endpoint.
az network private-dns zone create -g rg-dns -n privatelink.blob.core.windows.net
az network private-dns link vnet create -g rg-dns -z privatelink.blob.core.windows.net -n link-hub \
--virtual-network <hub-vnet-id> --registration-enabled false
2. Add private endpoints
az network private-endpoint create -g rg-data -n pe-stdata-blob \
--vnet-name vnet-spoke-data --subnet snet-pe \
--private-connection-resource-id <storage-account-id> --group-id blob \
--connection-name stdata-blob
az network private-endpoint dns-zone-group create -g rg-data --endpoint-name pe-stdata-blob \
-n default --private-dns-zone privatelink.blob.core.windows.net --zone-name blob
Public access is still on, so nothing breaks yet. Clients that resolve the private IP start using it immediately.
3. Move and verify clients
From each client network, check resolution returns the private IP:
nslookup stdata.blob.core.windows.net
| Client | What to do |
|---|---|
| App Service / Functions | VNet integration, and WEBSITE_VNET_ROUTE_ALL / route-all enabled |
| AKS, VMs in peered spokes | Hub DNS resolver or zone links |
| On-premises | Conditional forwarders to the resolver |
| Developers' laptops over the internet | VPN / point-to-site, or keep a tightly restricted public path |
| Azure services (ADF, Synapse, Fabric) | Managed private endpoints or trusted-services exceptions |
Watch the service logs: requests should now come from private IPs.
StorageBlobLogs
| where TimeGenerated > ago(1d)
| summarize count() by CallerIpAddress
4. Disable public access
az storage account update -g rg-data -n stdata --public-network-access Disabled
az sql server update -g rg-sql -n sql-prod --enable-public-network false
az keyvault update -n kv-prod --public-network-access Disabled
Do one service at a time, during business hours with the owners watching.
Warning
Check managed services that reach your resources from Microsoft networks (backup, Defender scans, Azure Monitor, Power BI). Some need a trusted-services exception or their own private endpoints.
5. Enforce
Assign Azure Policy definitions that deny public network access for each service type, and DeployIfNotExists policies that create DNS zone groups for new private endpoints.
Checklist
- Central private DNS zones linked; on-prem forwarding works
- Endpoints and DNS zone groups for each resource
- Logs show clients on private IPs only
- Public network access disabled per resource
- Deny policies assigned