Private Function Apps in Azure Government using App Service Environment (ASE)

Azure Functions is a platform for deploying serverless functions in a variety of different languages. It is easy to create APIs without having to worry about the underlying architecture and compute resources. In spite of the many advantages, they are not so easy to use for Government applications because they have a public endpoint that represents a potential attack surface and may be in conflict with Trusted Internet Connection (TIC) rules. The problems mirror the issues for public Web Apps; I have discussed this in some detail in a previous blog post.

Azure App Service Environment (ASE) is now available in Azure Government. I have written about the many advantages of ASE for Government Web Apps. Since App Service is the foundation of Azure Functions, it seems obvious to use an ILB ASE for hosting private Azure Functions in Azure Government. In this blog post, I will demonstrate that this is indeed possible and also show a few tricks to get it all working.

To follow along, you will need an ILB ASE deployed. You can use either Azure Commercial or Azure Government. I have posted an ASE template on GitHub, which you can use to get started. In addition to the ASE, you will need a VM on the same virtual network (or one that is peered) as the ASE. You can use my ASE DevOps template as inspiration or simply deploy a new VM into the same virtual network. If you need a wildcard certificate for your ASE, I have some instructions for getting a wildcard certificate using Let's Encrypt. Alternatively, you can use a certificate with several Subject Alternative Name (SAN) entries. It is also an option to use a self-signed certificate, in which case it is important that you import the certificate into your "Trusted Root Certificate Authorities Store" on the VM to avoid any SSL warnings or errors.

The goal is to have a setup as illustrated below:

 

We want an Azure Function App, which can only be access from the virtual network. You can create this Function App in the portal (hit the big plus sign and search for Function App). In the Function App wizard, select an App Service Plan in your ASE or create a new App Service Plan in the ASE and select it. After you have selected an App Service Plan associated with your ASE, you will see the domain suffix of the function app change to the domain name of your ILB ASE:

Once you have created the function app, you need to make sure that you have DNS entries for the app. For example, if your ILB ASE domain name is cloudynerd.us and your app name is function, then you need DNS names for function.cloudynerd.us and function.scm.cloudynerd.us. If you are adding this to your hosts file, it would look something like:

[plain]
10.0.1.11 function.cloudynerd.us
10.0.1.11 function.scm.cloudynerd.us
[/plain]

When you access the functions through the portal, you should now be able to add new functions and edit them in the portal. Here you see an example of inspecting the functions in an ASE Function App in Azure Government:

It is likely that you will have some problems accessing the functions from the portal. Specifically, it may say "inaccessible" in the Functions menu. If this happens you most likely have one of 4 problems:

  1. Your VM is not on the virtual network, e.g. you are trying to do this from your laptop.
  2. The DNS entries are missing either from your hosts file or your DNS server if you have a DNS server on the virtual network.
  3. The SSL certificate is not trusted. See above.
  4. The portal functions site is not listed in the CORS rules of your Function App.

If you are wondering which of the problems you are having, use the "Developer Tools" of your browser to look for error messages related to accessing the Kudu console of your Function App. The first three of the problems we have covered but the last one is a bit trickier. At the time of writing this blog post, the URL of the page requesting access to the Kudu console of your function app is https://functions-usgov-iowa.azurewebsites.us in Azure Government, but this site is not added to the CORS rules when you create a new Function App and you will get access denied. You can easily add that manually:

UPDATE 2018-4-01: Per comments by Mike Hacker, for functions in usgovtexas, you will also need to add: https://functions-usgov-texas.azurewebsites.us and https://functions.ext.azure.us. They have been added to the template mentioned below.

I have also created a template that will set up the Function App correctly for you. You can find it here. To use the template instead, you can create the ASE Function App from PowerShell with:

[ps]
$asp = Get-AzureRmAppServicePlan -ResourceGroupName "RG-FOR-ASE-ASP" -Name "ASP-NAME"

$templateParameters = @{
"appName" = "mihansenapp1"
"appServicePlanId" = $asp.Id
}

New-AzureRmResourceGroupDeployment -ResourceGroupName "functionapp" `
-TemplateUri https://raw.githubusercontent.com/hansenms/iac/master/primitives/functionapp.json `
-TemplateParameterObject $templateParameters
[/ps]

And that's it, you now have private Azure Functions in Azure Government (or Azure Commercial) by leveraging the isolation properties of the ASE. Let me know if you have questions/comments/suggestions.