Skip to content
CAMPUX
Field notes · Networking
Private endpoints

Azure private endpoints, explained without the fog

By 5 min read

A private endpoint drops a real network card — with a private IP from your own subnet — in front of a public Azure service. Here is what that actually means, how it differs from a service endpoint, and the one DNS gotcha that trips everyone.

New to cloud? CAMPUX is a free, build-first course. Start here →

The short answer

An Azure private endpoint is a network interface that takes a private IP address from your own virtual network subnet and connects, over Azure Private Link, to one specific Azure service. The service then answers on that private IP, the traffic stays on the Microsoft backbone, and you can switch public network access off entirely.

Here is the part most guides skip: creating the endpoint is the easy half. Nothing connects until DNS resolves the service hostname to that private IP, and the DNS side is a separate set of resources you have to wire yourself.

Most Azure platform services — a storage account, an Azure SQL database, a Key Vault — are born with a public front door. Their address, something like myaccount.blob.core.windows.net, resolves to a public IP on the internet. You can bolt firewalls onto that front door, but it is still a front door facing the street. A private endpoint does something more fundamental: it builds a side entrance that opens only into your own private network, and lets you brick up the public door entirely.

What a private endpoint actually is

Microsoft's definition is refreshingly concrete, so learn it word for word: "A private endpoint is a network interface that uses a private IP address from your virtual network. This network interface connects you privately and securely to a service that's powered by Azure Private Link."

Read that again, because the important word is network interface — a NIC, the same kind of virtual network card a VM has. When you create a private endpoint for your storage account, Azure carves a real NIC into one of your subnets and gives it a private IP, say 10.0.1.4. That IP is your storage account now, as far as your network is concerned. The documentation puts it beautifully: you are "bringing the service into your virtual network." Traffic to it never touches the public internet — it rides the Microsoft backbone from your subnet straight to the service.

Because it is just a private IP in your address space, everything that can already reach your VNet can reach it: VMs in the same network, peered networks, and on-premises systems connected over VPN or ExpressRoute. No public exposure required for any of them.

One endpoint, one sub-resource

A private endpoint targets a specific sub-resource, not the whole account. A storage account's blob service and its file service are separate targets — so if a workload needs both privately, that is two private endpoints. It is the detail people forget when connectivity mysteriously works for blobs but not for files.

A private endpoint gives a PaaS service a private IP inside your VNet, reached over Private Link.YOUR VNETVM10.0.0.4Private endpoint10.0.0.5 · private IPStoragePaaS servicePrivate Linktraffic stays on the private network — the service answers on an IP inside your VNet
Figure — A private endpoint puts a private IP for a PaaS service (here, Storage) inside your own VNet. Your VM reaches the service over that private address through Azure Private Link, so the traffic never crosses the public internet and the service is not exposed on a public IP. It is how you make a shared PaaS service answer only on your private network.

Private endpoint vs service endpoint vs public endpoint

They sound like twins and do opposite things. Here is the clean split:

Public endpointService endpointPrivate endpoint
AddressThe service's public IP, reachable from the internetThe same public IP — nothing about the address changesA new private IP taken from your own subnet
What it changesNothing. This is the default state of a PaaS serviceWhich sources the service accepts, and the source IP it seesWhere the service sits on your network
Who can reach itAnything the service firewall allowsOnly the subnets where you turned it on, once you also set the service-side rulesAnything that can route to the VNet: peered networks, VPN, ExpressRoute
On-premisesOver the internet, using your public egress IPNot covered — on-premises still needs a public firewall ruleYes, over VPN or ExpressRoute, as a normal private IP
Public access offNoNo — the public endpoint staysYes. Set public network access to disabled and the front door is gone
GranularityWhole serviceSubnet to serviceOne sub-resource of one specific resource
CostFreeFree — Microsoft charges nothing for service endpointsBilled: an hourly rate per endpoint plus data processed through it
DNS workNoneNoneRequired. A private DNS zone, a VNet link, and a zone group

In prose:

Shorthand for the interview: service endpoint restricts the public door; private endpoint builds a private one.

Three names, one family, and they get used interchangeably in job descriptions by people who should know better. Learn the split once:

The relationship is one-to-many in one direction only: one Private Link service can accept connections from many private endpoints, but a private endpoint connects to exactly one target. Connections are also one-directional. The consumer initiates; the service provider has no route back into your network.

A private endpoint doesn't guard the public entrance — it brings the building inside your walls.

The DNS gotcha that catches everyone

Here is where first attempts break. You create the private endpoint, shut off public access, and your app immediately fails to connect. Nothing is wrong with the endpoint. The problem is name resolution.

Your code still connects to the friendly hostname, myaccount.blob.core.windows.net. By default that name resolves — through Azure's public DNS — to the service's public IP, the very door you just bricked up. The private endpoint gave you 10.0.1.4, but nothing is telling the hostname to point there.

The fix is a private DNS zone (for storage blobs, privatelink.blob.core.windows.net) linked to your VNet. With it in place, an internal lookup of the hostname returns the private IP, and everything connects — no code change, same connection string. When you wire the endpoint up in the portal it offers to create and link this zone for you; in infrastructure-as-code you must declare it yourself, which is exactly why it gets missed. If a private endpoint "isn't working," check DNS before you touch anything else.

Private DNS zone integration, step by step

Here is the exact wiring that makes a private endpoint resolve correctly. Do these four things and the friendly hostname returns the private IP from inside your network:

  1. Create the private DNS zone for the service. The name is fixed per service type — privatelink.blob.core.windows.net for blob storage, privatelink.database.windows.net for Azure SQL, privatelink.vaultcore.azure.net for Key Vault. Get the name wrong and nothing resolves.
  2. Link the zone to your VNet with a virtual-network link. The link is what lets resources in that VNet see the private records; without it the zone exists but does nothing. Enable auto-registration only for VM DNS, not for the endpoint zone.
  3. Attach a DNS zone group to the private endpoint. This is the piece people skip: the zone group tells Azure to automatically create (and keep updated) the A record mapping the service hostname to the endpoint's private IP. Wire it once and Azure maintains the record for you.
  4. Verify from inside the VNet: from a VM in the network, resolve the public hostname (nslookup myaccount.blob.core.windows.net). It should now return your 10.x.x.x private IP, not a public one. If it still returns a public address, the zone link or the zone group is missing.

In Bicep or Terraform, all four are separate resources you must declare — the private endpoint, the privateDnsZone, the virtualNetworkLink, and the privateDnsZoneGroup. The portal bundles them behind one "integrate with private DNS zone" checkbox, which is why endpoints that work in the portal break when someone rebuilds them in code and forgets the zone group.

Create a private endpoint with the Azure CLI

The portal hides the moving parts, so build one on the command line at least once. Four required arguments do the work: which subnet the interface lands in, which resource it points at, which sub-resource of that resource, and a name for the connection.

az network private-endpoint create \
  --name pe-storage-blob \
  --resource-group rg-network \
  --vnet-name vnet-core --subnet snet-data \
  --private-connection-resource-id $(az storage account show -g rg-data -n mystorageacct --query id -o tsv) \
  --group-id blob \
  --connection-name conn-storage-blob

--group-id is the sub-resource. If you are unsure what a service accepts, ask the platform rather than guessing: az network private-link-resource list returns the valid group IDs for a given resource, and az network private-endpoint list-types -l eastus returns every resource type that supports a private endpoint in that region.

The endpoint now exists and resolves to nothing useful. Add the DNS zone group to make the hostname point at it:

az network private-endpoint dns-zone-group create \
  --resource-group rg-network \
  --endpoint-name pe-storage-blob \
  --name default \
  --zone-name privatelink-blob-core-windows-net \
  --private-dns-zone privatelink.blob.core.windows.net

If you do not own the target resource — a different team, a different tenant — add --manual-request true and a --request-message. That creates the connection in a pending state and waits for the owner to approve it. Automatic approval happens only when your identity holds the privateEndpointConnectionsApproval action for that resource type.

Azure private endpoint architecture: what actually gets created

One private endpoint is more objects than the portal blade suggests. Knowing the shape of it is what separates a design answer from a click-through answer.

At any size beyond a lab, the number that grows is the sub-resource count, not the service count. One storage account used for blobs, files, and Data Lake paths is three endpoints, three DNS zones, three zone groups. For a single network sharing one DNS view, Microsoft's own guidance is one private endpoint per private-link resource — duplicates create conflicting A records and intermittent resolution failures that look like anything but DNS. Build the naming convention and the module before you need the hundredth one, not after.

Private endpoint network policies: applying NSGs and route tables

By default, network policies are disabled for a subnet, which means network security groups and user-defined routes do not apply to the private endpoints in it. That surprises people who assume an NSG covers everything in the subnet. It covers the other resources; the private endpoints are exempt until you say otherwise.

Turn the policies on and NSGs, user-defined routes, and application security groups start applying to private endpoints in that subnet. The setting affects every private endpoint in the subnet, not one at a time. In ARM and PowerShell the property privateEndpointNetworkPolicies takes four values — Disabled, NetworkSecurityGroupEnabled, RouteTableEnabled, and Enabled — so you can switch on route tables without switching on NSGs. The Azure CLI is blunter and only offers both or neither:

az network vnet subnet update \
  --resource-group rg-network \
  --vnet-name vnet-core --name snet-data \
  --disable-private-endpoint-network-policies false

The reason this matters in a hub-and-spoke design: a private endpoint propagates a /32 route, and by longest-prefix match that route wins, sending traffic straight to the endpoint and around your firewall. To force it through a network virtual appliance, enable route-table policy on the subnet and write a route whose address range is equal to or narrower than the VNet address space. A default route of 0.0.0.0/0 will not do it — it is broader, so it loses. Two known rough edges worth saying out loud: the portal does not show effective routes or security rules for a private endpoint NIC, and NSG flow logs do not capture inbound traffic to a private endpoint. Plan your troubleshooting around that.

Private endpoints service by service: storage, Service Bus, Backup, Front Door

The mechanism is identical everywhere. What changes per service is the sub-resource name and the private DNS zone, and getting either one wrong is the usual cause of a silent failure. The zone names are fixed strings — Azure only auto-creates the DNS records if you use the exact recommended name.

ServiceSub-resource (group ID)Private DNS zone
Storage — blobblobprivatelink.blob.core.windows.net
Storage — filefileprivatelink.file.core.windows.net
Data Lake Gen2dfsprivatelink.dfs.core.windows.net
Azure SQL DatabasesqlServerprivatelink.database.windows.net
Key Vaultvaultprivatelink.vaultcore.azure.net
Service Busnamespaceprivatelink.servicebus.windows.net
Event Hubsnamespaceprivatelink.servicebus.windows.net
Container Registryregistryprivatelink.azurecr.io
Web App / Function Appsitesprivatelink.azurewebsites.net
Cosmos DB (SQL API)Sqlprivatelink.documents.azure.com

Storage accounts are the ones people trip over, because each service inside the account is its own target. Blob, file, queue, table, web, and dfs are six separate sub-resources with six separate zones. Note also that private endpoints are only supported on a general-purpose v2 account.

Service Bus takes a single namespace sub-resource, and it shares its zone name with Event Hubs and Azure Relay because all three live under servicebus.windows.net. One zone covers them in a given network, and the records inside it are per-namespace.

A Recovery Services vault for Azure Backup is the awkward one. The AzureBackup sub-resource needs three zones, not one: privatelink.{regionCode}.backup.windowsazure.com for the vault itself, plus privatelink.blob.core.windows.net and privatelink.queue.core.windows.net, because the backup service moves data through storage on your behalf. Wire only the first and backups fail in a way the vault blade will not explain. Site Recovery on the same vault is a different sub-resource again.

Azure Front Door inverts the whole model, which is why searching for "Front Door private endpoint" gets confusing answers. Front Door does not sit behind your private endpoint. On the Premium tier only, Front Door creates a private endpoint of its own, inside a Microsoft-managed regional network, pointing at your origin — an App Service, a blob container, an internal load balancer, API Management, Application Gateway, Container Apps. You then approve that pending connection on your origin, and your origin stops needing public access. Two consequences worth knowing: an origin group cannot mix private-link and public origins, and this only secures Front Door to origin. Client to Front Door stays public by design.

Managed private endpoints: the ones that are not in your VNet

A managed private endpoint is a private endpoint that a service creates and operates for you inside its managed virtual network, rather than one you create in yours. Azure Data Factory is the usual context: enable a managed virtual network on the integration runtime, and the service gets its own isolated network in a Microsoft subscription, with managed private endpoints as its way out to your data stores.

The point is that a data engineer gets private connectivity without designing a network. There is no subnet to size, no IP plan to negotiate, no address space to burn. What you give up is control: the network is under a Microsoft subscription, and custom DNS is not supported inside it.

The approval workflow is the same as anywhere else, and it is the step people forget. Creating a managed private endpoint puts the connection in a pending state on the target resource. Until the owner of that storage account or database approves it, no traffic moves. If a Data Factory pipeline hangs on a connection test right after you wired it up, go look for an unapproved private endpoint connection on the target.

When to reach for one

Use a private endpoint whenever a data-tier service should not be reachable from the internet at all: the database behind a web app, the Key Vault holding your secrets, the storage account behind an analytics pipeline. The pattern that makes a portfolio project look professional is exactly this — a public web front end whose backing storage and database are unreachable except through private endpoints, so you can point at a running URL and still prove the data tier has no public IP.

That is the whole idea. A private endpoint is not a firewall rule; it is a change of address. You move the service off the public street and into your own building, then decide, deliberately, whether the street door stays open at all.

Questions people also ask

What is a private endpoint in Azure?

A private endpoint in Azure is a network interface that uses a private IP address from your virtual network to connect privately to a service powered by Azure Private Link. The service becomes reachable at an address inside your own network, traffic travels over the Microsoft backbone instead of the internet, and public network access to the service can be turned off.

What is the difference between a private endpoint and a public endpoint?

A public endpoint is the internet-facing address an Azure PaaS service is created with, protected only by that service's firewall. A private endpoint is a second address for the same service, taken from your virtual network, reachable only from your network. Once the private endpoint works, you can disable public network access and the public endpoint stops existing for callers.

What is a managed private endpoint in Azure?

A managed private endpoint is a private endpoint created and managed by a service inside its own managed virtual network, not inside yours. Azure Data Factory uses them so pipelines can reach data stores privately without you designing a subnet. The target resource owner still has to approve the connection before traffic flows.

Do I need a dedicated subnet for private endpoints?

No. A private endpoint can take its IP from any subnet in the virtual network, and one subnet can hold many private endpoints for many different services. A dedicated subnet is a convention some teams adopt for clarity and for applying network policies in one place, not an Azure requirement.

Can I use a network security group with a private endpoint?

Yes, but not by default. Network policies are disabled on a subnet to begin with, so network security groups and route tables do not apply to private endpoints in it. Enable network policies on the subnet and NSGs, user-defined routes, and application security groups start applying to every private endpoint in that subnet.

What is the difference between a private endpoint and a private link?

Private Link is the underlying technology; a private endpoint is the object you create with it. Private Link is the Azure networking service that lets traffic reach a PaaS resource privately. A private endpoint is the network interface, sitting in your subnet, that Private Link provisions to make that connection real.

What is the difference between a private endpoint and a service endpoint?

A service endpoint keeps the service on its public IP and restricts access to a specific subnet. A private endpoint gives the service a new private IP inside your VNet and lets you shut off public access entirely. Service endpoints do not reach on-premises callers; private endpoints do, over VPN or ExpressRoute.

Does a private endpoint cost money?

Yes. A private endpoint is a billed Azure resource, charged hourly plus a per-GB rate for data processed through it. A service endpoint, by contrast, is free. Budget for it the same way you budget for a NIC, because that is functionally what it is.

Why can't I connect after setting up a private endpoint?

Almost always DNS. Your app still resolves the service's hostname to its public IP unless a private DNS zone, linked to your VNet, overrides that lookup to return the private IP instead. Create and link the zone before you disable public access, not after.

Can a private endpoint be used for on-premises access?

Yes. Because the private endpoint's IP lives inside your VNet's address space, anything already connected to that VNet over VPN or ExpressRoute can reach it, exactly like reaching any other private IP on the network. No public exposure needed on either side.

How do I create a private endpoint using the Azure CLI?

Run az network private-endpoint create with the subnet, the resource ID of the target service, the sub-resource in --group-id, and a connection name. Then run az network private-endpoint dns-zone-group create to attach the private DNS zone, or the hostname keeps resolving to the public IP. Use az network private-link-resource list if you do not know the group ID.

Further reading — the Microsoft docs
Your next class · free
You've read the idea. Class 14 — Private Connectivity is where you build it, hands-on — no account needed.Start Class 14 →
Captain O
Founder & instructor · CAMPUX Cloud Engineering Bootcamp
LinkedIn
Drilled in Class 14 — Private Connectivity. Next note: LRS, ZRS, GRS, GZRS: which copy survives what →