Last week , Azure Front Door Premium went into Public Preview. While this did bring about some other cool features and integrations, the one I’m most excited about today is the integration with Azure Private Link. This now allows Azure Front Door to make use of Private Link Services (not endpoints, which is what most people think about when they hear Private Link). Private Link Services allow for resource communication between two tenants, some of the most common use cases are software providers allowing private access to a solution running in their environment. Today I’m going to walk through how to connect Azure Front Door, through Private Link, to an App Service, without an ASE, the need to work with Private Link, DNS or anything of the sort. I believe this will become the new standard for hosting App Services.
With that, let’s get started! First, we need to create an Azure App Services Web App.
*Note* At the time of writing this post (03/01/2021) Private Link Service integration requires the App Service to be a Pv2.
Once the Web App is deployed, you’ll need the URL of the website and want to test it in a web browser. In this instance I’m not hosting anything in particular, simply hosting the sample page to show that it’s working.
At this point the web app is created, and you would expect to have to create a Private Link Endpoint now but since Azure Front Door Premium uses the Private Link Service functionality we can let Front Door do the work for us. With that said, let’s now go create the Azure Front Door Premium Service.
We need to make sure that the Tier is selected properly as the “Premium” SKU. After that radio button is selected, a section will populate below with different configuration options compared to the Standard Tier. The one we need to make sure to check is “Enable private link service”. After that’s selected, you will select the web app with which you want to establish Private Link connectivity from Front Door. If you would like, here you can also add a custom message. This will be what is displayed as a connection request in the Private Link Center in the next step.
On the review page, we can see that the endpoint created is a URL for Azure Front Door and this will be the public endpoint. The “Origin” is the web app to which Front Door will be establishing private connectivity.
Once Azure Front Door is done deploying, you will need to open up the Private Link Center. From there you will navigate to the “pending connections”, which is where you will see the connection request from Azure Front Door with the message you may or may not have customized. Remember that Azure Front Door uses Azure Private Link Service to connect it’s own managed Private Link Service to your Web App. You will need to “Authorize” the connection request in order for the connection to be created and allow Front Door to privately communicate with your Web App.
After the connection is approved you will notice that the “pending connection” is removed, and has been moved to “active connections”. At this point, you will also notice that access to the Web App through a browser will return an error message the same way it would if you were to have added firewall rules on the Web App. This is because it’s being configured to only allow inbound connections from Azure Front Door.
If you want to modify any of the configuration settings, you will go to the “Endpoint Manager” section of Azure Front Door, where you get the familiar interface used by both Azure Front Door and App Gateway.
In my testing, the time between clicking “Approve” in Private Link Center to the Web App being available through the Azure Front Door endpoint is anywhere between 15-30 minutes. I’m not quite sure why this is the case, though it is likely due to the service only being in preview. If you get an error message in the web browser using the Front Door URL, just grab a cup of coffee and give it some time to do its thing.
Once it’s all done though, you can use the Front Door URL in the web browser and see that it routes you to the App Service!
There we go, all set! This is really a dream configuration, and something a lot of us have been looking forward to for some time. In the past we’ve done something similar with App Gateways, and Private Link Endpoints. The beauty of the solution with Front Door Premium, is that there is no messing around with DNS or infrastructure whatsoever – you can deploy this entire solution in PaaS while taking advantage of Azure Front Door’s global presence!
Click here to get started with Azure Front Door Premium.
If you have any questions, comments, or suggestions for future blog posts please feel free to comment blow, or reach out on LinkedIn or Twitter. I hope I’ve made your day a little bit easier!
With the advent of the cloud came the ever so attractive PaaS service model. The first time I heard about this, I was sold. Host my application without having to manage the infrastructure, the OS, patching, scaling and all the other things that I really don’t want to do anyways – sign me up! The “catch” is though that (to misquote all those before me) “with less responsibility comes less power”. When relinquishing responsibility (the positive side of PaaS), you also relinquish some control and ability for customization. This is a conversation I have with customers at least once a week – how do I control networking for my PaaS application.
One my peers, Steve Loethen who focuses more on the application development aspects in Azure, and I were speaking and noted that it would be great if we could leverage Azure Private Link Endpoints and Azure Application Gateway to get both private connectivity from the internal network and leverage a cloud-native Web Application Firewall for internet traffic. Traditionally using the “isolated” tier of Azure App Services called an Azure Application Service Environment (which provides a completely isolated and dedicated app service environment) would be the way to go. Unfortunately the nature of a private stamp of a PaaS service inherently comes with a pretty heft price tag. There are still some great features to be had with the ASE, but using Private Link we can get to a point where all external access is blocked unless its using the WAF – but can be still be accessed over the internet network. I’ll document that configuration below.
To setup this environment we will need to:
Setup the Web App
Create a Virtual Network in Azure
Setup a Site-to-Site VPN
Setup a Private Link Endpoint for the Web App
Restrict Network Access to the Web App to only the Private Link Endpoint
Let’s get started! First, we’ll create the App Service. I’m going to be using the resource group named “pri-webapp-rg” and the app service name “private-webapp.azurewebsites.net” in the West US region.
*Note* At the time of writing this post (5/18/20) Private Endpoints require the App Service to be a Pv2.
I am not going to use it in this lab, but I am going to leave App Insights enabled. If you’ve not used App Insights yet as an APM tool I highly suggest you look at instrumenting your app with this tooling.
Go ahead and add any tags if you need any for your environment, then create that App Service. Next we’ll go and create our Azure Virtual Network. This will allow us to facilitate the private network connectivity. I’m going to create this in West US, I’ll note that Private Link Endpoints do not need to be deployed in the same region as the resource, but I want to reduce latency here so I’ll deploy the vnet (and subsequent Private Link Endpoints in the following steps) as the same region as the App Service.
I’m going to use the 10.2.0.0/16 address space, and initially create two subnets. The “WebApp” subnet will be for the Private Link Endpoint and the “AppGateway” subnet will be designated for the Application Gateway.
I’m going to leave the rest of the deployment settings with their default options selected for now and create the vnet.
Once the vnet has finished creating, we need to go create a “Gateway Subnet” which will be used for the VPN Gateway to be used for the Site-to-Site VPN for hybrid connectivity. By default, it will pre-select a subnet that is available in your address space. Once that subnet is created we have our finished vnet setup.
Now that the network in Azure is setup, we need to get the VPN Gateway configured. When the “West US” region is selected on the deployment screen you’ll get a list of available virtual networks in that region. I selected the one we just created, and it will validate that there is a “GatewaySubnet” created in that vnet and will select that as the deployment subnet for the VPN Gateway. I’m going to be using a Route-based VPN so I’ll select that as my VPN type then create a new public IP address and leave the Active-Active and BGP options disabled for this lab.
The VPN gateway does take 20-30 minutes to deploy, so go grab a cup of coffee. Once that’s done we’ll need to add the “connection” for the site-to-site VPN.
For this setup we’re using a Site-to-Site IPSec VPN Connection, and this is where you’ll also set your PSK and IKE protocol. You’ll also need to create a local network gateway, which is an ARM resource used for representing the on-premises network.
The “IP Address” field is where you’ll enter the public IP address of the appliance that’s going to terminate the VPN on-premises. You’ll also need to add which networks are on-prem, this will add add the local network address space to the route table of the VPN Gateway so it knows to use that link for traffic bound for those addresses.
Once the S2S VPN is setup, we can now go and setup the Private Link Endpoint for the App Service.
When choosing a private link endpoint you need to choose the resource type, so here I’m using the “Microsoft.Web/sites” resource type.
As noted earlier on, we created the “WebApp” subnet to hold the private link endpoint and we’ll select that here. A very important component of private link is DNS. As is stated so eloquently in my favorite Haku:
“It’s not DNS
There’s no way it’s DNS
It was DNS”.
Before deploying private link you have to consider the DNS scenario. Clients cannot call private link endpoints by their IP addresses, it has to be by their DNS names. I highly recommend some of the Microsoft Documentation on the topic, or Daniel Mauser has an amazing article on Private Link DNS Integration Scenarios. I’m going to go ahead and allow the private endpoint to create an Azure Private DNS Zone, but ultimately for this lab environment I’ll just be using a host file entry.
*Note* You can also check out my post on automated IaaS DNS Load Balancing to help with the private, hybrid DNS integration scenarios that may be required for Private Link here: DNS Load Balancing in Azure.
Alright, the private link endpoint is all setup. Now to make sure we restrict network traffic to that which only originates from the private link endpoint. App Services can use virtual network service endpoints to restrict traffic originating from vnets in Azure quite easily. Though in our case we want to make sure that on-premises traffic can also access that app service so rather than allowing access at the vnet level we’ll just be allowing the single IP of the private endpoint.
After adding the access restriction rule, you’ll see that the “Allow All” rule switches to a “Deny All” rule and is given the lowest priority on the ACL. Above that we have the single IP of the Private Link Endpoint that is allowed. As a result, the only IP that’s allowed to call this app service is that of the private link endpoint.
Great! Okay, now we’ve setup my app service, my site-to-site VPN, private link, and access restrictions. We should be all set to test connectivity from on-premises now, let’s go give that a shot. As noted above, since this is just a lab environment I’m just going to be using a host file entry on my test machine on my lab network, so lets set that up real quick.
Great, now let’s validate this in a browser and with powershell to both make sure the page loads and that it’s using the private endpoint. We can see that the page loads using the “public” DNS name, but the address is the 10.2.2.4 address that is assigned to the private link endpoint. We can also see that on a machine that’s just using the typical internet path is given a 403, since the source traffic is not coming from the private endpoint – perfect!
If we go back and look at the site-to-site VPN configuration now we’ll also see that traffic has started passing over that link which further validates the fact that the traffic is remaining private.
Now that we have confirmed the hybrid traffic is passing through the private endpoint and that all internet traffic is denied, let’s configure the Application Gateway with the Web Application Firewall SKU so that we can facilitate external traffic communicating with our private Web App (forgive my ever so descriptive naming convention) and create a new public IP address to be associated with the Application Gateway. Lastly, we’ll use the subnet that we designated earlier for the Application Gateway for the deployment.
When creating the backend pool we’ll enter the IP address of the private link endpoint. For the routing rule, since this is a lab and I don’t have a TLS certificate on-hand I’ll use an HTTP listener on the App Gateway and use the same HTTPS endpoint for the App Service that we’ve been using internally. In a production environment you’ll want to have HTTPS on the public listener. When creating the HTTP setting to use for this routing rule we want to override the host name to that of the App Service (in this case, “private-webapp.azurewebsites.net”) because remember that private link needs to be called using a DNS name and this way we can add that host name to the request header.
*Note* Since we deployed a Private DNS Zone, which is automatically attached to our virtual network, and the application gateway is deployed into the virtual network, we can use the DNS name of the app here because it will resolve correctly. Though, for clarity in this lab environment I’m just using the IP address.
After the Application Gateway is finished deploying I want to go add a DNS label to the public IP which is associated and confirm that it was applied so I can use that DNS name rather than the IP itself.
Okay, moment of truth! Remember the machine we used earlier that used the public path to get to the app service but got a 403 error because of the access restrictions? Let’s go ahead and try hitting the newly provisioned Application Gateway that does have a public listener and try the site now. We see that it’s using the DNS label and subsequent HTTP listener that we setup on the App Gateway, using the public interface and is routing us appropriately back to our private web app!
That’s all folks! As a retrospective, here’s what we’ve done:
Configured an App Service with Hybrid, Private Networking
Configured a scalable public endpoint that’s using a WAF in an IDS mode
Maintained the flexibility, scalability, and cost effectiveness of the non-ASE App Service
If you have any questions or suggestions for future blog posts feel free to comment below, or reach out to me via email, twitter, or LinkedIn.
10/8/20: Private Endpoints for App Service Web Apps now GA