In the previous post, I talked about how a Function App deployed in Consumption Plan cannot be deployed in a network-locked architecture. In this post, I will try to reach the same objective of deploying a Function App where all the components used by the app are not accessible from the public internet using App Service Plan. I will go through the deployment process, where I will be verifying the hosting through Kudu Tools and dive deep into the DNS (Domain Name System) workings with the Function App by showing an end-to-end example of how Key Vault references can be integrated with the app. Finally, I will wrap up this post with an architecture diagram of the complete solution.
This post is a part of a series outlined below:
- Consumption Plan – talks about how a Consumption Plan can be used to architect a network-locked solution.
- App Service Plan (this article) – describes the usage of an App Service Plan and how effectively a complete network-locked architecture can be deployed.
- App Service Environment – outlines the solution with an ASE (App Service Environment) v3 by covering similar effectiveness.
Please refer to the previous post to understand the scenario using the simple architecture diagram as shown below.
Figure 1: A simple architecture for the scenario
Some of the important points to be noted from the scenario are:
- There is an empty
AspSubnetinside the Virtual Network which can be used by the App Service Plan for any networking-related purposes.
- The Virtual Network used in this scenario is configured with Azure-provided DNS service as the DNS servers can be accessed via the public IP (Internet Protocol) address
Let us revise the objective that I will try to reach in this post. The expected outcome is as follows.
A Function App that is using the network-locked Storage Account (
stblogazurewebjobs01) as the web jobs storage and can access network-locked Key Vault (
kvblogdev01) secrets without exposing any functionality to the public internet.
With this objective in mind, let's look at a solution that deploys the Function App in an App Service Plan.
App Service Plan
I will now explore the next deployment offering by Azure - App Service Plan or Functions Premium. I am going to target the App Service Plan in this post because both offerings work the same so the process mentioned below will also work for Functions Premium.
In App Service (Web Apps, API (Application Programming Interfaces) Apps, or Mobile Apps), an app always runs in an App Service Plan. In addition, Azure Functions also has the option of running in an App Service Plan. An App Service Plan defines a set of computing resources for a web app to run. These compute resources are analogous to the server farm in conventional web hosting.
Following the same deployment steps, as shown in the previous post, upon choosing the same network-locked Storage Account, I should be able to complete my deployment with an App Service Plan. The application settings shown below indeed prove that the network-locked storage account is being used as the
Figure 2: Network-locked storage account being used as AzureWebJobStorage
Next, let us dig deep to check whether the Function App is hosted properly or not.
Is the Function App hosted properly?
The best way to verify if a Function App is hosted properly is to check its function URL. If the function URL can resolve and gives you a default Azure Functions page, then the first check is passed.
As shown below, I can see that the function URL can resolve, and I can see a default page.
Figure 3: Default Azure functions page
Next, I will check if I can access Kudu Tools. Kudu is the engine behind several features in Azure App Service related to source control-based deployment, and other deployment methods like Dropbox and OneDrive sync. As my app is not in the Isolated tier, I can access the Kudu using
https://<app-name>.scm.azurewebsites.net as shown below. I can access the Kudu tools, so the Function App hosting is working properly.
Figure 4: Kudu tools home page
The last check I will do is run a simple
HttpTrigger that can verify if the
AzureWebJobsStorage is working as expected. Upon creating a simple
HttpTrigger with the default template and using the
Code + Test section to run it, I start seeing the
Azure Functions Runtime is unreachable exception as shown below.
Figure 5: Azure Functions Runtime is unreachable
I can also see that I am not able to get the function URL as both Key and URL are coming up blank. Note that I have already verified that basic hosting is working by accessing function URL and Kudu Tools via the public internet, yet the Azure Function Runtime seems to be having trouble communicating with my network-locked Storage Account.
Figure 6: Get function URL is blank
The reason is simple - my Function App does not have access to the Virtual Network. As the Storage Account is only accessible from the inside of the Virtual Network, I need to enable the connection between my app to the Virtual Network using Regional virtual network integration.
Regional Virtual Network Integration
As per Microsoft’s official documentation, I can use regional virtual network integration to allow access to resources that are network locked. I will use this feature to solve my problem. As mentioned in the above objectives, we already have an
AspSubnet specifically created for this use case.
Figure 7: Regional Virtual Network Integration in the Function App
Once I have completed the virtual network integration, my Function App should be able to access network-locked resources inside the configured virtual network. Going back to my simple
HttpTrigger, I can access the function URL correctly as shown below, which means the Azure Functions runtime is working as expected.
Figure 8: Get the function URL working now
I can also execute my
HttpTrigger using Postman, which means that the Function App is hosted successfully and is also able to use the network-locked Storage Account as
Figure 9: HttpTrigger of the Function App working now
But, what about DNS resolution? The networking architecture emphasised the need for a properly working DNS. I can verify whether the DNS resolution for the Function App is working as expected by creating a Key Vault reference in the application settings and verifying whether it is getting resolved or not.
Testing DNS with Key Vault References
As per the current architecture, I have a network-locked Key Vault, which is only accessible from inside the Virtual Network. It also has a private endpoint configured with a private DNS zone which can be used for DNS resolution. As the Function App is now Virtual Network integrated, can it access a secret from this network-locked Key Vault by properly resolving its URL?
As per Microsoft’s tech blog, I can use some networking-related commands in Kudu Tools to check the DNS resolution of the Azure resources. Let us try to use
nameresolver to resolve the network-locked Key Vault as shown below.
Figure 10: DNS resolution for the Key Vault
nameresolver, I got the private IP address of my
kvblogdeve01 Key Vault as
172.16.0.5 which is indeed matching with the DNS configuration in the private endpoint as shown below.
Figure 11: Private IP address using private endpoint
Finally, I will try to add a Key Vault reference to my app, and I should be able to resolve it. As shown below, the Key Vault reference has been resolved successfully.
Figure 12: Key Vault reference resolved successfully
In this post, I tried to reach the objective of deploying a complete network-locked App Service Plan-based Function App that is to leverage an existing network-locked architecture. This architectural solution is shown below.
Figure 13: Architectural solution with an App Service Plan-based Function App
Some important points about the Function App deployed using an App Service Plan can be listed as follows:
- The Function App is accessible from the public internet and can still access private resources inside the virtual network.
- The Function App is not deployed inside the Virtual Network. Rather, it leverages the architecture using regional virtual network integration.
App Service Plans or Functions Premium can work effectively with the network-locked Azure resources using regional virtual network integration. This integration also enables the app to work with resources that have private endpoints. But can I implicitly deploy the Function App directly inside the Virtual Network without using delegations? That is indeed the use case of App Service Environment which I will cover in my next post, and it is also the last part of this three-part blog series.
Cross Posted on Abhinav's Blog