Application gateway allows you to have an App Service app or other multi-tenant service as a backend pool member. In this article, you learn to configure an App Service app with Application Gateway. The configuration for Application Gateway will differ depending on how App Service will be accessed:
The first option makes use of a custom domain on both Application Gateway and the App Service in the backend.
The second option is to have Application Gateway access App Service using its default domain, suffixed as ".azurewebsites.net".
This configuration is recommended for production-grade scenarios and meets the practice of not changing the host name in the request flow. You are required to have a custom domain (and associated certificate) available to avoid having to rely on the default ".azurewebsites" domain.
By associating the same domain name to both Application Gateway and App Service in the backend pool, the request flow doesn't need to override the host name. The backend web application will see the original host as was used by the client.
This configuration is the easiest and doesn't require a custom domain. As such it allows for a quick convenient setup.
Warning
This configuration comes with limitations. We recommend to review the implications of using different host names between the client and Application Gateway and between Application and App Service in the backend. For more information, please review the article in Architecture Center: Preserve the original HTTP host name between a reverse proxy and its backend web application
When App Service doesn't have a custom domain associated with it, the host header on the incoming request on the web application will need to be set to the default domain, suffixed with ".azurewebsites.net" or else the platform won't be able to properly route the request.
The host header in the original request received by the Application Gateway will be different from the host name of the backend App Service.
In this article you'll learn how to:
Configure DNS
Add App Service as backend pool to the Application Gateway
Configure HTTP Settings for the connection to App Service
A custom domain name and associated certificate (signed by a well known authority), stored in Key Vault. For more information on how to store certificates in Key Vault, see Tutorial: Import a certificate in Azure Key Vault
Route the user or client to Application Gateway using the custom domain. Set up DNS using a CNAME alias pointed to the DNS for Application Gateway. The Application Gateway DNS address is shown on the overview page of the associated Public IP address. Alternatively create an A record pointing to the IP address directly. (For Application Gateway V1 the VIP can change if you stop and start the service, which makes this option undesired.)
App Service should be configured so it accepts traffic from Application Gateway using the custom domain name as the incoming host. For more information on how to map a custom domain to the App Service, see Tutorial: Map an existing custom DNS name to Azure App Service To verify the domain, App Service only requires adding a TXT record. No change is required on CNAME or A-records. The DNS configuration for the custom domain will remain directed towards Application Gateway.
When no custom domain is available, the user or client can access Application Gateway using either the IP address of the gateway or its DNS address. The Application Gateway DNS address can be found on the overview page of the associated Public IP address. Not having a custom domain available implies that no publicly signed certificate will be available for TLS on Application Gateway. Clients are restricted to use HTTP or HTTPS with a self-signed certificate, both of which are undesired.
To connect to App Service, Application Gateway uses the default domain as provided by App Service (suffixed "azurewebsites.net").
In the Azure portal, select your Application Gateway.
Under Backend pools, select the backend pool.
Under Target type, select App Services.
Under Target select your App Service.
Note
The dropdown only populates those app services which are in the same subscription as your Application Gateway. If you want to use an app service which is in a different subscription than the one in which the Application Gateway is, then instead of choosing App Services in the Targets dropdown, choose IP address or hostname option and enter the hostname (example.azurewebsites.net) of the app service.
Select Save.
# Fully qualified default domain name of the web app:
$webAppFQDN = "<nameofwebapp>.azurewebsite.net"
# For Application Gateway: both name, resource group and name for the backend pool to create:
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
$appGwBackendPoolNameForAppSvc = "<name for backend pool to be added>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Add a new Backend Pool with App Service in there:
Add-AzApplicationGatewayBackendAddressPool -Name $appGwBackendPoolNameForAppSvc -ApplicationGateway $gw -BackendFqdns $webAppFQDN
# Update Application Gateway with the new added Backend Pool:
Set-AzApplicationGateway -ApplicationGateway $gw
An HTTP Setting is required that instructs Application Gateway to access the App Service backend using the custom domain name. The HTTP Setting will by default use the default health probe. While default health probes will forward requests with the hostname in which traffic is received, the health probes will utilize 127.0.0.1 as the hostname to the Backend Pool since no hostname has explicitly been defined. For this reason, we need to create a custom health probe that is configured with the correct custom domain name as its host name.
We will connect to the backend using HTTPS.
Under HTTP Settings, select an existing HTTP setting or add a new one.
When creating a new HTTP Setting, give it a name
Select HTTPS as the desired backend protocol using port 443
Make sure to set "Override with new host name" to "No"
Select the custom HTTPS health probe in the dropdown for "Custom probe".
An HTTP Setting is required that instructs Application Gateway to access the App Service backend using the default ("azurewebsites.net") domain name. To do so, the HTTP Setting will explicitly override the host name.
Under HTTP Settings, select an existing HTTP setting or add a new one.
When creating a new HTTP Setting, give it a name
Select HTTPS as the desired backend protocol using port 443
Make sure to set "Override with new host name" to "Yes"
Under "Host name override", select "Pick host name from backend target". This setting will cause the request towards App Service to use the "azurewebsites.net" host name, as is configured in the Backend Pool.
# Configure Application Gateway to connect to App Service using the incoming hostname
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
$customProbeName = "<name for custom health probe>"
$customDomainName = "<FQDN for custom domain associated with App Service>"
$httpSettingsName = "<name for http settings to be created>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Add custom health probe using custom domain name:
Add-AzApplicationGatewayProbeConfig -Name $customProbeName -ApplicationGateway $gw -Protocol Https -HostName $customDomainName -Path "/" -Interval 30 -Timeout 120 -UnhealthyThreshold 3
$probe = Get-AzApplicationGatewayProbeConfig -Name $customProbeName -ApplicationGateway $gw
# Add HTTP Settings to use towards App Service:
Add-AzApplicationGatewayBackendHttpSettings -Name $httpSettingsName -ApplicationGateway $gw -Protocol Https -Port 443 -Probe $probe -CookieBasedAffinity Disabled -RequestTimeout 30
# Update Application Gateway with the new added HTTP settings and probe:
Set-AzApplicationGateway -ApplicationGateway $gw
# Configure Application Gateway to connect to backend using default App Service hostname
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
$httpSettingsName = "<name for http settings to be created>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Add HTTP Settings to use towards App Service:
Add-AzApplicationGatewayBackendHttpSettings -Name $httpSettingsName -ApplicationGateway $gw -Protocol Https -Port 443 -PickHostNameFromBackendAddress -CookieBasedAffinity Disabled -RequestTimeout 30
# Update Application Gateway with the new added HTTP settings and probe:
Set-AzApplicationGateway -ApplicationGateway $gw
Open the "Listeners" section and choose "Add listener" or click an existing one to edit
For a new listener: give it a name
Under "Frontend IP", select the IP address to listen on
Under "Port", select 443
Under "Protocol", select "HTTPS"
Under "Choose a certificate", select "Choose a certificate from Key Vault". For more information, see Using Key Vault where you find more information on how to assign a managed identity and provide it with rights to your Key Vault.
Give the certificate a name
Select the Managed Identity
Select the Key Vault from where to get the certificate
Select the certificate
Under "Listener Type", select "Basic"
Click "Add" to add the listener
Assuming there's no custom domain available or associated certificate, we'll configure Application Gateway to listen for HTTP traffic on port 80. Alternatively, see the instructions on how to Create a self-signed certificate
Open the "Listeners" section and choose "Add listener" or click an existing one to edit
For a new listener: give it a name
Under "Frontend IP", select the IP address to listen on
Under "Port", select 80
Under "Protocol", select "HTTP"
# This script assumes that:
# - a certificate was imported in Azure Key Vault already
# - a managed identity was assigned to Application Gateway with access to the certificate
# - there is no HTTP listener defined yet for HTTPS on port 443
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
$appGwSSLCertificateName = "<name for ssl cert to be created within Application Gateway"
$appGwSSLCertificateKeyVaultSecretId = "<key vault secret id for the SSL certificate to use>"
$httpListenerName = "<name for the listener to add>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Create SSL certificate object for Application Gateway:
Add-AzApplicationGatewaySslCertificate -Name $appGwSSLCertificateName -ApplicationGateway $gw -KeyVaultSecretId $appGwSSLCertificateKeyVaultSecretId
$sslCert = Get-AzApplicationGatewaySslCertificate -Name $appGwSSLCertificateName -ApplicationGateway $gw
# Fetch public ip associated with Application Gateway:
$ipAddressResourceId = $gw.FrontendIPConfigurations.PublicIPAddress.Id
$ipAddressResource = Get-AzResource -ResourceId $ipAddressResourceId
$publicIp = Get-AzPublicIpAddress -ResourceGroupName $ipAddressResource.ResourceGroupName -Name $ipAddressResource.Name
$frontendIpConfig = $gw.FrontendIpConfigurations | Where-Object {$_.PublicIpAddress -ne $null}
$port = New-AzApplicationGatewayFrontendPort -Name "port_443" -Port 443
Add-AzApplicationGatewayFrontendPort -Name "port_443" -ApplicationGateway $gw -Port 443
Add-AzApplicationGatewayHttpListener -Name $httpListenerName -ApplicationGateway $gw -Protocol Https -FrontendIPConfiguration $frontendIpConfig -FrontendPort $port -SslCertificate $sslCert
# Update Application Gateway with the new HTTPS listener:
Set-AzApplicationGateway -ApplicationGateway $gw
In many cases a public listener for HTTP on port 80 will already exist. The below script will create one if that is not yet the case.
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
$httpListenerName = "<name for the listener to add if not exists yet>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Check if HTTP listener on port 80 already exists:
$port = $gw.FrontendPorts | Where-Object {$_.Port -eq 80}
$listener = $gw.HttpListeners | Where-Object {$_.Protocol.ToString().ToLower() -eq "http" -and $_.FrontendPort.Id -eq $port.Id}
if ($listener -eq $null){
$frontendIpConfig = $gw.FrontendIpConfigurations | Where-Object {$_.PublicIpAddress -ne $null}
Add-AzApplicationGatewayHttpListener -Name $httpListenerName -ApplicationGateway $gw -Protocol Http -FrontendIPConfiguration $frontendIpConfig -FrontendPort $port
# Update Application Gateway with the new HTTPS listener:
Set-AzApplicationGateway -ApplicationGateway $gw
}
Configure request routing rule
Using the earlier configured Backend Pool and the HTTP Settings, the request routing rule can be set up to take traffic from a listener and route it to the Backend Pool using the HTTP Settings. For this, make sure you have an HTTP or HTTPS listener available that is not already bound to an existing routing rule.
Open the "Backend health" section and ensure the "Status" column indicates the combination for HTTP Setting and Backend Pool shows as "Healthy".
Now browse to the web application using either the Application Gateway IP Address or the associated DNS name for the IP Address. Both can be found on the Application Gateway "Overview" page as a property under "Essentials". Alternatively the Public IP Address resource also shows the IP address and associated DNS name.
Pay attention to the following non-exhaustive list of potential symptoms when testing the application:
redirections pointing to ".azurewebsites.net" directly instead of to Application Gateway
this includes authentication redirects that try access ".azurewebsites.net" directly
domain-bound cookies not being passed on to the backend
The above conditions (explained in more detail in Architecture Center) would indicate that your web application doesn't deal well with rewriting the host name. This is commonly seen. The recommended way to deal with this is to follow the instructions for configuration Application Gateway with App Service using a custom domain. Also see: Troubleshoot App Service issues in Application Gateway.
Open the "Backend health" section and ensure the "Status" column indicates the combination for HTTP Setting and Backend Pool shows as "Healthy".
Now browse to the web application using the custom domain which you associated with both Application Gateway and the App Service in the backend.
Check if the backend health for the backend and HTTP Settings shows as "Healthy":
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Check health:
Get-AzApplicationGatewayBackendHealth -ResourceGroupName $rgName -Name $appGwName
To test the configuration, we'll request content from the App Service through Application Gateway using the custom domain:
$customDomainName = "<FQDN for custom domain pointing to Application Gateway>"
Invoke-WebRequest $customDomainName
Check if the backend health for the backend and HTTP Settings shows as "Healthy":
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Check health:
Get-AzApplicationGatewayBackendHealth -ResourceGroupName $rgName -Name $appGwName
To test the configuration, we'll request content from the App Service through Application Gateway using the IP address:
$rgName = "<name of resource group for App Gateway>"
$appGwName = "<name of the App Gateway>"
# Get existing Application Gateway:
$gw = Get-AzApplicationGateway -Name $appGwName -ResourceGroupName $rgName
# Get ip address:
$ipAddressResourceId = $gw.FrontendIPConfigurations.PublicIPAddress.Id
$ipAddressResource = Get-AzResource -ResourceId $ipAddressResourceId
$publicIp = Get-AzPublicIpAddress -ResourceGroupName $ipAddressResource.ResourceGroupName -Name $ipAddressResource.Name
Write-Host "Public ip address for Application Gateway is $($publicIp.IpAddress)"
Invoke-WebRequest "http://$($publicIp.IpAddress)"
Pay attention to the following non-exhaustive list of potential symptoms when testing the application:
redirections pointing to ".azurewebsites.net" directly instead of to Application Gateway
The above conditions (explained in more detail in Architecture Center) would indicate that your web application doesn't deal well with rewriting the host name. This is commonly seen. The recommended way to deal with this is to follow the instructions for configuration Application Gateway with App Service using a custom domain. Also see: Troubleshoot App Service issues in Application Gateway.
Restrict access
The web apps deployed in these examples use public IP addresses that can be accessed directly from the Internet. This helps with troubleshooting when you're learning about a new feature and trying new things. But if you intend to deploy a feature into production, you'll want to add more restrictions. Consider the following options:
Use Azure App Service static IP restrictions. For example, you can restrict the web app so that it only receives traffic from the application gateway. Use the app service IP restriction feature to list the application gateway VIP as the only address with access.