Public endpoints for Azure services like Storage, SQL Database, and App Services are convenient but introduce attack surfaces. This guide walks you through securing Azure service connectivity using private networking primitives: Virtual Network Service Endpoints and Azure Private Link with private endpoints. We'll cover architecture decisions, implementation with AZ CLI, and DNS integration patterns.

Why Private Access Matters

By default, most Azure PaaS services expose public endpoints. While protected by Azure's platform security, public endpoints:

  • Traverse the public internet, adding latency and potential eavesdropping risks
  • Require managing IP firewalls or shared keys for access control
  • Can't leverage your existing on-premises private connectivity (ExpressRoute/VPN)

Private access solutions bring Azure service traffic into your virtual network, enabling:

  • Traffic over Azure's backbone network, not the public internet
  • Integration with your existing NSG and firewall rules
  • Simplified access control using VNet private IP addresses

Virtual Network Service Endpoints

Service endpoints extend your VNet private address space to Azure services directly. Traffic from your VNet to the Azure service stays on Azure's backbone network, and service resources gain the VNet's private IP as the source address.

How Service Endpoints Work

When you enable a service endpoint on a subnet:

  1. A route is added to direct traffic destined for the service to the Azure backbone
  2. The service's firewall can be configured to allow traffic only from that specific subnet
  3. No public IP is required on the source resources

Configure Service Endpoints with AZ CLI

# Enable service endpoint for Azure Storage on a subnet
az network vnet subnet update \
  --resource-group myResourceGroup \
  --vnet-name myVnet \
  --name mySubnet \
  --service-endpoints Microsoft.Storage

# Enable service endpoint for Azure SQL Database
az network vnet subnet update \
  --resource-group myResourceGroup \
  --vnet-name myVnet \
  --name mySubnet \
  --service-endpoints Microsoft.Sql

# Verify service endpoints on a subnet
az network vnet subnet show \
  --resource-group myResourceGroup \
  --vnet-name myVnet \
  --name mySubnet \
  --query "serviceEndpoints"
Note: Service endpoints work only for traffic originating from the VNet where they're enabled. They don't support cross-tenant access or on-premises traffic over ExpressRoute/VPN without additional configuration.

Azure Private Link & Private Endpoints

Private Link is the newer, more capable solution for private access. It provides a private IP address in your VNet for Azure services (or your own services via Private Link Service).

Key Components

  • Private Endpoint: A network interface (NIC) in your VNet with a private IP from your subnet, connected to the target service
  • Private Link Service: Lets you expose your own services (load balancers) privately to other VNets or tenants
  • Private DNS Zone: Maps the service's public DNS name to its private IP address

Create a Private Endpoint with AZ CLI

Let's create a private endpoint for an Azure Storage account:

# Create a private endpoint for Azure Storage
az network private-endpoint create \
  --resource-group myResourceGroup \
  --vnet-name myVnet \
  --subnet myPrivateSubnet \
  --name storagePrivateEndpoint \
  --private-connection-resource-id "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount" \
  --group-id blob \
  --connection-name storageConnection

# Verify private endpoint creation
az network private-endpoint show \
  --resource-group myResourceGroup \
  --name storagePrivateEndpoint \
  --query "ipConfigurations[0].privateIPAddress"

Integrate Private Endpoints with DNS

For private endpoints to work, your applications must resolve the service's public DNS name to its private IP address. Azure Private DNS zones automate this.

Configure Private DNS Integration

# Create a Private DNS zone for Azure Storage
az network private-dns zone create \
  --resource-group myResourceGroup \
  --name "privatelink.blob.core.windows.net"

# Link the Private DNS zone to your VNet
az network private-dns link vnet create \
  --resource-group myResourceGroup \
  --zone-name "privatelink.blob.core.windows.net" \
  --name storageDnsLink \
  --virtual-network myVnet \
  --registration-enabled false

# Create a DNS zone group for the private endpoint
az network private-endpoint dns-zone-group create \
  --resource-group myResourceGroup \
  --endpoint-name storagePrivateEndpoint \
  --name storageDnsZoneGroup \
  --private-dns-zone "privatelink.blob.core.windows.net" \
  --zone-name blob
Important: You must use the correct Private DNS zone name for each service. Common ones include:
  • Azure Storage: privatelink.blob.core.windows.net, privatelink.file.core.windows.net
  • Azure SQL: privatelink.database.windows.net
  • Azure App Service: privatelink.azurewebsites.net

Design Considerations for Private Endpoints

When architecting private access, keep these patterns in mind:

  1. Hub-and-Spoke: Centralize private endpoints in a hub VNet, share across spoke VNets via VNet peering
  2. DNS Consistency: Ensure all VNets using the private endpoint have access to the same Private DNS zones
  3. Scalability: Each private endpoint has a fixed cost; consolidate when possible
  4. Monitoring: Enable private endpoint network policies to log traffic

Create a Private Endpoint in a Hub VNet

# Create private endpoint in hub VNet
az network private-endpoint create \
  --resource-group hubResourceGroup \
  --vnet-name hubVnet \
  --subnet hubPrivateSubnet \
  --name hubStoragePE \
  --private-connection-resource-id "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/spokeResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount" \
  --group-id blob \
  --connection-name hubStorageConnection

# Peer spoke VNet to hub to access the private endpoint
az network vnet peering create \
  --resource-group spokeResourceGroup \
  --vnet-name spokeVnet \
  --name spokeToHubPeering \
  --remote-vnet hubVnetID \
  --allow-vnet-access

# Link Private DNS zone to spoke VNet as well
az network private-dns link vnet create \
  --resource-group hubResourceGroup \
  --zone-name "privatelink.blob.core.windows.net" \
  --name spokeDnsLink \
  --virtual-network spokeVnet \
  --registration-enabled false

Integrate App Service with Azure VNets

Azure App Service (Web Apps, API Apps) can be integrated into your VNet to access private endpoints and on-premises resources. This is called VNet Integration.

Configure VNet Integration with AZ CLI

# Enable regional VNet integration for an App Service
az webapp vnet-integration add \
  --resource-group myResourceGroup \
  --name myWebApp \
  --vnet myVnet \
  --subnet myIntegrationSubnet

# Verify VNet integration
az webapp vnet-integration list \
  --resource-group myResourceGroup \
  --name myWebApp

# For Linux apps, you can also configure route all traffic through VNet
az webapp config set \
  --resource-group myResourceGroup \
  --name myWebApp \
  --vnet-route-all-enabled true
Pro Tip: Use VNet Integration for outbound traffic from your App Service to private resources. For inbound private access to your App Service, use a private endpoint for the App Service instead.

Service Endpoints vs Private Endpoints: When to Use Which?

Feature Service Endpoints Private Endpoints
Private IP in VNet No Yes
Cross-VNet/VPN/ExpressRoute access Limited Yes
DNS integration required No Yes
Supports custom services (Private Link Service) No Yes
Cost Free Hourly + data processed

Best Practices for Private Access

  • Prefer Private Endpoints for new deployments — they're more flexible and support more scenarios
  • Use Service Endpoints only for simple, same-VNet access to Azure services
  • Centralize Private DNS zones in a hub VNet for multi-VNet environments
  • Combine private endpoints with NSG rules to restrict traffic to specific subnets
  • Enable diagnostic logs for private endpoints to monitor connections
  • Test connectivity using az network watcher test-connectivity after configuration

Test Private Endpoint Connectivity

# Test connectivity to private endpoint from a VM in the same VNet
az network watcher test-connectivity \
  --resource-group myResourceGroup \
  --source-resource myVmId \
  --dest-address 10.0.1.5 \
  --dest-port 443

# Check private endpoint connection status
az network private-endpoint show \
  --resource-group myResourceGroup \
  --name storagePrivateEndpoint \
  --query "privateLinkServiceConnections[0].privateLinkServiceConnectionState"

Common Troubleshooting Scenarios

DNS Resolution Failures

If your application still resolves the public IP instead of the private IP:

# Check DNS resolution from a VM in the VNet
az vm run-command invoke \
  --resource-group myResourceGroup \
  --name myVm \
  --command-id RunShellScript \
  --scripts "nslookup mystorageaccount.blob.core.windows.net"

Private Endpoint Connection Failures

If the private endpoint connection is stuck in Pending:

# Manually approve a pending private endpoint connection (for your own services)
az network private-endpoint-connection approve \
  --resource-group myResourceGroup \
  --name storagePrivateEndpoint \
  --resource-name mystorageaccount \
  --type Microsoft.Storage/storageAccounts

Frequently Asked Questions

Can I use private endpoints with Azure Firewall?

Yes, you can route traffic through Azure Firewall to inspect traffic between your VNet and private endpoints. Configure user-defined routes (UDR) to direct traffic to the firewall.

Do private endpoints work across Azure tenants?

Yes, Private Link supports cross-tenant access. The private endpoint is created in your tenant, while the service is in another tenant. Approval from the service owner is required.

How many private endpoints can I create per VNet?

Each VNet supports up to 1000 private endpoints. For larger deployments, consider consolidating endpoints or using service endpoints for simpler scenarios.

Can I access private endpoints from on-premises via VPN?

Yes, if you enable gateway transit on the VNet peering between your hub (with VPN gateway) and the VNet hosting the private endpoint.

Recommended Books & Resources

Support SysOpsBits by checking out these related resources on Amazon: