DEV Community

iapilgrim
iapilgrim

Posted on

Scalable Enterprise Web Routing: Azure App Gateway + VMSS with Azure CLI

Building a resilient web architecture requires more than just a single server. In this tutorial, we transition from simple load balancing to Layer 7 Application Routing. We will deploy a Virtual Machine Scale Set (VMSS) and front it with an Azure Application Gateway, all using the Azure CLI.

🏗️ The Architecture

Unlike a standard Load Balancer (Layer 4), an Application Gateway (Layer 7) can make routing decisions based on HTTP headers and URL paths. We combine this with a VMSS to ensure our backend automatically scales based on demand.


🛠️ Objectives

  1. Deploy an Application Gateway for advanced web traffic management.
  2. Master Azure CLI for infrastructure automation.
  3. Utilize VMSS Extensions to "bootstrap" applications automatically.
  4. Setup a Mock Service using Python for isolated network testing.

💻 The Full Automation Script

Copy and save this script as deploy_appgw.sh. If you are on Windows, you can run this in WSL or Azure Cloud Shell.

#!/bin/bash

# --- 1. Configuration ---
rg="my-automated-rg3"
location="eastus2"
vnet_name="shared-vnet"
vmss_name="Hub-VMSS"
appgw_name="Hub-AppGateway"

echo "--- Starting Phase 6: Application Gateway & VMSS Deployment ---"

# --- 2. Create the Dedicated App Gateway Subnet ---
# App Gateway v2 requires its own empty subnet (min /24 recommended)
echo "Adding Application Gateway Subnet..."
az network vnet subnet create \
  --resource-group $rg \
  --vnet-name $vnet_name \
  --name appgw-subnet \
  --address-prefixes 10.0.4.0/24

# --- 3. Deploy the Virtual Machine Scale Set (VMSS) ---
echo "Deploying VMSS (The Elastic Backend)..."
az vmss create \
  --resource-group $rg \
  --name $vmss_name \
  --image Canonical:0001-com-ubuntu-server-jammy:22_04-lts:latest \
  --vm-sku Standard_B2ts_v2 \
  --instance-count 2 \
  --vnet-name $vnet_name \
  --subnet workload-subnet \
  --upgrade-policy-mode automatic \
  --admin-username azureuser \
  --generate-ssh-keys

# --- 4. Automate App Deployment with VMSS Extensions ---
# This "bootstraps" a Python mock service on every instance as it scales
echo "Applying Custom Script Extension..."
az vmss extension set \
  --publisher Microsoft.Azure.Extensions \
  --version 2.0 \
  --name CustomScript \
  --resource-group $rg \
  --vmss-name $vmss_name \
  --settings '{"commandToExecute": "mkdir -p /tmp/www && echo \"<h1>Backend Instance: $(hostname)</h1>\" > /tmp/www/index.html && cd /tmp/www && nohup python3 -m http.server 80 &"}'

# --- 5. Deploy the Application Gateway ---
echo "Creating Public IP for Gateway..."
az network public-ip create \
  --resource-group $rg \
  --name appgw-public-ip \
  --allocation-method Static \
  --sku Standard

echo "Deploying Application Gateway (Standard_v2)..."
az network application-gateway create \
  --name $appgw_name \
  --resource-group $rg \
  --location $location \
  --capacity 2 \
  --sku Standard_v2 \
  --public-ip-address appgw-public-ip \
  --vnet-name $vnet_name \
  --subnet appgw-subnet \
  --frontend-port 80 \
  --priority 100 \
  --http-settings-port 80 \
  --http-settings-protocol Http

# --- 6. Connect VMSS to the Gateway Backend Pool ---
echo "Linking VMSS to Application Gateway..."
backend_pool_id=$(az network application-gateway address-pool show \
  --gateway-name $appgw_name \
  --resource-group $rg \
  --name appGatewayBackendPool \
  --query id -o tsv)

az vmss update \
  --resource-group $rg \
  --name $vmss_name \
  --set virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0].ipConfigurations[0].applicationGatewayBackendAddressPools="[{'id': '$backend_pool_id'}]"

# Force update existing instances
az vmss update-instances --instance-ids "*" --name $vmss_name --resource-group $rg

echo "--- DEPLOYMENT COMPLETE ---"

Enter fullscreen mode Exit fullscreen mode

🔍 Post-Deployment Inspection (Azure CLI)

The CLI is the most powerful tool for inspecting live resources. Use these commands to verify your setup:

Check Backend Health

Confirm the Application Gateway can successfully "see" and "probe" the VMSS instances:

az network application-gateway show-backend-health \
  --name Hub-AppGateway \
  --resource-group my-automated-rg3

Enter fullscreen mode Exit fullscreen mode

Scale Up!

Test the elasticity of your design by increasing the instance count:

az vmss scale \
  --resource-group my-automated-rg3 \
  --name Hub-VMSS \
  --new-capacity 4

Enter fullscreen mode Exit fullscreen mode

❓ Troubleshooting Tips

1. Subnet Restrictions

The Application Gateway v2 must be in its own subnet. You cannot place VMs or other resources in appgw-subnet. If your deployment fails with a "Subnet Busy" error, check for existing NICs.

2. Extension Issues

If the web service isn't responding, check the status of the VMSS extension:

az vmss extension show \
  --resource-group my-automated-rg3 \
  --vmss-name Hub-VMSS \
  --name CustomScript

Enter fullscreen mode Exit fullscreen mode

3. App Gateway vs. Load Balancer: Which one?

  • Use Load Balancer (L4) when you need high-performance, low-latency traffic for internal services (e.g., SQL, non-HTTP protocols).
  • Use Application Gateway (L7) when you need SSL Termination, URL-path routing, or Web Application Firewall (WAF) protection.

🏁 Conclusion

By combining Application Gateway with VMSS, we’ve built a production-ready entry point for our Azure network. The use of CLI automation and extensions ensures that our environment is repeatable and easily scalable.

Top comments (0)