Jason Specland: An Occasionally Funny Software Guy

Making it up as I go along. Always.

When is an App Service not an App Service?

When is an App Service not an App Service? When it's an Application Service Environment with its own Internal Load Balancer on your internal Virtual Network.

(It's very un-Microsoft of me, but I actually spelled out the acronyms I'm about to use. But from now on, let's call it an ILB ASE.)

There are many online tutorials for setting up an ILB ASE to respond to requests over the public Internet by using an App Gateway. Here's an Azure Friday with Christina Compy from the product group. Here's a blog writeup from the Azure Tech Guy.

But I didn't read those. I did read the ASE docs and the guide to integrating ILB ASE with App Gateway and all of the App Gateway documentation.

This is not a tutorial about setting up the ILB ASE with App Gateway. It's an exploration of what I got wrong when learning to set it up in hopes that my misconceptions can lead to a deeper understanding.

The big idea of what I was trying to create is this:

ILB ASE with App Gateway high-level view

When I first tried to build this, I thought, "Hey! I'm a smart guy! I should be able to figure this out, and then refer to the documentation when I can't." Following the documentation, I created an ILB ASE, created an App Service Plan in the ASE, and a Web App in the App Service Plane.

I set up a Windows 10 machine inside the VNet to test accessing the ASE directly, and to use as an Azure Piplelines build and release agent. I fired up a Linux box to serve as the DNS server for the VNet (because I used to be a UNIX guy and spent way too much time configuring BIND) and created the DNS zones for myase.appserviceenvironment.net and myase.scm.appserviceenvironment.net. I followed the ILB ASE DNS configuration documentation. That part worked great. I could access the web apps on my ASE from my internal VNet.

Now, to make the app visible from the outside. To that, I turned to the App Gateway.

Misconception One: If I Select the App Service for My Backend Pool, App Gateway Knows How to Reach It

All of the guides on the internet properly say to put the ILB ASE's internal IP address as the target. But I cocksurely skimmed those guides, and saw that in the dropdown, I could select "App Services." Hey! An App Service Environment is an App Service, right? And when the UI changes to select an App Service, the App Services in the ILB ASE appear as selectable items. SCORE!

The wrong way to set up the App Gateway backend pool in Azure Portal


It's very helpful, but it doesn't work. It's asking for a "valid internet hostname." My ILB ASE has a hostname, but it's only available on my private DNS in my VNet.

I assumed that showing the ILB ASE websites in this menu meant that App Gateway knows how to reach them by looking up the IP address associated with the ILB ASE they belong to. But it doesn't, and that's why all the examples specifically tell you to enter the private IP address of the ILB ASE here.

Misconception Two: The Host Name in the Listener Refers to a Backend Pool

App Gateway Listener settings blade in Azure Portal

I mean, with a tooltip like that, can you blame me?

The "Host name" here refers to the hostname that the App Gateway (and not the ILB) will be listening for. Just like the ILB (and App Service in general), App Gateway listens on one IP address and port for multiple websites, and distinguishes between them via the host header.

Misconception Three: HTTP Settings Can Resolve Internal Hostnames

App Gateway HTTP settings pool blade in Azure Portal

That "Use for App service" setting is so tempting to click! And when I did, it automatically selected "Pick host name from backend address for you." Makes sense, if your logic works like mine.

My Logic: Since I selected the Web App in the dropdown, Azure knows all about it. It knows it's associated with an ILB ASE, it knows the ILB ASE's internal IP address (misconception one) and it knows what host header the web app is expecting.

Azure: WRONG! I can't resolve internal DNS names. You have to give me an IP. And since the backend address is an IP, I have no idea what to put into the host header if you select "Pick host name from backend address."

The HTTP settings can get the proper host header in one of two ways:

  1. The host name of the Web App in the ILB ASE is the same as the one used for the App Gateway's listener as described above.
  2. You specifically override the host name to be the one the ILB ASE Web App already knows about, be it the appserviceenvironment.net name or one you created yourself.

Misconception Four: The Host Part of the Health Probe is Resolved

App Gateway Health probe blade in Azure Portal

Putting the internal hostname here does work, helping enforce the misconception that the App Gateway can resolve internal DNS names if they're associated with an App Service through some Azure Magic. But this is not so. The "Host" here is only what's put in the host header. It is the settings in the backend pool that matter, and the backend pool needs the internal IP address.

What you can do here is check the box that reads "Pick host name from backend http settings." If your HTTP settings know what to use for the host header as described above, then the health probe will use those settings.

Misconception Five: The ILB ASE Needs to Know About the External Host Name

All of the tutorials I've found, including the one I linked to, tell you to set your custom domain in your web app in the ILB ASE and upload the certificate there. But that's not necessary anymore. The ILB ASEs now come with an appserviceenvironment.net hostname, and Azure is loaded with a wildcard cert for that domain. The internal web app doesn't need to know a thing about the external hostname or certificate.

Diagrams: The Right Way to Do It

Configure the listener: proper configuration of the App Gateway listener

Configure the backend pool: proper configuration of the ILB ASE backend pool in the App Gateway

Configure the http settings: proper configuration of the http settings for the ILB ASE in the App Gateway

Configure the custom health probe: proper configuration of the health probe in the App Gateway

Performances and Classes This Week

Friday, May 31, 2019

(Hey, that's tonight! I'm really bad at promoting things!)

My Armory improv team, "Falcon Toss" will be performing in the Armory's house team night. 9:30 PM at The Tank theater, 312 W 36th St.

It's our second-to-last performance of the season! So if you miss this one, you might have only one more chance to catch Falcon Toss before we're gone forever.

Saturday, June 1, 2019

(Hey, that's tomorrow! I'm really bad at... oh, I mentioned...)

I will be teaching a Drop-In improv class for The PIT from 6-9 PM at Simple Studios, 134 W 29th St., 2nd Floor. Cost is $20 cash.

The Result of my Cheapo Blog Experiment

Much has changed since I decided that I'd like to save money on my blog hosting costs.

Most notably, I started working for Microsoft. If I thought I was spoiled by my $150/month MSDN allowance... Man, oh, man, an MS Internal Subscription is very "kid in a candy store."

After a bunch of fits and starts, I follwed the path of least resistance: I exported the blog from WordPress, and created a static site with Gatsby.

At first I considered using ASP.NET Core and Cosmos DB. Cosmos is wonderful, but expensive. I remembered what Scott Hanselman said about not requiring a database. Cosmos is awesome if you need NoSQL with instant, worldwide replication and guaranteed throughput. My humble blog needs no such luxuries.

While I was pondering this, Microsoft released a better, cheaper option: Static website hosting in storage accounts. This is awesome because storage accounts, especially with locally redundant storage, are super-cheap.

There were still a few challenges to overcome. I wanted to do both HTTPS and use my custom domain, which storage account static hosting doesn't allow. So I stuck the lowest level of Azure CDN in front of it. For a relatively low-traffic website, the cost of that won't be an issue.

I've been having all kinds of fun with Gatsby itself. Rewriting all of my website's widgets in React has been kind of a fun challenge.

To update the blog, I've got an Azure DevOps project setup to automatically rebuild the site whenever I commit to master. The pipeline runs Gatsby, and sticks the resulting static HTML into my storage account. Easy peasy...

Okay, not quite so easy-peasy. In order to get completely off of WordPress, I had to get my wife's blog onto Gatsby as well. The translation from her WordPress to Gatsby was no more difficult than my own. But now I have to teach my non-technical wife how to use Markdown, Visual Studio Code, and Git. To her eternal credit, she seems game for the idea. We shall see how game she is once she tries to post her first post-migration post. I may have been penny wise and pound foolish in this regard...

However, it does appear that I was extremely penny wise, indeed. Only half-way through the billing month, but my monthly spend so far is forecast to be $2.07. Way, way down from the $100+/month I was spending to host Wordpress.

A New Job!

As many of you may have noticed* I have been kind of quiet as of late**. Well the very big reason for that is because I’ve been busy hunting for a new job.

I’ve just completed my very first week as a Cloud Solution Architect for Microsoft. I am absolutely over-the-moon excited about this amazing opportunity. I’m still drinking from the firehose of figuring out this enormous company and my role in it, but thus far everyone’s been absolutely delightful.

* No one noticed, because no one reads this blog. It’s just for me.
** I also almost never post on it, so how would you (which is to say no one) ever know if I was quiet or not?

My New Project: The Cheapo Blog

I work for BlueMetal, and we’re a big Microsoft partner. In fact, we’ve been partner of the year for the past three years running. That means that I build a lot of stuff in the Azure cloud. I’ve come to like it a great deal. I’m amazed by how simple it is to create super-powerful infrastructure at the click of a mouse, or the deployment of an ARM template.

I was so impressed with Azure that I moved my personal WordPress blogs from Dreamhost to Azure. That… was a bit of a mistake. Not because the performance was bad. It was quite good, in fact. But the problem is that even when sharing an App Service Plan between all of my blogs, using the Azure cloud as a private person who is not a corporation can get a bit expensive. My WordPress hosting costs shot up from about $10.99/mo. to about $80. Now, I had a ridiculous deal on Dreamhost. (Crazy Domain Insane, I believe they called it.) I’m certainly getting a bit better performance, and I could trivially scale it up. But that’s a lot of cash to spend every month.

A reasonable person would say, “Dang, let me migrate my blogs right the heck back to Dreamhost!” I am not a reasonable person.

Using only Azure resources, can I create a new blogging system that has performance that’s equal to or better than my WordPress blog, while still being way, way cheaper? I bet I can. It won’t be functionally competitive with the gigantic WordPress ecosystem, but I don’t use most of the stuff in the gigantic WordPress ecosystem. I’m just a simple country blogger.

Now let’s add another degree of difficulty on to this project. At work, I have a Visual Studio Enterprise subscription, with that delicious $150/month in Azure credits at my disposal. And let me tell you, I use that stuff all the time. In fact, since I’m working on different projects with different configurations, I don’t develop on my work laptop anymore. Any time I need a new work environment, I build one from scratch by building out a new VM in the Azure cloud. Easy peasy!

The downside is that I’m used to mindlessly building infrastructure on Azure, but never having to deal with the bill. For this project, I’m going to see if I can do this entirely on my own, with only my own money, using absolutely no resources that belong to my employer, and nothing that is unlicensed in any way.

There are several challenges involved in this. The first one is most obvious: I don’t actually have a Windows PC at home! What can I say, my family went all-in on the Mac a few years ago. My instinct would be to just fire up an Azure VM with Visual Studio and RDP right into it. But that would eat up a fair amount of money that I don’t want to spend.

Fortunately, my Mac is entirely capable of writing .NET Core web services using either Visual Studio for Mac or Visual Studio Code. I fooled around with Visual Studio for Mac for a little bit and it didn’t thrill me. It’s great for Unity (which I’ve dabbled in) and Xamarin (which I haven’t). But I’m building web apps, and VS Code is extremely capable for my purposes, so I’m going to go with that.

And so begins the adventure! Wish me luck!

Classes and Performances – August and September

I’ll be teaching the following drop-in classes at the PIT:

Sun, 8/12: 6-9 PM
Sun, 9/2: 6-9 PM
Fri, 9/7: 7-10 PM

As per usual, the classes take place at Simple Studios, and cost $20 in cash. See you there!

I’m going to be on vacation for two weeks in August, so I won’t have many performances, but my Armory team, Falcon Toss (caw!) is performing on:

Fri, 8/31: 9 PM
Fri, 9/14: 9 PM

As per also usual, the shows take place at The Tank and cost $5 in cash or $6 with a credit card. See you there, too, hypothetical person who goes to all of my stuff!

Upcoming Performances and Classes in July

I’m going to be teaching the following PIT drop-in classes:

Saturday, 7/21, 6-9 PM
Saturday, 7/28, 6-9 PM
Saturday, 8/4, 6-9 PM

All drop-in classes are at Simple Studios, 134 W. 29th St., 2nd Fl. and cost $20 per person.

I’m also going to be performing in the following shows:

Sunday, 7/22, 8:30 PM I’ll be performing with “Gritty Reboot” as part of the “Moviepassers Premiere Night” show at the PIT Loft, 154 W. 29th St. (between 6th and 7th Ave.). $8

Friday, 7/27, 9:30 PM I’ll be performing with “Falcon Toss,” my new house team at The Armory. The Armory shows take place at The Tank theater, which is at 312 West 36th St. $5

See you there!

Drop-In Improv Classes at the PIT: June

I’ll be teaching the following drop-in improv classes at the PIT. All classes are at Simple Studios, 134 W 29th St, 2nd Floor, and cost $20.

_Please note that the times of Saturday and Sunday drop-in classes have changed. They now run from 6-9 PM.

Objects Have Power Friday, June 15, 7-10 PM
Building a Character from the Outside In and the Inside Out Sunday, June 17, 6-9 PM
Building a Character from the Outside In and the Inside Out Friday, June 29, 7-10 PM

For more information, and the complete PIT drop-in schedule go the Drop-In Practices page on the PIT website.

See you there!

POSTPONED – Upcoming Workshop at the Armory

This workshop has been postponed. I will update here when a new date has been chosen.

I’ll be doing my “Listening and Reacting with Emotion” workshop on Sunday, May 27th, from 1-4 PM at Simple Studios. The workshop is associated with the Armory, and not the PIT who is my usual employer. But just the same, any old person can join in for the usual price of $20. (Armory Performers only pay $12! So if you’re an Armory performer, and have been waiting to take one of my workshops, this would be a super-great chance!)

Sign Up Here!

Upcoming Classes!

I’ll be teaching the following PIT Drop-In Classes. All classes are at Simple Studios, 134 W 29th St, 2nd Floor, and cost $20.

_Please note that the times of Saturday and Sunday Drop-In Classes have changed. They now run from 6-9 PM.

Objects Have Power Friday, May 11, 7-10 PM
Invest, Don’t Invent Friday, May 18, 7-10 PM
Listening and Reacting with Emotion Sunday, May 20, 6-9 PM

See you there!