Multi-Tier App on Azure
Checking access...
Project Overview
In this project you will deploy a three-tier web application on Azure:
- Web tier — Nginx web servers behind a public Load Balancer
- Application tier — Node.js API servers (internal, no public IP)
- Data tier — Azure SQL Database with firewall rules
Architecture
Internet │ ▼Azure Load Balancer (public, Layer 4) │ ├── VM-1 (web-subnet, Nginx) ├── VM-2 (web-subnet, Nginx) │ ▼ (internal)Azure Internal Load Balancer │ ├── VM-3 (app-subnet, Node.js API) ├── VM-4 (app-subnet, Node.js API) │ ▼Azure SQL Database (data-subnet firewall rules)Prerequisites
- An Azure subscription (free trial works)
- Azure CLI installed or Cloud Shell
Step 1: Create the Resource Group and VNet
az group create --name multi-tier-rg --location eastus
az network vnet create \ --resource-group multi-tier-rg \ --name app-vnet \ --address-prefix 10.0.0.0/16 \ --subnet-name web-subnet \ --subnet-prefix 10.0.1.0/24
az network vnet subnet create \ --resource-group multi-tier-rg \ --vnet-name app-vnet \ --name app-subnet \ --address-prefix 10.0.2.0/24
az network vnet subnet create \ --resource-group multi-tier-rg \ --vnet-name app-vnet \ --name data-subnet \ --address-prefix 10.0.3.0/24Step 2: Deploy the Public Load Balancer
az network public-ip create \ --resource-group multi-tier-rg \ --name web-pip
az network lb create \ --resource-group multi-tier-rg \ --name web-lb \ --public-ip-address web-pip \ --frontend-ip-name web-frontend \ --backend-pool-name web-backend
az network lb probe create \ --resource-group multi-tier-rg \ --lb-name web-lb \ --name http-probe \ --protocol tcp \ --port 80
az network lb rule create \ --resource-group multi-tier-rg \ --lb-name web-lb \ --name http-rule \ --protocol tcp \ --frontend-port 80 \ --backend-port 80 \ --frontend-ip-name web-frontend \ --backend-pool-name web-backend \ --probe-name http-probeStep 3: Create Web Tier VMs
# Create NICs with public load balancer associationfor i in 1 2; do az network nic create \ --resource-group multi-tier-rg \ --name web-nic-$i \ --vnet-name app-vnet \ --subnet web-subnet \ --lb-name web-lb \ --lb-address-pools web-backenddone
# Provision VMs with custom data (Nginx install)for i in 1 2; do az vm create \ --resource-group multi-tier-rg \ --name web-vm-$i \ --nics web-nic-$i \ --image Ubuntu2204 \ --size Standard_B1s \ --custom-data cloud-init-web.txtdoneCreate cloud-init-web.txt:
#cloud-configpackage_update: truepackages: - nginxruncmd: - systemctl enable nginx - systemctl start nginxStep 4: Deploy Azure SQL Database
az sql server create \ --resource-group multi-tier-rg \ --name multi-tier-sql \ --admin-user dbadmin \ --admin-password "Str0ngP@ssword!"
az sql db create \ --resource-group multi-tier-rg \ --server multi-tier-sql \ --name appdb \ --service-objective S0
# Allow app subnet to access the databaseaz sql server firewall-rule create \ --resource-group multi-tier-rg \ --server multi-tier-sql \ --name allow-app-subnet \ --start-ip-address 10.0.2.0 \ --end-ip-address 10.0.2.255Caution
In production, use VNet service endpoints or private endpoints (Azure Private Link) instead of firewall IP rules for database access. IP rules are shown here for simplicity.
Step 5: Deploy the Internal Load Balancer and App Tier
az network lb create \ --resource-group multi-tier-rg \ --name app-lb \ --sku Standard \ --frontend-ip-name app-frontend \ --backend-pool-name app-backend \ --vnet-name app-vnet \ --subnet app-subnet
az network lb probe create \ --resource-group multi-tier-rg \ --lb-name app-lb \ --name http-probe \ --protocol tcp \ --port 3000
az network lb rule create \ --resource-group multi-tier-rg \ --lb-name app-lb \ --name api-rule \ --protocol tcp \ --frontend-port 3000 \ --backend-port 3000 \ --frontend-ip-name app-frontend \ --backend-pool-name app-backend \ --probe-name http-probeStep 6: Configure Network Security Groups
az network nsg create --resource-group multi-tier-rg --name web-nsgaz network nsg create --resource-group multi-tier-rg --name app-nsg
# Allow HTTP from internet to web tieraz network nsg rule create \ --resource-group multi-tier-rg \ --nsg-name web-nsg \ --name allow-http \ --protocol tcp \ --destination-port-ranges 80 \ --access allow \ --priority 100
# Allow traffic from web tier to app tieraz network nsg rule create \ --resource-group multi-tier-rg \ --nsg-name app-nsg \ --name allow-web \ --protocol tcp \ --destination-port-ranges 3000 \ --source-address-prefixes 10.0.1.0/24 \ --access allow \ --priority 100Verification
# Get the public IP of the web load balanceraz network public-ip show \ --resource-group multi-tier-rg \ --name web-pip \ --query ipAddress
# Test the applicationcurl http://<web-lb-public-ip>Cleanup
az group delete --name multi-tier-rg --yes --no-waitTip
Use --no-wait to delete resources asynchronously. The command returns immediately and Azure handles the cleanup in the background.
Summary
You have deployed a three-tier application on Azure with VNet isolation, public and internal load balancers, NSG security rules, and Azure SQL Database. This architecture follows Azure best practices and can be extended with Auto Scaling (VMSS), CI/CD (Azure DevOps), and monitoring (Azure Monitor).