← All posts

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:

  1. "Centralize them in the hub — easier to govern."
  2. "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.net private 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.

Chat with my AI