Install an App Service with a Private Endpoint with outbound traffic routed through a Firewall and inbound traffic coming through an App Gateway.
In the /terraform folder are a selection of tf files. You will need to have terraform installed (I am running v0.12.24 on Powershell Core 7).
run terraform init
in a powershell prompt and then run the setup powershell script here, this script runs the terraform apply
and then deploys the sample app to the website.
The resource prefix and the location are defined as variables and you should provide new values (particularly for the prefix).
The resources can be cleaned up by running terraform destroy
- 2 resource groups
- 2 virtual networks (peered)
- 5 subnets
- A storage account with table storage accessible via a private endpoint
- A private DNS zone to allow resolution of the storage private endpoint
- An App Service (Website + plan) running a simple node application, public access is restricted through the firewall, network access is allowed through a private endpoint. (Note: private endpoints for web apps are currently in preview and limited to Premium V2 App Service plans)
- A Firewall that all outbound network traffic is routing through
- An App Gateway that all inbound traffic to the app service is routed through.
- A request comes into the Application gateway public ip address.
- The Application gateway uses the private DNS zone to resolve the web app.
- The private DNS zone resolves to an internal address for the web app.
- The Application gateway calls the web app over the vnet.
The application that gets deployed makes calls to http://httpbin.org/ip to retrieve the outbound ip of the server making the call.
By default a website with a vnet intergration will always go direct for outbound internet calls (using the app service shared outbound ips). By adding the WEBSITE_VNET_ROUTE_ALL=1
setting it will use the UDR applied to the subnet.
- The website has a private endpoint nic allocated to the web subnet.
- The web_se subnet contains a UDR that routes all traffic to the Azure Firewall.
- The firewall contains application rules that allow traffic to httpbin.org (for the running application), github and npm (for the application build).
The /ip
route on the website shows the call to httpbin.org/ip is successful and should also return the IP address of the firewall showing the request has been routed.
- Website requests a MYSTORAGE.table.core.windows.net address. By default this would resolve to the public ip address (which is locked down)
- The website is configured to point it's DNS requests at the internal azure DNS Server 168-63-129-16. (https://docs.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16). This uses the new
WEBSITE_DNS_SERVER
app setting in the web app (https://docs.microsoft.com/en-us/azure/app-service/web-sites-integrate-with-vnet) - The Azure DNS is aware of our Private DNS Zone so forwards the request there.
- The private DNS zone is configured to resolve the privatelink address to an ip address on the vnet.
- The web app can now communicate directly with the storage account over the private endpoint ip address.