Azure Private Endpoints and Terraform
Azure private endpoints are a very popular way to provide private connectivity to PaaS services within Azure. The goal of this article is to help provide some resources to get started and to provide coding examples of how to quickly set up your environment for private endpoints utilizing Terraform. I will not be focusing on Terraform basics or on what private endpoints are. Below is the official documentation on what Private Endpoints are.
What is a private endpoint? | Microsoft Docs
Prerequisites For Private Endpoints
In order to get a private endpoint to work successfully you must create the private endpoint interface and create an A-record within specific Azure private DNS zones. Each service you use will have specific DNS zones that are required. You can find the complete list from Microsoft with all the private DNS zones in the link below.
Azure Private Endpoint DNS configuration | Microsoft Docs
The other requirement before you get started, is that your VNET needs to have a virtual network link to the private DNS zone. This comes with some caveats depending on your environment. If you just have a single VNET and are not using custom DNS on your VNET, you’re all set. If you have multiple vnets or custom DNS set on your VNETs read on.
Multiple VNETs / Custom DNS Prerequisites
If your environment has multiple VNETs or you are overriding azure’s DNS with your own internal DNS, you have some work to do. Any internal nodes (VMs for example) that try to connect to a service set up with Private Endpoint, need to ultimately receive the DNS resolution from Azure’s DNS (168.63.129.16). In a very simple environment (our lab for example) this is done by creating a private DNS zone virtual network link (we will do this below in code). If you are not using custom DNS, you will need to link every zone you want to use, to every VNET in your environment where you want the private endpoint resolution to work.
Using Custom DNS Entries? This is where it gets a bit complicated and I will summarize the requirements laid out by Microsoft in this article below.
Azure Private Endpoint DNS configuration | Microsoft Docs
There is a hard requirement that you have custom DNS servers in Azure, specifically in a VNET that has been configured with a private DNS zone virtual network link to the Private DNS zones you wish to use. These DNS servers need to forward any resolution for these Private Endpoint zones to the list I linked to earlier to 168.63.129.16. As long as you have met these requirements you should get the private endpoint IP when resolving any service you have setup with private endpoints. This gets a bit tricky if you have DNS servers in other environments, for example on premise and you want to use private endpoints. I will not go into a lot of detail here but you essentially need to make sure these requests are all forwarded to your custom DNS servers in azure, to then be forwarded to 168.63.129.16. I have used Infoblox in several environments and they do a good job explaining this setup so I have provided a link below.
Using Infoblox for Conditional Forwarding and Hybrid Name Resolution in Azure DNS Private Zones
Now that we have got all the requirements out of the way, let’s get coding. I have the entire code (including the provider blocks) on github.
Create the private DNS zones
The first thing I will walk through is creating some quick code that can be added to as new private DNS zones get added. Using the code below, you should only need to add another key and value to the list and apply the code and you’ll be all set.
In the code below, there is a locals value ‘private_dns_zones’, you can keep going with this list for as many private endpoints as you got. I removed a bunch from my environment code to minimize the amount on screen in this blog. I will add a complete list in github and link at the bottom.
Create the Virtual Network Links
Now that we have our private DNS zones, the virtual networks in our environment, need to have a virtual network link created so when DNS resolution within those VNETs occur, Azure knows to use the private DNS zones vs public DNS resolution.
At this point you should now have your vnet linked to several private end zones. At this point you’re ready to go and can start creating private endpoints. The below block can be used to create a private endpoint and find the private DNS zone in question (line 31). The example is a basic key vault. FYI, this code below doesn’t completely secure your key vault from public access. This is just demonstrating the public endpoint creation!
Now with our example demo completed. In my lab I have a key vault called
‘kveus2–1dm1’
Here’s a few screenshots showing everything linked up properly. Below we can see the DNS record that was successfully created.
Here we see where the VNET got successfully linked to the DNS zones (just going to show one for brevity).
On the Key Vault itself if you go to the networking blade, go to the private endpoint connections tab, you should see your private endpoint connection
From a public endpoint, we can see that if I try nslookup and search the URI of the key vault, I get a public IP.
From a jumpbox VM, in the same VNET (subnet1), if I try to do the same nslookup, I get the private IP that is attached to the a-record in the private dns zone (10.1.2.4).
Conclusion
Hopefully this helped you understand the configuration on private end point a little better and hopefully my Terraform code can be found useful in your use of private endpoints and private DNS.
Follow me on LinkedIn: Jeffrey Blanchard | LinkedIn