Step 5: Add health checks and Always On
This is step 5 of the enterprise web app learning path.
So far Zava Widgets is configured, data-driven, and keyless - but the platform
has no way to know whether a running instance is actually healthy, and on a lower
tier the app can go cold between requests. This step fixes both. You point App
Service health check at the app's /health endpoint so the platform can detect
and replace unhealthy instances, and you turn on Always On so the app stays
loaded and responsive.
The app already exposes a health probe. GET /health returns HTTP 200 with a small
JSON body that also reports the current data source, so it doubles as a quick status
check.
In this step you will:
- Configure App Service health check to poll
/health. - Turn on Always On so the app is not unloaded when idle.
- Confirm both settings and see the probe respond.
Estimated time: 15 to 20 minutes.
Objectives
By the end of this step you will be able to:
- Configure an App Service health check path.
- Explain how health check and multiple instances work together to remove unhealthy nodes.
- Turn on Always On and describe when you need it.
Before you start
You need the resource group and web app from the earlier steps:
RESOURCE_GROUP="rg-zava-widgets"
APP_NAME="<your-app-name>"
If you deployed with azd, read the names from your environment:
cd app-service-labs/samples/zava-widgets
RESOURCE_GROUP=$(azd env get-values | grep RESOURCE_GROUP_NAME | cut -d'"' -f2)
APP_NAME=$(azd env get-values | grep WEB_APP_NAME | cut -d'"' -f2)
How health check and Always On help
App Service health check pings a path you choose on every instance. When an instance keeps failing and you are running two or more instances, the platform stops routing traffic to the bad one and replaces it - so a single wedged instance does not serve errors. Always On keeps the app loaded instead of unloading it after a period of inactivity, which avoids a slow first request (a cold start) and is required for continuous background work.
Health check does the most for you when the app runs on more than one instance - which is exactly what you add in the next step, autoscale. Setting it now means the platform is ready to act the moment you scale out.
Turn on health check and Always On
- Azure CLI (az)
- Azure portal
Set the health check path and turn on Always On:
az webapp config set \
--name "$APP_NAME" --resource-group "$RESOURCE_GROUP" \
--always-on true \
--generic-configurations '{"healthCheckPath": "/health"}'
- In the Azure portal, go to your web app.
- Select Monitoring > Health check. Set it to Enable, enter the path
/health, and select Save. - Select Settings > Configuration (or Settings > General settings), set Always On to On, and select Save.
Verify
Confirm both settings are in place:
az webapp config show \
--name "$APP_NAME" --resource-group "$RESOURCE_GROUP" \
--query "{healthCheckPath: healthCheckPath, alwaysOn: alwaysOn}"
You should see /health and true:
{"alwaysOn": true, "healthCheckPath": "/health"}
Now call the probe directly:
APP_URL="https://$(az webapp show --name "$APP_NAME" --resource-group "$RESOURCE_GROUP" --query defaultHostName -o tsv)"
curl -s "$APP_URL/health"
It returns HTTP 200 with the app's status and current data source:
{"status":"healthy","dataSource":"azure-sql"}
With a single instance, health check can detect a problem but has no healthy
instance to fail over to. Its value shows up once you run two or more instances,
which is the next step. Keep the path lightweight - /health should check that the
app is up without doing heavy work on every ping.
Troubleshooting
healthCheckPathis empty after saving. Confirm you passed the path exactly as{"healthCheckPath": "/health"}and that/healthreturns 200. Re-run theaz webapp config showquery to confirm.- Always On is greyed out in the portal. Always On requires a Basic tier or higher. It is not available on Free or Shared plans. This path runs on B1, which supports it.
- The probe returns a non-200 status. Open
$APP_URL/healthin a browser. If it errors, the app is not healthy for another reason - check the earlier steps and the app logs before relying on the probe.
Summary
App Service now watches Zava Widgets: it polls /health, is ready to pull a bad
instance out of rotation, and keeps the app warm with Always On. That is the
groundwork for running more than one instance. Next you add autoscale, so the app
grows and shrinks its instance count with load - and health check finally has
somewhere to route around failures.