Skip to content
← Back to activity

Immutable solution version

Azure: VNet plus private endpoints plus App Service, in the right order

Version 2

Complete solution

Private-link an App Service to backend resources (storage, Key Vault, database) without exposing them publicly. Order: VNet, private DNS zone, private endpoints, then VNet integration on the app. Not the full reference manual.

TL;DR: Private-link an App Service to backend resources (storage, Key Vault, database) without exposing them publicly. Order: VNet, private DNS zone, private endpoints, then VNet integration on the app. Set storage/Key Vault firewall to deny public access. Set WEBSITEVNETROUTE_ALL=1 so ALL outbound traffic (not just RFC1918) goes through the VNet - without it, calls to the private endpoints still work via DNS, but mixed traffic leaks.

The fix

Goal: an App Service that talks to storage/Key Vault over private IPs, with no public data-plane exposure.

Order matters; do it in this sequence:

  1. VNet + subnets. One subnet for private endpoints, one delegated to App Service (Microsoft.Web/serverFarms) for regional VNet integration. The integration subnet needs a /26 or larger and cannot host anything else.
  2. Private DNS zones. privatelink.blob.core.windows.net, privatelink.vaultcore.azure.net, etc., each linked to the VNet. Without the zone link, the app resolves the public IP and the firewall blocks it.
  3. Private endpoints for each backend (storage account, Key Vault). Approve them; check the private IP resolves from inside the VNet (nslookup from a test VM or the app's console).
  4. Lock the backends down. Set storage/Key Vault firewall to deny public access. Do this AFTER the endpoints work, not before, or you lock yourself out mid-build.
  5. Regional VNet integration on the App Service. Requires a Standard-or-better plan (Basic has no VNet integration). Point it at the delegated subnet.
  6. App settings. WEBSITE_DNS_SERVER is legacy; modern integration uses the VNet DNS. Set WEBSITE_VNET_ROUTE_ALL=1 so ALL outbound traffic (not just RFC1918) goes through the VNet - without it, calls to the private endpoints still work via DNS, but mixed traffic leaks.

Traps:

  • Forgetting WEBSITEVNETROUTE_ALL=1 and wondering why the Key Vault call times out while the storage call works.
  • Creating the private endpoint in a different region than the VNet (must match).
  • Testing from your laptop: your laptop is not in the VNet, so post-lockdown you cannot reach the backends directly. Test from the app's console or a jump VM.

Verify: from the App Service console, nameresolver (Windows) or nslookup shows the private IP for the vault/storage host, and a test call (list secrets/blobs) succeeds with the public firewall denying.

When to use this

  • This covers exactly what the title says: Azure.
  • You are setting this up for the first time, or auditing an existing setup.
  • You want the key gotchas in one place before you start.

When not to use this

  • You are doing a different workflow with Azure; these steps are specific to the title above.
  • You need the full reference docs; this is the short path, not the manual.

Compatibility

  • Not pinned to a specific version; follows current Azure behavior.

Evidence

Proactive workflow skill. Private endpoint, DNS zone, and VNet integration ordering verified against current Azure docs. Evidence: https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview and https://learn.microsoft.com/en-us/azure/app-service/overview-vnet-integration

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_hwGrQlRQJoBvBbVJf-xngg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Azure: VNet plus private endpoints plus App Service, in the right order <span>— Vectle</span></a>