Blue-Green Deployments in Azure
Blue-green deployments eliminate deployment downtime and provide instant rollback capability by maintaining two environments: one running the current production version, one holding the new version. Traffic switches between them at the DNS or load balancer level — a change that takes seconds and can be reversed just as quickly. Azure supports blue-green natively through App Service deployment slots, Container Apps revisions, and AKS Service selector changes.
The blue-green concept
In a blue-green deployment, you maintain two environments:
Blue is the currently live environment serving production traffic. Blue is running the previous stable version.
Green is the standby environment where you deploy and validate the new version. Green receives no production traffic while you are testing it.
When the new version is validated in the green environment, you cut all traffic from blue to green. If the new version has a problem, cut all traffic back from green to blue. Blue is still running the previous version, ready to accept traffic.
The key requirement: both environments must be running and warm. The old environment must stay alive until you are confident in the new version — you cannot shut it down the moment the traffic switches.
Blue-green with App Service deployment slots
App Service’s deployment slot swap is the canonical blue-green mechanism in Azure. The production slot is blue. The staging slot is green. You deploy the new version to staging, validate it, then swap slots. The swap changes which slot the production hostname routes to.
What happens during a slot swap:
1. Azure applies the target slot’s configuration (app settings, connection strings) to the source slot instances so they warm up with production configuration.
2. Azure sends requests to the source slot (staging) and waits for healthy responses, confirming the application has completed startup.
3. Azure atomically switches the internal routing so the production hostname now points to the previously-staging infrastructure.
4. The previously-production infrastructure (now serving no traffic) becomes the staging slot.
# 1. Deploy new version to staging slot
az webapp deployment slot create \
--name app-myapp-prod \
--resource-group rg-prod \
--slot staging \
--configuration-source app-myapp-prod
# 2. Deploy application code to staging slot
az webapp deploy \
--name app-myapp-prod \
--resource-group rg-prod \
--slot staging \
--src-path ./publish/app.zip \
--type zip
# 3. Validate the staging slot manually or run automated smoke tests
# Staging slot URL: https://app-myapp-prod-staging.azurewebsites.net
# 4. Swap: staging slot becomes production, production becomes staging
az webapp deployment slot swap \
--name app-myapp-prod \
--resource-group rg-prod \
--slot staging \
--target-slot production
# 5. Verify the new version is live
az webapp show \
--name app-myapp-prod \
--resource-group rg-prod \
--query "{state:state, url:defaultHostName}"
# 6. If rollback is needed: swap back
az webapp deployment slot swap \
--name app-myapp-prod \
--resource-group rg-prod \
--slot staging \
--target-slot productionConfigure swap-with-preview using az webapp deployment slot swap —action preview to apply the production configuration to the staging slot without completing the swap. This lets you validate the staging slot with production configuration (environment variables, connection strings) before the final swap. Use —action complete to finish the swap, or —action reset to cancel it.
Slot-sticky vs swapped settings
By default, all app settings and connection strings swap with the slots. If your staging slot has a staging database connection string, that connection string moves to production after the swap — which is usually wrong.
Mark settings as “Deployment slot setting” (slot-sticky) to keep them bound to a specific slot. Slot-sticky settings do not swap — they stay with the slot they are configured on, regardless of swap direction.
# Mark a connection string as slot-sticky (stays on this slot, does not swap)
az webapp config connection-string set \
--name app-myapp-prod \
--resource-group rg-prod \
--slot staging \
--settings DefaultConnection="Server=sql-staging.database.windows.net;..." \
--connection-string-type SQLAzure \
--slot-setting trueTypical slot-sticky settings: database connection strings (staging DB vs production DB), logging endpoints (staging Log Analytics vs production), feature flag service endpoints, third-party API keys that are environment-specific.
Blue-green in AKS with Service selector changes
In AKS, blue-green is implemented using two Deployments (blue and green) and a single Service. The Service selects pods via a label. Changing the Service’s selector label from blue to green switches all traffic to the new version:
# production-service.yaml
# The selector determines which pods receive traffic
apiVersion: v1
kind: Service
metadata:
name: myapp-production
namespace: production
spec:
selector:
app: myapp
version: blue # Change this to "green" to switch traffic
ports:
- port: 80
targetPort: 8080# Deploy the green (new) version
kubectl apply -f myapp-green-deployment.yaml -n production
# Validate green pods are healthy
kubectl get pods -l app=myapp,version=green -n production
kubectl logs -l app=myapp,version=green -n production --tail=50
# Switch traffic: update Service selector from blue to green
kubectl patch service myapp-production \
-n production \
--type='json' \
-p='[{"op": "replace", "path": "/spec/selector/version", "value": "green"}]'
# Verify new pods are receiving traffic
kubectl get endpoints myapp-production -n production
# Rollback: switch selector back to blue
kubectl patch service myapp-production \
-n production \
--type='json' \
-p='[{"op": "replace", "path": "/spec/selector/version", "value": "blue"}]'Keep the blue Deployment running until you are fully confident in the green version. Only delete the blue Deployment after a suitable validation period.
Blue-green in Container Apps
Container Apps revisions provide a clean blue-green mechanism. Deploy the new version as a new revision with 0% traffic. Test it directly using the revision-specific URL. When ready, shift 100% of traffic to the new revision in one step:
# Deploy new revision (green) with 0% traffic initially
az containerapp update \
--name myapp \
--resource-group rg-prod \
--image myregistry.azurecr.io/myapp:v2.0 \
--revision-suffix green-v2
# Test the green revision directly via its revision URL
# Format: https://<app-name>--<revision-suffix>.<env-domain>
az containerapp revision show \
--name myapp \
--resource-group rg-prod \
--revision myapp--green-v2 \
--query "properties.fqdn"
# Validate green revision (no production traffic yet)
# Run smoke tests against the revision-specific URL
# Switch: move 100% of traffic to green revision
az containerapp ingress traffic set \
--name myapp \
--resource-group rg-prod \
--revision-weight myapp--green-v2=100
# Rollback: switch back to the previous revision
az containerapp ingress traffic set \
--name myapp \
--resource-group rg-prod \
--revision-weight myapp--blue-v1=100Blue-green vs canary: when to use each
Blue-green is the right choice when:
- The new version has been thoroughly tested in staging and you have high confidence in it.
- The change is large and a mixed-version state (some users on v1, some on v2) would cause problems.
- You need instant, deterministic rollback — a single CLI command or button press.
- The deployment is time-sensitive (a hotfix) and you cannot afford a multi-hour canary process.
Canary is the right choice when:
- The change has uncertain production behaviour and you want to limit the blast radius.
- You want statistical confidence from real traffic before full promotion.
- The application can tolerate mixed versions simultaneously without inconsistency.
Common mistakes
- Deleting the old environment immediately after the swap. The old version is your rollback option. Deleting the blue environment immediately after switching to green means rollback requires redeploying from scratch — a slow, risky operation. Keep the old environment alive for at least 24 hours after the swap. Only decommission it after you are confident the new version is stable.
- Not marking slot-specific settings as slot-sticky in App Service. If you have environment-specific connection strings (staging DB vs production DB) and you forget to mark them as slot-sticky, they will swap with the code. After the swap, your production application is pointing at the staging database. This is a silent data-integrity incident — no crash, just production writes going to the wrong database.
- Running blue-green with backwards-incompatible database schema changes. A blue-green switch moves all traffic at once. If the new version runs a migration that removes a column the old version references, rollback becomes impossible without also rolling back the database migration. Use backwards-compatible schema migrations (additive changes only, deprecation before removal) so that rolling back the application is sufficient for rollback.
Summary
- Blue-green deployments maintain two identical environments (blue = current, green = new) and switch traffic between them at the routing level.
- App Service slot swap warms up the staging slot before switching the production hostname — zero-downtime with automatic health checks.
- Mark environment-specific settings as slot-sticky in App Service so they do not swap with the application code.
- AKS blue-green works by changing a Service’s label selector from the blue Deployment to the green Deployment.
- Keep the old environment alive after the switch — rollback must be a seconds-long operation, not a redeployment.
Frequently asked questions
What is a blue-green deployment?
Blue-green is a deployment strategy where you maintain two identical environments (blue and green). One environment runs the current production version; the other holds the new version. When ready to release, you switch all traffic from the current environment to the new one. If the new version has a problem, you switch traffic back instantly. The old environment stays warm and ready for rollback.
How does App Service slot swap achieve zero downtime?
When you run a slot swap, Azure first warms up the staging slot: it sends health check requests to the staging slot until the application responds successfully. Only after the staging slot is confirmed healthy does Azure switch the DNS-level routing so the production hostname points to the staging slot's infrastructure. The swap takes seconds at the routing level. Users in mid-request finish on the old slot; new requests go to the new version.
What is the difference between blue-green and canary deployments?
Blue-green is a binary switch — you go from 0% to 100% of traffic on the new version in one step. Canary is gradual — you increment from 5% to 10% to 25% to 100% over time, monitoring at each step. Blue-green is faster to execute and simpler to reason about; canary is safer for changes with unknown risk. Use blue-green for well-tested releases with clear rollback criteria; use canary when you need statistical confidence from real traffic before full promotion.