Deploying an ILB ASE + Application Gateway (WAF)
*This method of deploying an ILB ASE is now moved to (Classic)* I have the article on setting up the new ASE deployment here - https://www.azuretechguy.com/ilb-ase-new
This lab aims at deploying an ILB ASE from scratch, deploy and configure private DNS to serve the ASE, configuring the VNET, provisioning of the ILB SSL Certificate, creating Web Apps and exposing one of the web apps to the internet by using an Application Gateway in WAF tier.
By doing this you will gain knowledge in ILB ASE, SSL, Domain, private DNS, Application Gateway and WordPress deployment.
Table of Contents:
- Lab Pricing estimates
- Internet domain
- Resource Group
- DNS Server
- Installing and Configuring the DNS Server
- Configuring the custom DNS for the VNET
- Deploying the ILB ASE
- Creating and deploying the ILB Certificate
- Uploading the Certificate to the ASE
- Finish the DNS configuration
- Creating our first App in the ASE
- Creating an App Service Plan
- Creating an App
- Deploying a WordPress site with AzureDB
- Implementing Application Gateway with ILB ASE
- Configuring HTTPS through the Application Gateway
This is a serious and big lab so it takes time. Here is what actions we will be doing and ~approx. time
- Buying free internet domain ~20 min
- Creating the RG + VNET ~5 min
- Deploying a VM ~10 min
- Installing and Configuring private DNS ~20-30 min
- Deploying ILB ASE ~20 min + 1hour deployment time
- ILB Certificate ~25 min
- Post-ASE DNS Configuration ~5-10 min
- Deploying App Service plan + 1st Web App ~10 min
- Deploying WordPress site + exploring KUDU ~20min
- Deploying and Configuring Application Gateway ~1 hour + 30 min deployment time
Total ~ 3h
Here is what will cost you to keep the lab for 5 days of testing using Azure pricing calc.
Auto-shutdown after working hours so total hours for 5 days = 60
B2ms + disks x 60 hours = $6.29
ASE + I1 Isolated plan
I1 instance x 120 hours = $36
Stamp fees = 1.55$ x 120 hours = $185.48
Total = $221.48
Azure Database for MySQL
1x Servers x 120 hours = $4.78
5B Backup fee + LRS = $0.60 + $0.12
Total = $5.49
West Europe, WAF, Medium, 1 Instance
1 instance x 120 hours = $16.93
LAB TOTAL FOR 5 DAYS
- Valid subscription that is able to deploy the below resources
- ILB ASE + I1 isolated plan
- Internet domain name ($free)
- SSL Certificate covering the *. and .scm and domains ($free)
- Virtual machine with a DNS server role
- Application Gateway
Before we start doing anything. We want to have an idea of what domain we are going to be using for our ASE. Let’s go and create a free domain at freenom.com.
- Search for a domain name. The free domains end in .ml or .tk domains. So, whatever you like you can search for and click Check Availability
- In my case I will be searching for djo-ase and I am choosing .tk. Click Get it now! And go to checkout
- I am choosing for “Period” only 3 months. And I click Continue
- Then I will go through the registration process and will acquire the domain
- Once I have the domain, I can let it sit for now. We won’t be using it for a while. To manage the domain, log in with whatever email and password you registered in the previous step. Link here.
- By recommendation from Microsoft, it is not recommended to use the same domain name for the ASE and for your general use domain name but for this lab we will be using the same. The one you picked up above.
Let’s create the Resource group that will host the entire lab. We want it to be separate from anything else so it can be cleaned up easily later. Go and Create a Resource Group called ILB-ASE-RG in West Europe Region
Let’s first create the VNET. We want a VNET in the ILB-ASE-RG resource group so navigate to the resource group and Click Add/Create resources. Search and select Virtual Network OR click here.
The options I am choosing are the following: (based on recommendations from this official documentation)
Once the VNET is deployed, navigate to it and create a second Subnet called VM-Subnet with address range of 192.168.21.0/28
Because in ASE you want to take care of your own DNS, we will be creating a private DNS Server hosted on an Azure VM. Go and Create a VM using this link.
- Deploy it in ILB-ASE-RG
- Name it DNS-01
- Region West Europe
- No infrastructure redundancy required
- Image – Windows Server 2016 Datacenter
- Size – B2s or B2ms (a little more expensive)
- Username and Password of your choosing
- Allow Inbound ports – 3389
- OS disk type: Standard HDD The rest of the blade’s options remain default
- Virtual Network – ILB-ASE-VNET and deploy in the VM-Subnet
- Public IP – it will auto populate to DNS01-ip. The rest of the settings are default
- On the Management tab – Set up Auto-Shutdown so the machine can shut down after working hours.
- Go on Review + Create and click Create to deploy it.
Once the VM is deployed, log in to it and open the Server Manager. Click on “Add roles and Features”. Skip the first “Before you Begin” wizard by clicking Next.
- Role-based or feature-based installation – Next
- Leave the default Select server from the server pool – Next
- Select the DNS Server checkbox and Add selected features on the popup. Also ignore the warning for no static IP. Click Next
- On the “Select features” menu, do not select anything, just click Next. Then click Next on the next screen.
- On the last screen – Install
- Once the installation succeeds – Close the install wizard
- Go back to the Server Manager and click on Tools and select DNS
- Click on the DNS icon and expand until you see the “Forward Lookup Zones”. Right-click and select New Zone
- Choose Primary zone
- Name it with the same domain name you picked up from freenom.com. In this example it is djo-ase.tk. Click Next when ready.
- Click Next on the next screen and again Next on “Do not allow dynamic updates” and in the end Finish. Now we have created our DNS primary zone for the djo-ase.tk domain
Now that we have a custom DNS server ready for serving requests – let’s change the DNS Server for the VNET from Azure-managed to custom – our own DNS server we just configured.
- Pick up the private IP address of your DNS-01 server from the Overview blade on your VM
- Browse to your ILB-ASE-VNET and go to DNS Servers blade. Click on “Custom” and put the private IP address of your DNS-01 VM and click Save.
- Restart your DNS-01 VM
- Once the VM is back online, log in to it. Open CMD and type ipconfig /all. Confirm that the DNS Servers is your own private IP address
- Ping google.com to confirm resolution. If you see an IP address in your reply, it means that your DNS resolution is fine through your new private DNS Server. You can also try browsing different public domain names in a browser
So far this is what we have:
- We have a resource group and a VNET with 2 subnets in it. A VM deployed to the VM-Subnet with a DNS role serving DNS requests for the entire VNET. Click below image to enlarge
Now that we have a Domain name, Configured DNS Server and a VNET, it’s time to deploy the ASE – Click here.
- Deploy in the ILB-ASE-RG resource group
- Name your ASE in your own fashion
- Choose “Internal” type
- Domain – the domain name you have picked up from freenom and configured as a primary DNS zone in your DNS Server
- Click Next to proceed to Networking
- This should auto-populate with the ILB-ASE-VNET and the ILB-ASE-Subnet that we created previously. If not, choose them manually
- Click Review and create. Check that your info is correct and click Create to start deploying
- It will be deploying for ~ an hour. Move on to the next chapter while your ASE is deploying (if you can)
While/Once the ASE is deployed, we need to take care of the ILB Certificate. In ILB ASE, the domain name you choose will be inherited by all your future Web Apps. In our case the domain is djo-ase.tk so any future app’s domain will be WebappName.djo-ase.tk. So this is best done by covering every subdomain of djo-ase.tk. This means that we need a wildcard * certificate covering the *.djo-ase.tk. However, we need to cover the KUDU websites (scm) too so alongside the *.djo-ase.tk, we need to order our certificate with an additional SAN to cover *.scm.djo-ase.tk as well. Also good to note that in an ILB ASE all requests to the Web Apps inside that ASE will be handled and distributed by the ILB (Internal Load Balancer) and this is the reason we will be uploading this Certificate on the ILB and not individually on each App Service plan/Web App.
Let’s go and get ourselves a real and valid wildcard certificate from Let’s Encrypt for free.
- Now in a new tab, go to https://my.freenom.com/clientarea.php?action=domains and click on “Manage Domain” against your domain. Then choose “Manage Feenom DNS”. This should lead you to your domain DNS zone where we can create some records required by Let’s Encrypt to provision the SSL Certificate. Leave the tab opened.
- Go to https://www.sslforfree.com in a new tab.
- In the input bar type “*.djo-ase.tk, *.scm.djo-ase.tk” (in your case use your chosen domain name but keep the format the same). You can copy my example without the brackets and paste in your own page and just replace my domain with yours.
- Once you click on Create Free SSL Certificate, the page will load with 2x TXT records that you will need to create. Use copy/paste to copy the values from the Let’s encrypt page to the freenom DNS. Don’t worry about the TTL – 1. It’s fine even if you can’t specify it in freenom. In the end it should look like this:
- Wait for some time for propagation. You can use the links to test if records are recognized ok
- When both verifications return “TXT Record(s) Found”. You are ready to proceed
- Click on Download SSL Certificate
- This will load another page and at the bottom there is a Download All SSL Certificate Files button. Click it.
- This will download a .zip file which you will save somewhere on your workstation
- Extract it to a folder
- We now need to convert these certificates to a PFX file
- Go to https://www.sslshopper.com/ssl-converter.html
- “Type to Convert To” change it to PFX/PKCS#12 and additional fields will show up
- For Certificate file to Convert on top choose the crt file from the extracted zip. Note that selecting this will remove the extra fields on the web page as it is buggy. Re-choose “Type to Convert To” and change it to PFX/PKCS#12 again
- For Private Key File choose key
- For Chain Certificate File choose the crt
- Go down to the PFX Password field and type your PFX password that you will use for this certificate. Remember it
- Click Convert Certificate
- This will download a pfx file on your workstation. You might want to rename it to your domain name.pfx for easier recognition
- You may close the Let’s Encrypt page, and the SSL convert page
- Go to your ASE. You will find a blade called ILB Certificate. Click on the Update ILB certificate button
- Choose the pfx file we converted in the last steps and put the chosen PFX password. Click Upload. If it comes up with an error, refresh the blade and see if the certificate has actually uploaded anyway. Try again of it hasn’t. I had some issues uploading the certificate right after the ASE creation and it miraculously turned out that it was uploaded after some re-tries a little bit later. I think it will fail with "no HostingEnvironments" error if you try to upload too early after the provisioning itself has finished*
- You want to have the ILB certificate visible in the blade like this:
*Try in 1-2 hours if it continues to fail. It should succeed later on.
Now that we have the ASE provisioned (still ok to proceed if you don't have the ILB Certificate uploaded), we are ready for the final bit of private DNS configuration. Inside the ASE, we have a DNS resolution from the private DNS server we deployed and configured. We created a forward lookup zone called “djo-ase.tk” which means that everyone inside the VNET will be resolving this domain based on the DNS records we have in our internal lookup zone. Let’s make some DNS records
- Log back in to your DNS Server VM – DNS-01
- Go back to the DNS Manager (Server Manager -> Tools -> DNS)
- Browse to your domain’s forward lookup zone
- Switch back to your Azure portal and go to the ASE and IP Addresses blade. There you will find your ILB IP address. Copy it and go back to the DNS Server VM and your DNS Manager.
- Now the zone has no records and we will be creating an A record, just like in a Public DNS zone. However, knowing that in our situation, we want to be resolving automatically any subdomain of our domain, without having to do any further DNS records, it is best if we just cover all subdomains (meaning all possible apps that we create in the ASE) with one record. We will treat it just like the ILB Certificate and create an A record with wildcard (*) that points to the ILB IP address. In my case - * - pointing to 192.168.20.11, meaning – point every subdomain to the ILB IP Address because the ILB will be distributing all the requests internally to the proper web apps.
- Here is how to create the DNS record
- While in the DNS Manager and selected the zone (as in the Screenshot above), right-click somewhere in an empty space in the right pane of the DNS Manager and select New Host (A or AAAA) record
- So only type * in the Name field and the ILB IP Address into the IP Address field and click Add Host, Ok and then Done.
- The result should be 1x A record with wildcard pointing to your ILB IP Address
- Now we need to take care of the scm subdomain separately
- Select the domain zone and right-click it. Select New Domain
- Type scm for new Domain. Click OK.
- This will create a subdomain zone for your main domain. Create an A record the same as the one we created in the main zone
Let’s test if the DNS resolution is working
- Open CMD and try to ping anything (even if it doesn’t exist) under your domain. For example: ping djo.djo-ase.tk
- The result should be like this, showing that we resolve the domain name to 192.168.20.11
- Let’s test it for *.scm. as well
- Remember, we do not seek response. We only care that it tries to resolve to the ILB IP Address. All seems to be working fine. We have no more work on the DNS Server. You may want to leave it logged however, as we are going to use it for more testing.
Once the ASE is deployed, everything else in terms of creating the web app feels almost the same as outside of an ASE. We need to have App Service plan inside the ASE that will be serving workloads for our apps. Remember, the ASE itself is only a portion of the PaaS environment that is reserved for you. Basically, Microsoft is giving you an App Services scale unit just for you. This means that after the ASE (ASE being just a scale unit) everything else is the same - App Service plans and Web apps on top of the scale unit.
Go to Create a resource and start creating an App Service Plan. You don’t have to be in the ASE to do that. You can also use this link to start the creation.
Note that for Location you can choose the ASE instead of normal regions. Once you select the ASE as location, the App Service Plan tiers change and you are only offered the ASE (Isolated – i1, i2 and i3) tiers. Choose Isolated I1 for cost saving.
- Choose Windows
- Click Review and Create. Click Create once the validation finishes.
Now that you have an App Service Plan (a VM to serve your workloads) it is time to create our first Web App. Create it the normal way or click here.
- When you select the correct subscription and resource group the App Service Plan/Location should automatically be the ASE App Service Plan. If not, select it manually.
- Note that when you select the ASE App Service Plan the domain for your web app changes from azurewebsites.net to your own ASE domain
- Click Create when ready
Let’s test it out. Since the resolution of our domain in the ILB ASE itself is only resolvable within the VNET, the only location from which we can open the web app is our DNS server. Go back to your DNS Server and open a browser. Try to browse your web app. Mine is just-app.djo-ase.tk
Does it work? If not, you might have missed some of the steps.
Let’s try with SSL (HTTPS). Does it work? No? That’s because we do have an ILB Certificate on the ILB but we still need to create bindings inside the web apps.
- Go back to your Web App and go to SSL Settings
- Click on Add Binding. Your only choices should be your App’s domain, the ILB Certificate and SNI binding. Click Add Binding
Your end result should be the binding:
Go back to your DNS-01 VM and try to browse your app again with https://
This time it works!!!
Let’s try to browse the KUDU. But before we try, let’s get the credentials to log in to KUDU. Go back to the Azure portal and browse to your web app. In the Overview blade, click on Get publishing profile. This will download a settings file which you will open with Notepad or Notepad++
Use these to identify your username and password for KUDU.
For me it is $just-app for username and dLNiTdx8yumKzCA3h0FnwB1Zth539iaBsQr34LjjKqeaGL2v5f3fgjfCfzXv for password.
Let’s give it a try
Give it some time after you have created the binding. The KUDU website might still offer you the generic ASE certificate if you try right away.
It will ask you for the Kudu credentials in the old-fashioned Basic Authentication prompt window. Use the credentials from the file.
Did it work?
Note that because the ILB ase is only accessible from the VNET in which the ASE is deployed, the KUDU is also only accessible that way. This means that you won’t be able to browse KUDU from the portal as well. (You might be able to launch KUDU from the portal only from a browser on a machine inside that VNET)
Now that you have successfully deployed an App inside that ILB and understood how it works, I can suggest you deploying few more apps testing different scenarios. For example, a WordPress would be an interesting idea where the database will sit outside of the ASE.
Let’s do that.
Go to your resource group and click this link to create a Web app + MySQL (Azure DB)
Look at the below example and do yours the same. Make the MySQL Location in West Europe for low latency
Click Create when ready
Go back to the DNS-01 VM and download and install FileZilla from this link.
When the App is deployed browse to the Overview tab and look for your FTP hostname
Paste it into the FileZilla connection window. For username and password – get this app’s Publishing profile and get your credentials to log in to the app
$WordPress for me with the long password
From the VM’s browser, go and download the latest WordPress - https://WordPress.org/download/
Unzip it into a folder somewhere on the VM. Browse to that folder from FileZilla on the left pane which represents your local machine. On the right pane browse to the wwwroot of your web app. Delete the existing hostingstart.html file.
On your left pane select all files with ctrl + a and right-click. Click Upload.
Wait for the upload to finish. Ignore the certificate warnings.
Once the upload is finished, browse to your web app. In my case - https://wordpress.djo-ase.tk (again browsing from the VM)
This will launch the WordPress installation wizard. First step is to establish connection to the database. Use the parameters you’ve set for the database server when you created the app and the database server few steps ago. It should look like this:
If all good – it will say Run the Installation
Finish the details around the WordPress site title and username/password. I’ve named my WordPresss – ILB ASE WordPress 😊
We now have a WordPress site in an ILB ASE with a connection to Azure DB!
Congratulations. You are now properly running an ILB ASE. Here is what we’ve done so far:
Click to enlarge
Now, let’s say we want to expose our WordPress site from outside of the VNET to the internet. We will be using Application Gateway in a WAF tier to accomplish this. One magical property of the Application Gateway that makes it suitable/possible is that we deploy it in a VNET of our choosing. This means that we will deploy it into the ILB ASE VNET and the Gateway will be using our own VNET custom DNS and will be able to resolve the ASE domain (djo-ase.tk) web apps internally.
We will be using this guide to accomplish our goal - https://docs.microsoft.com/en-us/azure/app-service/environment/integrate-with-application-gateway
Before we deploy the Application Gateway, we need to create a subnet dedicated for it inside the ILB-ASE-VNET because of this requirement
- Browse to your ILB-ASE-VNET -> Subnets
- Name your subnet Gateway-Subnet
- Leave the suggested address range
For me it is:
Let’s start creating the Application Gateway - https://ms.portal.azure.com/#create/Microsoft.ApplicationGateway-ARM
- West Europe
- WAF tier
- 1 Instance
- Medium SKU
- Firewall status: Enabled
- Firewall mode: Detection
- Virtual Network: ILB-ASE-VNET
- Subnet: Gateway-Subnet
Click Next: Frontends>
- Add new Public IP address of your gateway - AppGw-IP for example. Leave it Public only
Click Next: Backends>
- Add a backend pool
- Name it something like ASE-backend-pool
- Leave the target type fqdn and for target put the ILB IP Address – 192.168.20.11
- Click Add
Click Next: Configuration>
- Rule Name: Rule1 or whatever you like it to be called
- Listener name: HTTP-Listener
- Frontend IP: Public
- Protocol: HTTP
- Port: 80
- Listener type: Basic
Switch to Backend targets
- Backend target: ASE-backend-pool
- HTTP setting: Add New -> call it HTTP and save
Click Add in the end
Click Next: Tags>
Skip adding tags
Click Next: Review + Create
Wait for the gateway to deploy
Once the gateway is ready browse to it
- Make sure that the backend pool still points to the ILB private IP
- Go to Health Probes and +Add (we are following the guide on integrating waf with ase, this is step 6)
- Name: WordPress-probe
- Protocol: HTTP
- Host: your WordPress site hostname. Mine is WordPress.djo-ase.tk
- Path: /
- Click OK to create the probe
- Wait for the probe to be created. It might take some time.
- Go to HTTP Settings
- Check “Use custom probe”
- Select the newly created probe from the drop-down
- Click Save
- Wait for the settings to be saved. It might take some time again.
- Go to Backend Health after waiting for some time and check if the health is good
- We will now be pointing the wordpress.djo-ase-tk in the public domain we purchased from freenom to the Application Gateway
- Go to Overview blade of the gateway and take the Public IP
- Log back in to the Freenom client area - https://my.freenom.com/clientarea.php?action=domains
- Click on Manage Domain
- Click on Manage Freenom DNS
- Create an A record
- Name: wordpress
- Type: A
- TTL: 3600
- Target: The public IP of the Gateway
- OR you can configure CNAME to do the job (although I prefer A records)
- Name: wordpress
- Type: CNAME
- TTL: 3600
- Target: The public DNS name of the Gateway (next to the IP address in Overview blade of the AppGW)
Give it a couple of minutes and try browsing your website url from outside of the VNET. Use http:// to browse your WordPress. Does it work?
Now, if we want to make sure that https traffic also is passed through the application gateway, we have some more work to do.
We will need to create another Listener on the Application Gateway that will be responsible for HTTPS (443)
- Go to your Application Gateway and browse to Listeners
- Add a new Basic Listener
- Name: HTTPS-Listener
- New frontend Port
- Name: SSL-Port
- Port: 443
- Protocol: HTTPS
- Upload PFX: Upload the same PFX as the one we used for the ILB Certificate
- Name: ASE-SSL
- Password: your pfx password
- Click OK to add the listener and wait for its completion
- Go to Health Probes
- Create a new Probe
- Name: WordPress-probe-https
- Protocol: HTTPS
- Host: wordpress.djo-ase.tk
- Path: /
- OK to save the probe
- Go to HTTP Settings
- Create a new HTTP Setting
- Name: HTTPS
- Protocol: HTTPS
- You will need our common certificate but this time in .cer format. From Let’s Encrypt we already have it under .crt format. To convert .crt to .cer is very easy
- Open the .crt certificate in your zip-extracted folder from Let’s encrypt
- Go to Details
- Click Copy to File
- Click Next
- Choose Base-64 encoded X.509 (.CER) option and click Next
- Choose to save the new .cer file in the same directory as the others. You can name it
- Finish the wizard. The output is a .cer file
- Use the .cer file for the HTTP setting
- Port: 443
- Use custom probe: WordPress-probe-https (the newly created one)
- Save the HTTP Setting
- Go to Rules blade
- Add a new rule. Name it Rule2 and associate the new HTTPS listener with it. Backend pool remains the same and HTTP setting - HTTPS
- Click OK to save the rule
Try browsing the website from outside of the VNET with https://. Does it work?
If yes, Congrats. If no, give it some time or start troubleshooting, it will be fun.
You now should be having a WordPress site, hosted in an ILB ASE which is accessible from anywhere!
This completes our whole lab build.
I hope it was fun. Feel free to let me know if there is any step you are struggling with or any mistake in any of the steps I have provided.