Summary
In this article, I would share problems I faced when deploying and configuring Azure Application Gateway and App Service. At this point, I have not solved problems of App Service redirection for HTTP protocol, but I was able to successfully build it for HTTPS. The sample code is here network-sample-app.
TOC
HTTP
Context
I was trying to build a sample template with Web App and Application Gateway using azure-quickstart-templates web-app-with-app-gateway-v2.
- Public IP DNS:
kawatawebapp-evrlkrxuhtnti.japaneast.cloudapp.azure.com
- App Service endpoint:
kawatawebapp-evrlkrxuhtnti.azurewebsites.net
- Frontend protocol: HTTP
- Backend protocol: HTTP
- Backend inbound is through Service Endpoint from Virtual Network subnet to App Service
Problem
At first, it looks working well. I can see the default App Service view through a browser.
However, whe I deployed a sample .NET Web API with a GET request route api/travelplan
, it does not work. The browser redirects the response and showed 403 Forbidden status code.
Request to .japaneast.cloudapp.azure.com/api/travelplan
Response from .azurewebsites.net/api/travelplan
Cause
The domain name of original request is .cloudapp.azure.com
but a redirection of App Service sets .azurewebsites.net
in the location header. This is what a Microsoft official documentation Troubleshoot App Service issues in Application Gateway explains.
Workaround failed
In the official documentation, I found two workarounds.
- Rewrite the location header
- Use a custom domain name
I do not have my own domain name, and I tried the first one that rewrites the location header. Application Gateway Rewrite configuration is added like below.
ARM template
"rewriteRuleSets": [
{
"name": "rewriteLocationHeader",
"properties": {
"rewriteRules": [
{
"ruleSequence": 100,
"conditions": [
{
"variable": "http_resp_Location",
"pattern": "(https?):\\/\\/.*azurewebsites\\.net(.*)$",
"ignoreCase": true
}
],
"name": "NewRewrite",
"actionSet": {
"responseHeaderConfigurations": [
{
"headerName": "Location",
"headerValue": "{http_resp_Location_1}://kawatawebapp-evrlkrxuhtnti.japaneast.cloudapp.azure.com{http_resp_Location_2}"
}
]
}
}
]
}
}
]
It keeps the original domain name .cloudapp.azure.com
in the response header, but it does not respond and got request timeout.
HTTPS
Acutally, I have not found a solution for the issue above yet, but I tried SSL with Key Vault to see if it works. A self-signed certificate is stored in the Key Vault and Application Gateway retrieves it for SSL communication. The code is in thie respository network-sample-app.
Probe problem
This SSL configuration works, but sometimes I faced errors of 502 Bad Gateway or 404 Not Found. I looked through the problem and found this happens because of Application Gateway Probe configuration, probe path "/"
. In the beginning, I set up the configuration below.
ARM template
"probes": [
{
"Name": "BackendProbe",
"properties": {
"Protocol": "Https",
"Path": "/",
"Interval": 30,
"Timeout": 10,
"UnhealthyThreshold": 3,
"MinServers": 0,
"PickHostNameFromBackendHttpSettings": true
}
}
]
- Before code deploy
- After code deploy
Probe cause
According to the Microsoft documentation Application Gateway health monitoring overview, Azure Application Gateway automatically removes any resource considered unhealthy from the pool. This sample API does not have the root path and showed errors.
Probe solution
So I put the code below so the custom probe works correctly with the path /api/travelplan
after the code deployment.
"probes": [
{
"Name": "BackendProbe",
"properties": {
"Protocol": "Https",
"Path": "/api/travelplan",
"Interval": 30,
"Timeout": 10,
"UnhealthyThreshold": 3,
"MinServers": 0,
"PickHostNameFromBackendHttpSettings": true
}
}
]
Finally, it works.
Below is the pattern table what response you receive depending on probe path, code deployment, request route.
Code | Not deployed | Deployed | Deployed |
---|---|---|---|
Request route | / | / | /api/travelplan |
Probe path "/" | 200 | 502 | 502 |
Probe path "/api/travelplan" | 502 | 404 | 200 |
In the code sample, I use "/health"
route path for the custom probe. You need to change the code something like below.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/health");
});
}
ARM template
{
"type": "Microsoft.Web/sites",
...
"properties": {
"siteConfig": {
"healthCheckPath": "/health"
}
}
}
"probes": [
{
"Name": "BackendProbe",
"properties": {
"Protocol": "Https",
"Path": "/health",
"Interval": 30,
"Timeout": 10,
"UnhealthyThreshold": 3,
"MinServers": 0,
"PickHostNameFromBackendHttpSettings": true
}
}
]
Top comments (0)