Securing service traffic in Azure – Part 3

Securing service traffic in Azure

In Part 1 we looked at using private endpoints to secure access to a data source, from only our app service. In Part 2 I showed you how to achieve a similar result but using service endpoints. The same set of controls that recommends we secure everything, and led us down this path, also recommends that we implement application security. In this final part of the series of “Securing service traffic in Azure”, I will take the application configuration from Part 2:

And show you how to protect your traffic end to end by placing it behind a Web Application Firewall.

Web Application Firewall

A Web Application Firewall, or WAF, is a security solution that monitors, filters, and blocks incoming and outgoing web traffic to protect web applications from various cyber threats and attacks. From a high level:

  1. The client connects to the WAF
  2. The WAF inspects the request for malicious intent
  3. If OK, the WAF then forwards the request to the application layer

It is fair to say that the topic of Web Application Firewalls, best practice and their configuration is a large topic and not one covered here. As our focus is on securing service traffic in Azure, I will only be focusing on the basic functionality of the Microsoft WAF and the application gateway required to secure my application. For more detail on Microsoft Web Application Firewalls, you can read about it here.

The WAF capability requires a Microsoft Application Gateway with WAF enabled. I am going to step through the configuration of the Application Gateway and how to secure our function app behind it. Once secured with the application gateway, I can then apply additional security of the WAF policies to it.

Microsoft Application Gateway

Selecting “Microsoft Application Gateway” from the marketplace, I have given my application gateway a name, and as this is used purely for our testing, I have set the autoscaling to “No” and selected the smallest instance count. As the application gateway behaves like an external load balancer, it also requires a subnet to connect to in order to interact with internal services. This subnet is important to securing the app service completely behind the Application gateway.

For my front end, I have added a new public IP address and accepted the defaults:

The backend pool is where I link the App Gateway to the function app, so I have selected “App Services” from the target type, and then selected my function app:

Now that I have a front end and back end connection, the application gateway requires a routing rule to link the two together. I have given the routing rule a name of “forward_traffic” and a priority of 100. The routing rule needs a listener and a target. As this is about securing an app service behind a WAF, I will not delve into configuring HTTPS listeners. That is a topic for another discussion. For now, I will be using open HTTP over port 80 as our connection point:

I then need to configure the backend targets. My target is the pool created in the previous tab “bepool1”:

I am creating a new “Backend settings”. For this, I have accepted most of the defaults, however I need to link to the app service.

As the Hostname for the Function App continues to resolve even when the firewalling is complete, I pick the hostname from the backend target. This is for test/demo purposes only so I can ignore the warning.

Once this is all entered, I let the system create my application gateway. Testing with the IP address of the public IP, my datafile is returned:

Securing the Function App

The application gateway is now forwarding traffic through to the Function App, however, my function app is still responding to its FQDN:

To restrict the Function App, I need to go into the “Networking” settings and create an “Access Restriction”:

Enabling this will open a new blade of settings. As I am using service endpoints not private endpoints, I am leaving “Allow public access” enabled. For the site access rules, I have set the “unmatched rule action” to Deny, and then created a new rule:

For the new rule, I have linked it to my virtual network and subnet that is configured for the Application gateway. This generates a warning that there is no service endpoint. But when we finalise the configuration, the system creates it for us. Back to the main page and I save the configuration:

Now when we test access to my function app, we can see the firewall is preventing access:

However, when we test the application gateway again, you can see that the traffic is flowing as expected:

Now that the function app is secured behind an Application Gateway my configuration logically looks like this:

That just leaves us to inspect traffic as it passes through the application gateway.

Adding WAF policies

As I mentioned earlier, WAF configuration is a much bigger topic than I can cover here. For the purposes of this demonstration, I will be using defaults to demonstrate the theory only.

My first step is to create the WAF policy. From the market place, I have selected “Web Application Firewall (WAF)” by Microsoft. I have selected “Regional WAF”, given the policy a name, selected “Prevention” and then selected “Review and Create” to create the policy:

Once the policy is created, to connect it to the application gateway, I need to upgrade the Application Gateway from “Standard V2” to “WAF V2”. This is found under the “Web Application firewall” tab for our application gateway:

Here you can see I have selected my recently created WAF policy and then clicked save. To test the applied policy, I now try calling my function app with a SQL injection in the URL:

As you can now see, my application is not only secured so that only one external point exists for my data, it is also protected by an application firewall ensuring security and filtering

This is the final part in the series “Securing service traffic in Azure”.

Azure firewall basic is now generally available


On the 15th March, 2023 Microsoft announced the general availability of Azure firewall basic.

Azure firewall is a cloud native network security service that provides threat protection for cloud workloads running in Azure. It is a stateful service offering both east/west and north/south protection along with high availability and scalability. Azure firewall is available in 3 SKU’s; Standard, Premium and now Basic. All 3 versions provide the following features:

  • Built-in high availability
  • Availability Zones
  • Application FQDN filtering rules
  • Network traffic filtering rules
  • FQDN tags
  • Service tags
  • Threat intelligence
  • Outbound SNAT support
  • Inbound DNAT support
  • Multiple public IP addresses
  • Azure Monitor logging
  • Certifications

And while premium has additional features such as TLS inspection and IDPS, the Basic SKU has the following limitations:

  • Supports Threat Intel alert mode only.
  • Fixed scale unit to run the service on two virtual machine backend instances.
  • Recommended for environments with an estimated maximum throughput of 250 Mbps.

Where Azure Firewall Basic comes into its own is in cost to run. The Basic pricing model is designed to provide essential protection to SMB customers at an affordable price point for low volume workloads.

Approximate Costs

At the time of writing this article, the approximate retail costs for running Azure Firewall are:

Basic$0.592 (AU) per deployment hour
$432.16 (AU) per month
Standard$1.871 (AU) per deployment hour
$1,365.83 (AU) per month
Premium$2.619 (AU) per deployment hour
$1,911.87 (AU) per month
Recommended retail costs for running Azure Firewall

As you can see, Azure Firewall Basic is considerably cheaper than the Standard or Premium SKU’s just to turn on. But as mentioned previously, it is only for small workloads. The processing costs for data through Azure firewall basic are roughly 4 times more expensive.

If we look at processing 100GB in an hour the running costs would look like:

SKUCost per GBProcessing costTotal cost
(inc run cost)
Basic$0.098 (AU)$9.80 (AU)$10.39 (AU)
Standard$0.024 (AU)$2.40 (AU)$4.27 (AU)
Premium$0.024 (AU)$2.40 (AU)$5.02 (AU)
Recommended retail data processing costs

Clearly, sustained high workloads are much more expensive through the Basic SKU as opposed to the Standard or Premium SKU’s. The basic SKU is cost cheaper only when customers are processing less than 9,520GB per month, or 13GB per hour.


The new pricing model provides a much cheaper option for SMB customers to secure essential workloads at an affordable price where data volumes are low.