Cloud
Azure App Service slots: validate a swap before promoting to production
A production runbook for qualifying an Azure App Service slot swap with configuration drift, warmup, identity, dependencies, logs, validation and rollback before promotion.
An App Service slot swap looks like a clean release mechanism: deploy to staging, warm it up, then exchange traffic with production. In practice, the swap can move the wrong configuration, expose a dependency that was only valid in staging, break managed identity access, reset warm caches or hide an application regression behind a fast rollback.
The use case is a production web app or API hosted on Azure App Service. A new version has been deployed to a staging slot and the team is about to promote it. The runbook goal is to decide whether to swap, hold, fix configuration, or roll back to the current production slot with enough evidence to explain the decision later.
Freeze the release contract
Before touching the swap button, describe what must remain stable. A slot swap changes routing, but the real risk is the contract around settings, identities, dependencies and probes.
Release to qualify
App Service name and resource group
Source slot: staging
Target slot: production
Build or container image version
Deployment pipeline run
Expected public hostname and custom domains
Expected dependencies: database, storage, API, queue, cache
Change window and rollback owner
Controls to prove
Slot settings are correctly marked
Production-only secrets do not move to staging
Staging-only diagnostics do not move to production
Managed identity and RBAC are valid for the target dependencies
Health probes pass from the same ingress path as users
Rollback swap is tested and documented This release contract prevents a common confusion: a green staging URL does not prove that the application will behave correctly after it becomes production.
Compare settings before the swap
Slot settings decide which values stay with the slot and which values move during the swap. A single wrong flag can promote a staging connection string or leave production with a feature flag intended only for validation.
APP_NAME="app-prod"
RESOURCE_GROUP="rg-app-prod"
SOURCE_SLOT="staging"
TARGET_SLOT="production"
az webapp config appsettings list --name "$APP_NAME" --resource-group "$RESOURCE_GROUP" --slot "$SOURCE_SLOT" --output json > appsettings-staging.json
az webapp config appsettings list --name "$APP_NAME" --resource-group "$RESOURCE_GROUP" --output json > appsettings-production.json
jq -r '.[] | [.name, .slotSetting, (.value | tostring | length)] | @tsv' appsettings-staging.json | sort > staging-settings.tsv
jq -r '.[] | [.name, .slotSetting, (.value | tostring | length)] | @tsv' appsettings-production.json | sort > production-settings.tsv
diff -u production-settings.tsv staging-settings.tsv || true The diff should not expose secret values. It should expose names, slot flags and value presence. If DATABASE_URL, KeyVaultName, Feature__WriteMode or APPLICATIONINSIGHTS_CONNECTION_STRING differ, decide whether that difference is expected and whether it should stick to the slot.
Warm the candidate through the real path
A warmup endpoint that only checks process liveness is not enough. The staging slot must prove that it can start, load configuration, reach dependencies and return a useful response through the same gateway, DNS and TLS path used in production.
STAGING_HOST="app-prod-staging.azurewebsites.net"
PROD_HOST="app.example.com"
CORRELATION_ID="swap-$(date +%Y%m%d%H%M%S)"
curl -sS -D staging-headers.txt -H "x-correlation-id: $CORRELATION_ID" "https://$STAGING_HOST/health/ready"
curl -sS -D production-headers.txt -H "x-correlation-id: $CORRELATION_ID-before" "https://$PROD_HOST/health/ready" The probe should be representative but bounded. It can check database read, cache connection, queue metadata, feature flag loading and identity token acquisition. It should not write production data from staging unless the action is explicitly safe.
Validate identity and dependency access
Slot swaps do not magically fix identity. The application may use a system-assigned identity, a user-assigned identity, Key Vault references, Storage, SQL or private APIs. The candidate slot must prove that the runtime identity after promotion will be the intended one.
Check before swap
Managed identity enabled on the production app and expected slot
User-assigned identity client ID is stable
Key Vault references resolve in the source slot
Database or API access tested with the application identity
Private dependencies reached through the expected VNet Integration path
Feature flags do not enable write paths before promotion
Hold the swap when
Staging works only with a broader test identity
Key Vault references show unresolved or stale values
Dependency access succeeds from staging but not from production path
The new version requires a role assignment that is not yet propagated If the candidate needs a new role, qualify that change separately. Do not hide an identity change inside a slot swap.
Read logs as release evidence
The swap decision should use logs before and after promotion. Keep the pipeline run, slot name, build version and correlation IDs together.
let Window = 2h;
let CorrelationPrefix = "swap-";
AppServiceHTTPLogs
| where TimeGenerated > ago(Window)
| where CsUriStem has "/health" or CsUserAgent has "swap-probe"
| project TimeGenerated,
Host = CsHost,
Uri = CsUriStem,
Status = ScStatus,
TimeTaken,
UserAgent = CsUserAgent
| order by TimeGenerated desc If Application Insights is used, correlate requests, dependencies and exceptions with the same release marker. A green HTTP status with failing dependencies is not a green release.
Decide swap, hold or rollback
The decision must be written before the team is under pressure. The matrix below keeps the action narrow.
Swap
Settings diff is reviewed
Slot settings are correct
Warmup passes through the intended path
Identity and dependencies are validated
Logs show no new critical exceptions
Rollback owner and command are ready
Hold
Configuration drift is unexplained
Health check is too shallow
Dependency access uses a test identity
Required RBAC or DNS change is still propagating
Observability cannot prove the candidate behavior
Rollback after swap
Production probes fail after promotion
Error rate or dependency failures rise for the new version
Feature flag creates unexpected writes
Customer path regresses and local fix is riskier than reversal A rollback swap is not a failure of the process. It is the reason the release path exists. What matters is knowing which evidence triggers it.
Execute and validate the swap
Run the swap with an explicit source and target, then replay the same probes immediately. Avoid changing several unrelated controls during the same window.
APP_NAME="app-prod"
RESOURCE_GROUP="rg-app-prod"
SOURCE_SLOT="staging"
TARGET_SLOT="production"
CORRELATION_ID="swap-$(date +%Y%m%d%H%M%S)"
az webapp deployment slot swap --name "$APP_NAME" --resource-group "$RESOURCE_GROUP" --slot "$SOURCE_SLOT" --target-slot "$TARGET_SLOT"
curl -sS -D after-swap-headers.txt -H "x-correlation-id: $CORRELATION_ID-after" "https://app.example.com/health/ready" Keep the before and after probe outputs with the deployment ticket. If rollback is needed, use the same swap command in the opposite direction and rerun the probes.
Conclusion
App Service slots are useful when they are treated as an operational release path, not as a shortcut around production validation. The safe swap decision separates configuration, slot flags, warmup, identity, dependencies, logs and rollback.
The best outcome is not simply that the swap succeeds. It is that the team can explain why it was safe to promote, what was validated after promotion and exactly when rollback would be triggered.