Personally, I find Azure Private Link Service incredibly valuable and beneficial. However, I recognize that it can be confusing at first glance, especially when it’s not actively used and becomes a bit fuzzy in memory. That’s precisely why I’m writing this article – to serve as a reference for future instances when I, and others like me, encounter this challenge.
Long story short, Azure Private Link enables one-directional access to resources via a virtual network (vNET) privately. A resource published via Private Link (and its associated services) into a vNET cannot access other resources within the vNET. However, other resources within the vNET can access the published resource. A resource can be any Azure PaaS service (such as Azure KeyVault or Azure CosmosDB, a list of supported services can be found here) or any your workload represented by Azure Load Balancer. The traffic goes via the Microsoft backbone network.
Private Link resources in detail
Azure Private Link Service resource
This resource is specifically designed for publishing a Load Balancer via Private Link. It’s not getting involved in the setup of Azure native PaaS service, just for Load Balancer. In essence, it’s associated with the Frontend IP of the chosen Load Balancer. Each Private Link Service can only be assigned to a single Load Balancer Frontend IP - a Standard Load Balancer can host up to 8 Private Link Services. Private Link Service is a standard Azure resource that requires deployment within a resource group and location.
Azure Private Endpoint resource
Private Endpoint is a critical component in both approaches, whether for Azure PaaS services or for Load Balancers, and it must be present at all times. It serves as an instance (interface) of the published resource within a virtual network (vNET).
A Private Endpoint has an associated resource, namely the Azure Network Interface (NIC) resource. This NIC allocates an IP address within a virtual network (vNET).
Why To Care about DNS
The seamless utilization of an Azure PaaS resource via Private Link, without any additional configuration, relies on correct DNS configuration.
Let’s show it on example - when you deploy a Blob Storage, it gets a hostname like:
Whenever you access the hostname
myblobstorage.blob.core.windows.net, it automatically resolves to the assigned public IP address of the Blob Storage service. However, with Private Endpoint, a Network Interface (NIC) representing the Blob Storage is deployed within your vNET, allocated with a private IP address from your vNET range. Therefore, you need to access the Blob Storage using this private IP.
Consider a scenario where you have a Blob Storage with the hostname
myblobstorage.blob.core.windows.net, and public access is blocked. If you perform an HTTPS call for
https://myblobstorage.blob.core.windows.net/ from a resource within the vNET:
- In a standard setup, the hostname myblobstorage.blob.core.windows.net would be translated by a public DNS server to the associated Azure public IP address (e.g., 20.60.181.xxx) and routed via the vNET’s configured internet routing method. However, since the request appears to arrive from the “public internet” rather than the vNET, the Blob Storage service would refuse it due to disabled public access.
- Alternatively, if you wish to use the internal IP address directly, you could perform an HTTPS call for
https://10.0.1.2/(the private IP address within the vNET). In this case, TLS certificate validation comes in the game. The request would be routed to the Blob Storage server correctly, and the server would respond with a TLS certificate issued for
myblobstorage.blob.core.windows.nethostname. However, the web client initiating the request will validate the certificate and encounter a TLS error regarding the mismatching certificate (as the certificate is not issued for
10.0.1.2). While turning off certificate validation could be an option, it introduces vulnerability to Man-in-the-Middle (MiTM) attacks, which is not advisable.
To tackle this challenge, the Private Link concept relies on “overwriting DNS records” within the vNET. For this purpose, Azure provides a built-in service called Azure Private DNS Zone. This service allows hosting specific DNS zones, while forwarding the rest of the requests for resolutions to standard DNS servers.
When your vNET utilizes default Azure DNS resolvers, you simply need to create the Azure Private DNS Zone for the selected PaaS service. Corresponding records for the PaaS resource should be configured within this private DNS zone. As a result, any DNS resolution requests originating from the selected vNET will automatically be overwritten to use Private Link’s IP records.
In case your vNET utilizes a custom DNS resolvers, you may set up a forwarder within a Azure vNET, integrated with Azure Private DNS Zone and you may configure your environment to even resolve resources via Private Link from on-premises. More details about Azure DNS Private Resolver can be found here.
The Vital Role of vNET
Without a virtual network (vNET), consuming a resource via Private Link isn’t possible. The vNET serves as the essential conduit facilitating communication between the published resource and the consuming resource, such as a virtual machine (VM) or Azure Function.
DNS Private Zones
As mentioned earlier, configuring the corresponding Azure DNS Private Zone is crucial for ensuring the smooth operation of Private Endpoint. List of DNS zones for Azure PaaS services, such as
privatelink.vaultcore.azure.net for KeyVault, can be found in Microsoft Docs here.
For debugging a effective resolution of DNS records within a vNET you may utilize my open-source tool AzFuncDebugger.
Ingress vs. Egress traffic
Azure Private Link communication is incoming-only from a resource perspective. This means that the resource accessed via Private Link cannot initiate communication with any other resource within the virtual network. Therefore, Private Link should not be considered as an option for routing bi-directional communication between two resources within the virtual network.
For instance, if you access a resource like KeyVault from an AppService, you could utilize publishing KeyVault via Private Endpoint (incoming traffic from KeyVault perspective). However, for outbound traffic from the AppService, you would need to employ standard vNET outbound traffic integration.
Some Azure PaaS services consist of multiple sub-resources (subdomains), as seen with Azure Storage, which has
privatelink.blob.core.windows.net for Blob,
privatelink.file.core.windows.net for File, and so on.
This implies that to consume all sub-resources of an Azure Storage resource, you would need to create multiple Private Endpoints, each with its corresponding DNS records, to ensure full functionality.
The full list of sub-resources for Azure PaaS resources can be found here.
Cross-region / Cross-tenant Private Links
One significant benefit of Azure Private Link worth emphasizing is its capability to publish a service from one region to another by creating a Private Endpoint in a different region. Because the traffic travels via the Microsoft backbone network, the additional latency incurred is minimal. However, it’s important to keep in mind that splitting resources of your workload across regions may decrease the resiliency of the workload, as it becomes dependent on two regions.
Another remarkable use case is the ability for Private Link connections to be cross-tenant. As an Azure ISV provider, you can construct a highly intricate SaaS solution and expose only a load balancer to the customer. This load balancer allows the customer to privately consume the SaaS service within their vNETs via Private Link.
Multiple Private Endpoints can be associated with a single Private Link Service, with a maximum of up to 1000 instances. For instance, this capability allows you to deploy a single Load Balancer for your SaaS solution and share it among multiple customers.
Infrastructure as Code Support
All resources related to Azure Private Link have full support to be deployed via IaC tooling like Azure ARM, Bicep or Terraform. See example within this article to deploy resources via Azure Bicep.
Since Azure Private Link supports the creation of cross-tenant connections, establishing a secure connection requires initiating a new Private Link connection from the consumer’s tenant and obtaining approval from the tenant that owns the Private Link Service with resources.
If the consumer has RBAC permissions on the published resources via the Private Link Service, the connection will be automatically approved. However, if the consumer does not have such permissions, manual approval from the customer is required. In this scenario, the Azure Private Link Center interface in the Azure Portal allows customers to view all pending connections and approve or reject Private Link connections as needed.
Please keep in mind that Private Endpoints incur additional costs, priced at
$0.01 per hour for each Private Endpoint. Additionally, there are additional costs associated with the processing of inbound and outbound data transferred via Private Endpoints, which are charged per GB. It’s important to note that these costs could potentially accumulate to significant amounts in certain scenarios. On the other hand, utilizing a Private Link Service itself is free of charge.