Private Endpoints in Hub-and-Spoke: Per-Spoke or Centralized?
Where you put the private endpoint determines who can reach the PaaS service. There's a Microsoft-recommended pattern, and it's not "all in the hub."
Two competing instincts when adding private endpoints to a hub-spoke:
- "Centralize them in the hub — easier to govern."
- "Put them in the spoke — closer to the workload."
The Microsoft Architecture Center reference for Private Link in hub-spoke gives a clear rule of thumb:
Per-spoke for app-specific PaaS
If a database or storage account belongs to one workload (one spoke),
the private endpoint lives in that spoke's snet-pe subnet. The
workload reaches it directly. The hub doesn't know or care.
Hub-centralized for shared services
Things every spoke uses — central Key Vault, central log collection storage, shared image registry — get private endpoints in the hub, with the private DNS zone linked to all spoke VNets.
Subnet sizing
A common mistake: under-sizing snet-pe. Each PE consumes one
NIC IP. Plan for /27 minimum even for a small spoke; PE sprawl
sneaks up on you.
Don't forget the DNS plumbing
The private endpoint by itself doesn't help anyone resolve. You also need:
- The
privatelink.<service>.azure.netprivate DNS zone (created once). - A VNet link from that zone to every VNet that needs to resolve.
- The PE's DNS zone group attaching it to the zone.
Missing any one of those three and your app gets the public IP back — which silently bypasses your private endpoint at the network layer. The firewall logs will tell you eventually. Save yourself the trouble.