The three models
| Model | How it works | Exposure |
|---|---|---|
| Public endpoint + firewall rules | Service stays on its public IP; allow-list IP ranges / trusted services | Public IP reachable; access limited by rules and auth |
| Service endpoints | Traffic from selected subnets reaches the service's public endpoint over the Azure backbone with subnet identity; service firewall allows those subnets | Still the public endpoint, but only listed subnets (plus allowed IPs) get in |
| Private endpoints (Private Link) | A private IP in your VNet maps to one resource; public access can be disabled | No public access; reachable from VNets, peered VNets and on-prem via private routing |
Comparison
| Public + rules | Service endpoints | Private endpoints | |
|---|---|---|---|
| Public network access disabled | No | No | Yes |
| Reach from on-premises privately | No | No | Yes (via VPN/ER + DNS) |
| Scope | Whole service endpoint | Per subnet → service type (policies can narrow for Storage) | Per resource |
| Data exfiltration protection | Weak | Partial (service endpoint policies for Storage) | Strong (only mapped resources) |
| DNS work | None | None | Private DNS zones, forwarding from on-prem |
| Cost | None | None | Per endpoint-hour + per GB |
| Operational complexity | Low | Low | Medium-high (DNS is where incidents happen) |
Choose by data and access path
| Situation | Suggested model |
|---|---|
| Confidential/regulated data, or policy requires no public endpoints | Private endpoints, public access disabled |
| Accessed from on-premises applications | Private endpoints |
| Internal app in Azure, non-sensitive data, cost-sensitive | Service endpoints |
| Public website assets, public APIs | Public endpoint (with WAF/front door where relevant) |
| Dev/test sandboxes | Service endpoints or public with IP rules, by policy |
Design the DNS before the first endpoint
- Central private DNS zones (
privatelink.blob.core.windows.net, etc.) in the hub/connectivity subscription. - Zone records created by Azure Policy (DeployIfNotExists) when endpoints are created.
- On-premises DNS conditional forwarders to Azure DNS Private Resolver inbound endpoints.
- Test from every client network: spokes, on-prem, VPN users (see the private endpoint DNS troubleshooting post).
Guardrails with Azure Policy
| Policy | Effect |
|---|---|
| Public network access should be disabled for | Deny in prod landing zones |
| Configure private DNS zones for private endpoints | DeployIfNotExists |
| Storage accounts should restrict network access | Audit/Deny |
| Allowed private endpoint subnets | Custom, to keep endpoints in designated subnets |
Use exemptions with an expiry for justified exceptions instead of weakening the policy.
Migration note
Moving existing services from public to private without downtime is its own procedure (see the "move Azure PaaS from public endpoints to Private Link" transformation post): endpoints and DNS first, test, then disable public access.
Warning
Service endpoints don't stop the service being reachable on its public IP from other allowed sources, and they don't help on-premises clients. If your security requirement says "no public endpoint", only private endpoints with public access disabled meet it.
Checklist
- Data classification and access paths known per resource
- Model chosen and recorded per resource type and environment
- Central private DNS and on-prem forwarding in place
- Policies enforce the choice; exemptions expire
- Every client network tested