Azure App Service Environment v3

Radosław Wiankowski
rwiankowski
Published in
6 min readJul 13, 2021

--

Picture from the Azure App Service Team Blog

I love Azure App Service. It’s a versatile offering that allows us to deploy a broad spectrum of applications without running Virtual Machines. And while I fully acknowledge that VMs are always there and that most applications still need them, I rather someone else manages them. So, if possible, I’ll always choose PaaS over IaaS.

However, App Service has one limitation, which has been a big issue for me — it doesn’t, or to be precise — didn’t, support zone redundancy in a way that is accessible for most customers. Having worked with Azure for a few years now, I’m familiar with the concept of a Cloud Service, and I remember when Availability Zones were introduced, so the limitation didn’t surprise me. Still, I wouldn’t say I liked it.
The SLA on App Service (99,95%) is excellent, but an SLA is a just contractual promise. Zone-redundancy, on the other hand, is uptime by design, and most customers want it.

One might, of course, say that we were able to deploy a zone-redundant implementation of Azure App Service using App Service Environments(ASEv2), and they would be correct. But, we would have to deploy at least two ASEs — each pinned to a different zone, then deploy separate App Service Plans, independent App Services, etc. With the stamp fee of around 950 EUR/month per ASE, both cost and complexity went through the roof.

With all the above, you can probably imagine how excited I was when Microsoft announced ASEv3 late last year. The new version is based on a new architecture and promised significantly reduced complexity, native zone redundancy, and to remove the dreaded stamp fee. And now the long wait is over — App Service Environment version 3 is Generally Available. So I took it for a ride, and I’m here to share my findings.

To set off on the right foot, I wrote a simple Bicep template:

AppServiceEnvironment.bicep

The template doesn’t contain too many specifics and should be relatively easy to read. I default zone-redundancy to true, but you can always override the parameter. The aseLbMode is probably the only parameter that requires a bit of explanation.
We can deploy the ASE with an internal load balancer or with an Internet-facing one. I wanted the former, therefore set the value to “3”, but if you’d like a Public IP, you can override the parameter and set it to “0”. Be mindful that it takes an integer, not a string, as input.

The deployment takes a very long time — I’ve tried a few times and have seen results between 2:15 and 3:30, with an average time around 2 hours 45 minutes. So hit run, and find yourself something else to do, while you wait.

Once the ASE is ready, we can deploy an App Service Plan. The ASE will be listed with Azure Regions in the location selector if you’re doing it through the portal. That can be a bit hard to find the first time around, so be mindful. Naturally, I opted for another Bicep template:

AppServicePlan.bicep

Once again, it’s a reasonably straightforward template, but you might find two strange things in there. I like to pass the SKU as an entire object, and I use a small trick with a variable to make the hosting environment optional.
This resource took between 10 and 20 minutes for me to get deployed.

At this point, we are done with any ASE specific adjustments. I used the portal to deploy a .NET 5 Linux App Service without any unique settings.
The beauty of this setup is that we don’t need any particular configuration as far as the network goes — no access restrictions, not regional VNET integration, no problems.
If you were going for an entirely internal setup, you could now configure DNS, and you would be good to go. I, however, wanted to replicate a topology that we see very often with our customers, so I added an Application Gateway.

The gateway is again very standard, and because I was lazy, I also went with the GUI experience. To make the whole setup work as I wanted it to, I finetuned the following settings.

In the backend configuration, instead of choosing App Service, I selected “IP Address or FQDN” and passed in the internal VIP of the App Service Environment:

The IP Addresses tab of the ASE
Application Gateway Backend Configuration

And in the HTTP Listener, I configure a custom host header (domain name) and pass in the URL of my App Service. I chose HTTPS as the protocol and trused the built-in certificate. All other settings I left with default settings.

Application Gateway HTTP Setting

If you’re unsure about the address, you can find it in the overview of your App.

App Service Overview tab

And that was it. The backend reported as healthy, and I was able to browse my application. Once again, my laziness kicked in, and I settled for unencrypted HTTP on the Frontend configuration. Configuring SSL certificates and DNS is your typical AAG setup and wasn’t my focus with this experiment.

A vanilla .NET 5 app running in my ASE v3

Overall, I’m delighted with the outcome. Configuring a secure, zone-redundant App Service implementation is straightforward, and I didn’t experience any nasty surprises. The process does require patience, as the App Service Environment and the App Service Plan can take half a day to get deployed, but it is a single-tenant infrastructure, so I understand.

One thing that I am not sure about at the time of writing is pricing. The GA announcement and the documentation state that for a zone-redundant ASEv3, we will pay the cost of at least nine (9) instances of the I1v2 App Service Plan. However, the portal GUI indicates that we will need at least three (3) instances of an Isolated v2 App Service Plan. Nine would get us above 3200 EUR monthly (with Azure West Europe as my pricing reference), and that is extremely expensive if zone-redundancy is the only thing you’re after. Three still make it quite costly, but it makes sense given that we have three availability zones. I’ve asked Microsoft to clarify and will update this article accordingly. You can track the issue here:

If you’d like to use any of my templates, you can find them on GitHub, and if you have any exciting findings regarding the new ASEv3, reach out.

--

--