Service Endpoints and Private Endpoints - When to use
One of the requirements that continuously pop up when you're working on securing your Azure workloads is to remove public access from as m
Azure Private link is a relatively new service that allows the users to connect to a PaaS service privately using an IP address.
You might say that this feature existed for ages with Service Endpoints which injected the PaaS service in a virtual network and allowed private connectivity towards the service without it being exposed on the internet. The main difference between the two is that Service Endpoints only injects the service in the Virtual Network and cuts off the internet connection while Private Link is a service that attaches a private IP that exists in your virtual network and you can access it using that RFC1918 IP address.
As I mentioned, before Private Link we had Azure Service Endpoints which injected the PaaS service in the delegated subnet and then the Azure gateway cut off any internet traffic towards it.
The problem with service endpoints is that it requires a cloud-native operation for it to work properly, meaning that you don’t use third-party NVAs to funnel the 0/0 traffic towards them for traffic inspection because if you do that it breaks the system and you lose access to your storage account/database or other Service Endpoint enabled systems. Azure Firewall, for example, supports this scenario – Example –
The real problem is that Azure Firewall came late and lacking some critical features that most companies require. It’s getting there but it’s going to take some more time. All modesty aside, I managed to convince a bank CISO that service endpoints are enough for their SQL Databases and this was about an e-banking system. The problem with the cloud is that people do not understand it and most security people if not all if they do not understand something 100% then they’re going to block it but I digress.
To overcome the complete storm of complaints regarding service endpoints and to satisfy the general public requests to attach private IPs to PaaS Services, Microsoft came up with the Private Link service which basically attaches an RFC1918 IP address to a supported PaaS system and has that system be only available in the VNET where the IP exists.
This is a much more understandable system than service endpoints. You simply tell whoever may be concerned that the system doesn’t have a public IP address, do a demo, and done.
Supported PaaS Services (This list will get old soon as new services get enrolled) – For an accurate list please go to -> https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-overview#private-link-resource
rivate link resource name | Resource type | Subresources |
---|---|---|
Private Link Service (Your own service) | Microsoft.Network/privateLinkServices | empty |
Azure SQL Database | Microsoft.Sql/servers | Sql Server (sqlServer) |
Azure Synapse Analytics | Microsoft.Sql/servers | Sql Server (sqlServer) |
Azure Storage | Microsoft.Storage/storageAccounts | Blob (blob, blob_secondary) Table (table, table_secondary) Queue (queue, queue_secondary) File (file, file_secondary) Web (web, web_secondary) |
Azure Data Lake Storage Gen2 | Microsoft.Storage/storageAccounts | Blob (blob, blob_secondary) Data Lake File System Gen2 (dfs, dfs_secondary) |
Azure Cosmos DB | Microsoft.AzureCosmosDB/databaseAccounts | Sql, MongoDB, Cassandra, Gremlin, Table |
Azure Database for PostgreSQL -Single server | Microsoft.DBforPostgreSQL/servers | postgresqlServer |
Azure Database for MySQL | Microsoft.DBforMySQL/servers | mysqlServer |
Azure Database for MariaDB | Microsoft.DBforMariaDB/servers | mariadbServer |
Azure Key Vault | Microsoft.KeyVault/vaults | vault |
Azure Kubernetes Service – Kubernetes API | Microsoft.ContainerService/managedClusters | managedCluster |
Azure Search | Microsoft.Search/searchService | searchService |
Azure Container Registry | Microsoft.ContainerRegistry/registries | registry |
Azure App Configuration | Microsoft.Appconfiguration/configurationStores | configurationStore |
Azure Backup | Microsoft.RecoveryServices/vaults | vault |
Azure Event Hub | Microsoft.EventHub/namespaces | namespace |
Azure Service Bus | Microsoft.ServiceBus/namespaces | namespace |
Azure Relay | Microsoft.Relay/namespaces | namespace |
Azure Event Grid | Microsoft.EventGrid/topics | topic |
Azure Event Grid | Microsoft.EventGrid/domains | domain |
Azure WebApps | Microsoft.Web/sites | sites |
As you can see, a lot of services are getting Private Link support and Microsoft knows that this is a must because the blocker in adoption was always the publicly exposed part of the service. Now that you’re able to actually have a private IP attached to that service, you don’t have a “security” concern attached. Don’t get me wrong, I’m a strong believer in security, but security should not add roadblocks but guardrails.
First of all, be very wary that some PaaS Services may be in preview and breaking changes may occur. Next, validate that you do not use Service Endpoints in the VNET where you will be adding the Private Link connection.
If all those boxes check then all you have to do is to follow the startup guide from here: https://docs.microsoft.com/en-us/azure/private-link/create-private-endpoint-powershell
At the time of writing this article, there’s a huge capacity issue in Azure and I cannot create bespoke scripts to automate this cycle end to end ?
The example from above shows how to connect an Azure VM to an Azure SQL Database using the private IP. Please take notice that in the guide above references an Azure Private DNS Zone that is injected in the VNET. Azure SQL Databases cannot be accessed via the private IP directly and this limitation is by design.
For starters, here’s a reference architecture that shows how you would integrate Private Link in your hybrid cloud environment.
Implementing this in production depends on a system by system basis. You need to know the limitations of each system and work around them. For SQL Databases you know that you need to call them using the Private DNS CNAME, storage accounts work the same. Implementing access on-premises can be done with a simple DNS forwarder. I say simple but it can be a hassle -Been there done that ?
I would say start small, always in the development environment and then move to production. Never start in production unless you want a new job.
That being said. Stay safe, have a good one.