Deploy an Azure Application Gateway with an IPv6 frontend - ARM template

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.

If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to Azure button. The template opens in the Azure portal.

Button to deploy the Resource Manager template to Azure.

Important

Application Gateway IPv6 frontend is now generally available.

Prerequisites

Review the template

This template creates a simple setup with a dual-stack 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's dual-stack frontend supports 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",
    "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"
            }
        },
        "utcTime": {
            "defaultValue": "[utcNow('MMddHHmmss')]",
            "type": "String"
        },
        "location": {
            "defaultValue": "[resourceGroup().location]",
            "type": "String",
            "metadata": {
                "description": "Location for all resources."
            }
        },
        "vmSize": {
            "defaultValue": "Standard_DS1_v2",
            "type": "String",
            "metadata": {
                "description": "Size of the virtual machine."
            }
        },
        "publicIPAddresses_appgwipv4_name": {
            "defaultValue": "[format('{0}{1}', 'dualipv4', parameters('utcTime'))]",
            "type": "String"
        },
        "publicIPAddresses_appgwipv6_name": {
            "defaultValue": "[format('{0}{1}', 'dualipv6', parameters('utcTime'))]",
            "type": "String"
        }
    },
    "variables": {
        "virtualMachineName": "myVM",
        "virtualNetworkName": "[format('{0}{1}', 'myVNet', parameters('utcTime'))]",
        "networkInterfaceName": "net-int",
        "ipconfigName": "ipconfig",
        "ipconfigNameV6": "ipconfigV6",
        "publicIPAddressName": "[format('{0}{1}', 'public_ip', parameters('utcTime'))]",
        "publicIPAddressNamev6": "[format('{0}{1}', 'public_ipv6', parameters('utcTime'))]",
        "nsgName": "vm-nsg",
        "applicationGateWayName": "[format('{0}{1}', 'myAppGatewayipv6', parameters('utcTime'))]",
        "virtualNetworkPrefix": [
            "10.0.0.0/16",
            "ace:cab:deca::/48"
        ],
        "subnetPrefix": [
            "10.0.0.0/24",
            "ace:cab:deca::/64"
        ],
        "backendSubnetPrefix": [
            "10.0.1.0/24",
            "ace:cab:deca:10::/64"
        ]
    },
    "resources": [
        {
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2022-07-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": "nsg",
                "count": "[length(range(0, 2))]"
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2022-07-01",
            "name": "[format('{0}{1}', variables('publicIPAddressName'), range(0, 3)[copyIndex()])]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Standard"
            },
            "properties": {
                "publicIPAddressVersion": "IPv4",
                "publicIPAllocationMethod": "Static",
                "idleTimeoutInMinutes": 4,
                "dnsSettings": {
                    "domainNameLabel": "[format('{0}{1}', parameters('publicIPAddresses_appgwipv4_name'), range(0, 3)[copyIndex()])]",
                    "fqdn": "[concat(format('{0}{1}', parameters('publicIPAddresses_appgwipv4_name'), range(0, 3)[copyIndex()]), '.centraluseuap.cloudapp.azure.com')]"
                }
            },
            "copy": {
                "name": "publicIPAddress",
                "count": "[length(range(0, 3))]"
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2022-07-01",
            "name": "[format('{0}{1}', variables('publicIPAddressNamev6'), range(0, 3)[copyIndex()])]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Standard"
            },
            "properties": {
                "publicIPAddressVersion": "IPv6",
                "publicIPAllocationMethod": "Static",
                "idleTimeoutInMinutes": 4,
                "dnsSettings": {
                    "domainNameLabel": "[format('{0}{1}', parameters('publicIPAddresses_appgwipv6_name'), range(0, 3)[copyIndex()])]",
                    "fqdn": "[concat(format('{0}{1}', parameters('publicIPAddresses_appgwipv6_name'), range(0, 3)[copyIndex()]), '.centraluseuap.cloudapp.azure.com')]"
                }
            },
            "copy": {
                "name": "publicIPAddress",
                "count": "[length(range(0, 3))]"
            }
        },
        {
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2022-07-01",
            "name": "[variables('virtualNetworkName')]",
            "location": "[parameters('location')]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": "[variables('virtualNetworkPrefix')]"
                },
                "subnets": [
                    {
                        "name": "myAGSubnet",
                        "properties": {
                            "addressPrefixes": "[variables('subnetPrefix')]",
                            "privateEndpointNetworkPolicies": "Enabled",
                            "privateLinkServiceNetworkPolicies": "Enabled"
                        }
                    },
                    {
                        "name": "myBackendSubnet",
                        "properties": {
                            "addressPrefixes": "[variables('backendSubnetPrefix')]",
                            "privateEndpointNetworkPolicies": "Enabled",
                            "privateLinkServiceNetworkPolicies": "Enabled"
                        }
                    }
                ],
                "enableDdosProtection": false,
                "enableVmProtection": false
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2022-11-01",
            "name": "[format('{0}{1}', variables('virtualMachineName'), add(range(0, 2)[copyIndex()], 1))]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "networkInterface"
            ],
            "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)))]"
                        }
                    ]
                }
            },
            "copy": {
                "name": "virtualMachine",
                "count": "[length(range(0, 2))]"
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines/extensions",
            "apiVersion": "2022-11-01",
            "name": "[format('{0}{1}/IIS', variables('virtualMachineName'), add(range(0, 2)[copyIndex()], 1))]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "virtualMachine"
            ],
            "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)"
                }
            },
            "copy": {
                "name": "virtualMachine_IIS",
                "count": "[length(range(0, 2))]"
            }
        },
        {
            "type": "Microsoft.Network/applicationGateways",
            "apiVersion": "2022-07-01",
            "name": "[variables('applicationGateWayName')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddressName'), range(0, 3)[0]))]",
                "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddressNamev6'), range(0, 3)[0]))]",
                "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
            ],
            "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')))]"
                            }
                        }
                    },
                    {
                        "name": "appGwIPv6PublicFrontendIp",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIPAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}0', variables('publicIPAddressNamev6')))]"
                            }
                        }
                    }
                ],
                "frontendPorts": [
                    {
                        "name": "port_80",
                        "properties": {
                            "port": 80
                        }
                    },
                    {
                        "name": "port_81",
                        "properties": {
                            "port": 81
                        }
                    }
                ],
                "backendAddressPools": [
                    {
                        "name": "myBackendPool1",
                        "properties": {}
                    },
                    {
                        "name": "myBackendPool2",
                        "properties": {}
                    }
                ],
                "backendHttpSettingsCollection": [
                    {
                        "name": "myHTTPSetting1",
                        "properties": {
                            "port": 80,
                            "protocol": "Http",
                            "cookieBasedAffinity": "Disabled",
                            "pickHostNameFromBackendAddress": false,
                            "requestTimeout": 20
                        }
                    },
                    {
                        "name": "myHTTPSetting2",
                        "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
                        }
                    },
                    {
                        "name": "myListenerIpv6",
                        "properties": {
                            "frontendIPConfiguration": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('applicationGateWayName'), 'appGwIPv6PublicFrontendIp')]"
                            },
                            "frontendPort": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('applicationGateWayName'), 'port_80')]"
                            },
                            "protocol": "Http",
                            "requireServerNameIndication": false
                        }
                    }
                ],
                "requestRoutingRules": [
                    {
                        "name": "myRoutingRule1",
                        "properties": {
                            "ruleType": "Basic",
                            "httpListener": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGateWayName'), 'myListener')]"
                            },
                            "priority": 10,
                            "backendAddressPool": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateWayName'), 'myBackendPool1')]"
                            },
                            "backendHttpSettings": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGateWayName'), 'myHTTPSetting1')]"
                            }
                        }
                    },
                    {
                        "name": "myRoutingRule2",
                        "properties": {
                            "ruleType": "Basic",
                            "httpListener": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGateWayName'), 'myListenerIpv6')]"
                            },
                            "priority": 20,
                            "backendAddressPool": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateWayName'), 'myBackendPool2')]"
                            },
                            "backendHttpSettings": {
                                "id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGateWayName'), 'myHTTPSetting2')]"
                            }
                        }
                    }
                ],
                "enableHttp2": false,
                "autoscaleConfiguration": {
                    "minCapacity": 0,
                    "maxCapacity": 10
                }
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2022-07-01",
            "name": "[format('{0}{1}', variables('networkInterfaceName'), add(range(0, 2)[copyIndex()], 1))]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/applicationGateways', variables('applicationGateWayName'))]",
                "nsg",
                "publicIPAddress"
            ],
            "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'), 'myBackendPool1')]"
                                },
                                {
                                    "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateWayName'), 'myBackendPool2')]"
                                }
                            ]
                        }
                    },
                    {
                        "name": "[format('{0}{1}', variables('ipconfigNameV6'), add(range(0, 2)[copyIndex()], 1))]",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIPAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddressNamev6'), add(range(0, 2)[copyIndex()], 1)))]"
                            },
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'myBackendSubnet')]"
                            },
                            "privateIPAddressVersion": "IPv6"
                        }
                    }
                ],
                "enableAcceleratedNetworking": false,
                "enableIPForwarding": false,
                "networkSecurityGroup": {
                    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}{1}', variables('nsgName'), add(range(0, 2)[copyIndex()], 1)))]"
                }
            },
            "copy": {
                "name": "networkInterface",
                "count": "[length(range(0, 2))]"
            }
        }
    ]
}

Multiple Azure resources are defined in the template:

Deploy the template

Deploy the ARM template to Azure:

  1. 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.

    Button to deploy the Resource Manager template to Azure.

  2. Select or create your resource group, type the virtual machine Admin Username and Admin Password.

    A screenshot of create new application gateway: Basics.

    Note

    Select a region that is the same as your resource group. If the region doesn't support the Standard DS1 v2 virtual machine SKU, this SKU is not displayed and you must choose a different size.

  3. 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 can be used to verify that Azure successfully created the application gateway.

To use IIS to test the application gateway:

  1. Find the public IP address and DNS name for the application gateway on its Overview page. In the following example, the DNS name is dualipv611061903310.eastus.cloudapp.azure.com.

    A screenshot showing the application gateway's public IP address and DNS name.

  2. Copy the public IP address or DNS name, and then paste it into the address bar of your browser to browse that IP address.

  3. Check the response. A valid response verifies that the application gateway was successfully created and can successfully connect with the backend.

    A screenshot showing a successful test of application gateway.

    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 process 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>

Next steps