Quickstart: Direct web traffic with Azure Application Gateway - ARM template
In this quickstart, you use an Azure Resource Manager template (ARM template) to create an Azure Application Gateway. Then you test the application gateway to make sure it works correctly. The Standard v2 SKU is used in this example.
An Azure Resource Manager template is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for your project. The template uses declarative syntax. You describe your intended deployment without writing the sequence of programming commands to create the deployment.
You can also complete this quickstart using the Azure portal, Azure PowerShell, or Azure CLI.
If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to Azure button. The template will open in the Azure portal.
Note
Application Gateway frontend now supports dual-stack IP addresses (Preview). You can now create up to four frontend IP addresses: Two IPv4 addresses (public and private) and two IPv6 addresses (public and private).
Prerequisites
- An Azure account with an active subscription. Create an account.
Review the template
For the sake of simplicity, this template creates a simple setup with a public frontend IP, a basic listener to host a single site on the application gateway, a basic request routing rule, and two virtual machines in the backend pool.
Note
Application Gateway frontend now supports dual-stack IP addresses (Public Preview). You can now create up to four frontend IP addresses: Two IPv4 addresses (public and private) and two IPv6 addresses (public and private).
The template used in this quickstart is from Azure Quickstart Templates
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.26.54.24096",
"templateHash": "2911869422088455783"
}
},
"parameters": {
"adminUsername": {
"type": "string",
"metadata": {
"description": "Admin username for the backend servers"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Password for the admin account on the backend servers"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_B2ms",
"metadata": {
"description": "Size of the virtual machine."
}
}
},
"variables": {
"virtualMachineName": "myVM",
"virtualNetworkName": "myVNet",
"networkInterfaceName": "net-int",
"ipconfigName": "ipconfig",
"publicIPAddressName": "public_ip",
"nsgName": "vm-nsg",
"applicationGateWayName": "myAppGateway",
"virtualNetworkPrefix": "10.0.0.0/16",
"subnetPrefix": "10.0.0.0/24",
"backendSubnetPrefix": "10.0.1.0/24"
},
"resources": [
{
"copy": {
"name": "nsg",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2023-09-01",
"name": "[format('{0}{1}', variables('nsgName'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "RDP",
"properties": {
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 300,
"direction": "Inbound"
}
}
]
}
},
{
"copy": {
"name": "publicIPAddress",
"count": "[length(range(0, 3))]"
},
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2023-09-01",
"name": "[format('{0}{1}', variables('publicIPAddressName'), range(0, 3)[copyIndex()])]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIPAddressVersion": "IPv4",
"publicIPAllocationMethod": "Static",
"idleTimeoutInMinutes": 4
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2023-09-01",
"name": "[variables('virtualNetworkName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('virtualNetworkPrefix')]"
]
},
"subnets": [
{
"name": "myAGSubnet",
"properties": {
"addressPrefix": "[variables('subnetPrefix')]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"name": "myBackendSubnet",
"properties": {
"addressPrefix": "[variables('backendSubnetPrefix')]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
],
"enableDdosProtection": false,
"enableVmProtection": false
}
},
{
"copy": {
"name": "virtualMachine",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2023-09-01",
"name": "[format('{0}{1}', variables('virtualMachineName'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"version": "latest"
},
"osDisk": {
"osType": "Windows",
"createOption": "FromImage",
"caching": "ReadWrite",
"managedDisk": {
"storageAccountType": "StandardSSD_LRS"
},
"diskSizeGB": 127
}
},
"osProfile": {
"computerName": "[format('{0}{1}', variables('virtualMachineName'), add(range(0, 2)[copyIndex()], 1))]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true
},
"allowExtensionOperations": true
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', variables('networkInterfaceName'), add(range(0, 2)[copyIndex()], 1)))]"
}
]
}
},
"dependsOn": [
"networkInterface"
]
},
{
"copy": {
"name": "virtualMachine_IIS",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2023-09-01",
"name": "[format('{0}{1}/IIS', variables('virtualMachineName'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"autoUpgradeMinorVersion": true,
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.4",
"settings": {
"commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
}
},
"dependsOn": [
"virtualMachine"
]
},
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2023-09-01",
"name": "[variables('applicationGateWayName')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"name": "Standard_v2",
"tier": "Standard_v2"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'myAGSubnet')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}0', variables('publicIPAddressName')))]"
}
}
}
],
"frontendPorts": [
{
"name": "port_80",
"properties": {
"port": 80
}
}
],
"backendAddressPools": [
{
"name": "myBackendPool",
"properties": {}
}
],
"backendHttpSettingsCollection": [
{
"name": "myHTTPSetting",
"properties": {
"port": 80,
"protocol": "Http",
"cookieBasedAffinity": "Disabled",
"pickHostNameFromBackendAddress": false,
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "myListener",
"properties": {
"frontendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('applicationGateWayName'), 'appGwPublicFrontendIp')]"
},
"frontendPort": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('applicationGateWayName'), 'port_80')]"
},
"protocol": "Http",
"requireServerNameIndication": false
}
}
],
"requestRoutingRules": [
{
"name": "myRoutingRule",
"properties": {
"ruleType": "Basic",
"priority": 1,
"httpListener": {
"id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGateWayName'), 'myListener')]"
},
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateWayName'), 'myBackendPool')]"
},
"backendHttpSettings": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGateWayName'), 'myHTTPSetting')]"
}
}
}
],
"enableHttp2": false,
"autoscaleConfiguration": {
"minCapacity": 0,
"maxCapacity": 10
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddressName'), range(0, 3)[0]))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
]
},
{
"copy": {
"name": "networkInterface",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2023-09-01",
"name": "[format('{0}{1}', variables('networkInterfaceName'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"ipConfigurations": [
{
"name": "[format('{0}{1}', variables('ipconfigName'), add(range(0, 2)[copyIndex()], 1))]",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddressName'), add(range(0, 2)[copyIndex()], 1)))]"
},
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'myBackendSubnet')]"
},
"primary": true,
"privateIPAddressVersion": "IPv4",
"applicationGatewayBackendAddressPools": [
{
"id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateWayName'), 'myBackendPool')]"
}
]
}
}
],
"enableAcceleratedNetworking": false,
"enableIPForwarding": false,
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}{1}', variables('nsgName'), add(range(0, 2)[copyIndex()], 1)))]"
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/applicationGateways', variables('applicationGateWayName'))]",
"nsg",
"publicIPAddress"
]
}
],
"outputs": {
"location": {
"type": "string",
"value": "[parameters('location')]"
},
"name": {
"type": "string",
"value": "[variables('applicationGateWayName')]"
},
"resourceGroupName": {
"type": "string",
"value": "[resourceGroup().name]"
},
"resourceId": {
"type": "string",
"value": "[resourceId('Microsoft.Network/applicationGateways', variables('applicationGateWayName'))]"
}
}
}
Tip
You can modify values of the Name
and Tier
parameters under resource\applicationGateWay\properties\sku
to use a different SKU. For example: Basic
. For information about deploying custom templates, see Create and deploy ARM templates.
Multiple Azure resources are defined in the template:
- Microsoft.Network/applicationgateways
- Microsoft.Network/publicIPAddresses : one for the application gateway, and two for the virtual machines.
- Microsoft.Network/networkSecurityGroups
- Microsoft.Network/virtualNetworks
- Microsoft.Compute/virtualMachines : two virtual machines
- Microsoft.Network/networkInterfaces : two for the virtual machines
- Microsoft.Compute/virtualMachine/extensions : to configure IIS and the web pages
Deploy the template
Deploy the ARM template to Azure:
Select Deploy to Azure to sign in to Azure and open the template. The template creates an application gateway, the network infrastructure, and two virtual machines in the backend pool running IIS.
Select or create your resource group, type the virtual machine administrator user name and password.
Select Review + Create and then select Create.
The deployment can take 20 minutes or longer to complete.
Validate the deployment
Although IIS isn't required to create the application gateway, it's installed to verify if Azure successfully created the application gateway. Use IIS to test the application gateway:
Find the public IP address for the application gateway on its Overview page. Or, you can select All resources, enter myAGPublicIPAddress in the search box, and then select it in the search results. Azure displays the public IP address on the Overview page.
Copy the public IP address, and then paste it into the address bar of your browser to browse that IP address.
Check the response. A valid response verifies that the application gateway was successfully created and can successfully connect with the backend.
Refresh the browser multiple times and you should see connections to both myVM1 and myVM2.
Clean up resources
When you no longer need the resources that you created with the application gateway, delete the resource group. This removes the application gateway and all the related resources.
To delete the resource group, call the Remove-AzResourceGroup
cmdlet:
Remove-AzResourceGroup -Name <your resource group name>