-
Notifications
You must be signed in to change notification settings - Fork 267
Open
Description
Summary
Add support for deploying to Azure App Service deployment slots to enable zero-downtime deployments with staging validation before production promotion.
Problem
Currently, azd deploy deploys directly to the production App Service. Teams need to:
- Deploy to a staging slot for validation
- Promote staging to production with zero downtime
- Rollback quickly if issues are detected
This workflow is a standard best practice for production deployments but requires manual intervention outside of azd.
Proposed Solution
New CLI Commands
Deploy to Slot
azd deploy <service> --to <slot-name>
azd deploy <service> --from-package <package-path> --to <slot-name>Examples:
azd deploy web --to staging # deploy to staging slot
azd deploy web --from-package ./dist/web.zip --to staging # deploy package to stagingPromote to Production (Traffic Shift)
azd deploy <service> --traffic <slot-name>:100Examples:
azd deploy web --traffic staging:100 # promote staging to production (triggers swap)
azd deploy web --traffic production:100 # rollback (swap back)Interactive confirmation before swap:
Ready to shift 100% traffic to staging (this will swap slots):
Current production:
Version: azd-deploy-20260107-1015
Staging (will become production):
Version: azd-deploy-20260107-1210
Proceed with traffic shift? (Y/n)
Check Deployment Status
azd deploy <service> --statusShows current version/URL for each slot (production, staging, etc.).
User Workflow
# 1. Deploy to staging
azd deploy web --to staging
# 2. Test staging
# ... run tests against staging URL ...
# 3. Promote to production
azd deploy web --traffic staging:100
# 4. Rollback if needed
azd deploy web --traffic production:100Prerequisites (User Setup)
Users must manually add slot infrastructure:
Bicep with AVM module:
module stagingSlot 'br/public:avm/res/web/site/slot:0.2.0' = { ... }
output SERVICE_WEB_STAGING_URI string = 'https://${stagingSlot.outputs.name}.azurewebsites.net'
output SERVICE_WEB_STAGING_NAME string = stagingSlot.outputs.nameRequirements:
- App Service Plan must be Standard S1+ or Premium tier (Basic/Free don't support slots)
- Slot infrastructure outputs must follow naming convention:
SERVICE_{SERVICENAME}_{SLOTNAME}_URI
Optional azure.yaml default:
services:
web:
project: .
language: py
host: appservice
deployment:
slot: staging # default slot when using --to without argumentImplementation Considerations
1. Infrastructure Detection
- Read
azure.yamlto identify services and optional default slot (deployment.slot) - Read
azd provisionoutputs to detect which slots exist in infrastructure (don't parse IaC files) - Required outputs:
SERVICE_{SERVICENAME}_{SLOTNAME}_URI,SERVICE_{SERVICENAME}_{SLOTNAME}_NAME - Works with any IaC tool (Bicep, Terraform)
- Clear error if outputs missing with guidance on adding slot infrastructure
2. Deployment Type Detection
- Only support code-based App Service deployments (zip deploy, run from package)
- Error if user attempts slot operations on Web App for Containers: "Deployment slots for containerized App Services are not yet supported. Use Azure Container Apps for container-based blue/green deployments."
3. Traffic Management (Swap)
- For App Service:
--traffic <slot>:100triggers atomic slot swap - Only 0% or 100% supported (binary traffic model)
- Interactive confirmation before swap with version info
- Track deployment version in app settings (
AZD_DEPLOYMENT_VERSION) for visibility
4. Version Tracking
Store deployment metadata in slot app settings for auditing:
- CI/CD: Extract from environment variables (commit hash, branch, build number)
- Local dev: Generate identifier
azd-deploy-YYYYMMDD-HHMM - Mark as slot-specific (sticky) so version stays with slot during swap
5. Configuration Management
- Phase 1: All slots share same configuration from azd environment (
.azure/<env-name>/.env) - For slot-specific config needs: use multiple azd environments (Pattern 2)
- Future (Phase 3): Native slot-specific configuration support
6. Error Handling
- Clear error if slot doesn't exist
- Clear error if App Service Plan SKU doesn't support slots
- Graceful handling if swap fails (Azure API errors)
- Best-effort warning if deployment appears in progress
7. User Experience
- Show clear progress during traffic shift
- Display slot URLs after deployment
- Warnings before destructive operations
- Show version info before/after traffic shifts
- Maintain backward compatibility (no flags = deploy to production)
8. Telemetry (Required)
Track usage metrics to inform Phase 2-4 decisions:
deploy.to- deployment to slotdeploy.traffic- traffic shift operationdeploy.status- status check- Success/failure rates, operation latency, slot names used
9. Known Limitations
- No concurrent operation protection (document to avoid simultaneous operations)
- Shared configuration across slots (until Phase 3)
- Code-based App Service only (no container support)
Design Principles
- Generic interface: Use
--toflag that will extend to Container Apps in Phase 2 - Leverage existing features: Use existing
--from-packagefor artifact promotion - Output-based detection: Read provision outputs, not IaC files
- Backward compatible: No breaking changes; existing behavior unchanged without flags
- Infrastructure-agnostic: Works with Bicep, Terraform, ARM
Success Criteria
- Users can deploy to staging slot with single command
- Traffic shift operation completes in < 10 seconds
- Zero downtime during traffic shift
- Clear error messages guide users to correct configuration
- 90% of users successfully deploy with slots on first attempt
Out of Scope (Future Phases)
- Phase 2: Container Apps revision support with same
--tointerface - Phase 3: Auto-provision slots, slot-specific configuration, concurrency protection
- Phase 4: TBD
References
- Related Issue: #6451
- AVM Bicep Module: avm/res/web/site/slot:0.2.0
- Aspire 13.1 Feature: Azure App Service Deployment Slots
Metadata
Metadata
Assignees
Labels
No labels