- Add separate deployment pipeline (azure-pipelines-deploy.yml) for App Service deployment - Add advanced pipeline with deployment slots (azure-pipelines-slots.yml) - Restore azure-pipelines.yml to build-only (no deployment) - Add comprehensive Azure setup documentation: - AZURE-NEW-SUBSCRIPTION-SETUP.md: Complete step-by-step Azure resource setup - AZURE-RESOURCES-OVERVIEW.md: Quick reference for all Azure resources - AZURE-ACR-SHARED-SETUP.md: Guide for shared Container Registry - AZURE-ACR-NAMING-RECOMMENDATION.md: Naming recommendations for Zuyderland - AZURE-PIPELINE-DEPLOYMENT.md: Automated deployment setup guide - AZURE-PIPELINE-QUICK-REFERENCE.md: Quick reference for pipeline variables - AZURE-PIPELINES-USAGE.md: Guide for using build and deployment pipelines - Add setup script (scripts/setup-azure-resources.sh) for automated resource creation - Support for shared ACR across multiple applications
9.0 KiB
Azure Pipeline Automated Deployment Guide
Complete guide for setting up automated deployment from Azure DevOps Pipeline to Azure App Services.
📋 Overview
The enhanced azure-pipelines.yml now includes:
- ✅ Build Stage: Builds and pushes Docker images to ACR
- ✅ Deploy Stage: Automatically deploys to Azure App Services
- ✅ Verification: Health checks after deployment
🚀 Quick Setup
Step 1: Configure Pipeline Variables
Update the variables in azure-pipelines.yml:
variables:
# Azure Container Registry
acrName: 'zdlas' # Your ACR name
repositoryName: 'cmdb-insight'
dockerRegistryServiceConnection: 'zuyderland-cmdb-acr-connection'
# Azure App Service
resourceGroup: 'rg-cmdb-insight-prod' # Your resource group
backendAppName: 'cmdb-backend-prod' # Your backend app name
frontendAppName: 'cmdb-frontend-prod' # Your frontend app name
azureSubscription: 'zuyderland-cmdb-subscription' # Azure service connection
# Deployment
deployToProduction: true # Set false to skip deployment
useDeploymentSlots: false # Set true for zero-downtime deployment
Step 2: Create Azure Service Connection
You need an Azure service connection for App Service deployment:
- Go to Azure DevOps → Your Project
- Project Settings → Service connections → New service connection
- Choose Azure Resource Manager
- Select:
- Authentication method: Managed identity (recommended) or Service principal
- Azure subscription: Your subscription
- Resource group: Your resource group (optional)
- Service connection name:
zuyderland-cmdb-subscription(match the variable name) - Click Save
Step 3: Configure Environment
The pipeline uses an environment called production:
- Go to Pipelines → Environments
- Click Create environment
- Name:
production - Add Approvals and checks (optional):
- Approvals: Require manual approval before deployment
- Gate: Health checks before deployment
Step 4: Run Pipeline
The pipeline will automatically:
- Build Docker images
- Push to ACR
- Deploy to App Services
- Verify deployment
Trigger automatically on:
- Push to
mainbranch - Git tags starting with
v*
🔧 Configuration Options
Enable/Disable Deployment
To skip deployment (only build images):
variables:
deployToProduction: false
Or use pipeline variables in Azure DevOps:
- Go to Pipelines → Your pipeline → Edit
- Click Variables
- Add variable:
deployToProduction=false
Use Specific Image Tag
By default, the pipeline deploys the latest tag. To deploy a specific version:
# In the Deploy stage, change:
containers: '$(acrName).azurecr.io/$(repositoryName)/backend:$(imageTag)'
This will deploy the specific build ID instead of latest.
🎯 Zero-Downtime Deployment (Deployment Slots)
For production deployments without downtime, use deployment slots:
Step 1: Create Deployment Slots
# Create staging slot for backend
az webapp deployment slot create \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod \
--slot staging
# Create staging slot for frontend
az webapp deployment slot create \
--name cmdb-frontend-prod \
--resource-group rg-cmdb-insight-prod \
--slot staging
Step 2: Update Pipeline for Slots
Create azure-pipelines-slots.yml (see advanced example below) or modify the existing pipeline:
- task: AzureWebAppContainer@1
displayName: 'Deploy to Staging Slot'
inputs:
azureSubscription: '$(azureSubscription)'
appName: '$(backendAppName)'
deployToSlotOrASE: true
resourceGroupName: '$(resourceGroup)'
slotName: 'staging'
containers: '$(acrName).azurecr.io/$(repositoryName)/backend:latest'
- task: AzureCLI@2
displayName: 'Swap Staging to Production'
inputs:
azureSubscription: '$(azureSubscription)'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az webapp deployment slot swap \
--name $(backendAppName) \
--resource-group $(resourceGroup) \
--slot staging \
--target-slot production
📊 Pipeline Stages
Stage 1: Build
What it does:
- Builds backend Docker image
- Builds frontend Docker image
- Pushes both to ACR with tags:
$(Build.BuildId)andlatest
Output:
backendImage: Full image URL for backendfrontendImage: Full image URL for frontend
Stage 2: Deploy
What it does:
- Deploys backend container to App Service
- Deploys frontend container to App Service
- Restarts both App Services
- Verifies deployment with health checks
Conditions:
- Only runs if
deployToProduction = true - Only runs if Build stage succeeded
Stage 3: Verify
What it does:
- Checks backend health endpoint (
/api/health) - Checks frontend accessibility
- Reports status
🔐 Permissions Required
The Azure service connection needs:
-
App Service Contributor role on:
- Backend App Service
- Frontend App Service
- App Service Plan
-
ACR Pull permissions (if using Managed Identity):
- Already configured via Managed Identity on App Services
Grant Permissions
# Get service principal ID from Azure DevOps service connection
# Then grant permissions:
az role assignment create \
--assignee <service-principal-id> \
--role "Website Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/rg-cmdb-insight-prod
🛠️ Troubleshooting
Deployment Fails: "Service connection not found"
Solution:
- Verify service connection name matches
azureSubscriptionvariable - Check service connection exists in Project Settings → Service connections
- Verify service connection has correct permissions
Deployment Fails: "App Service not found"
Solution:
- Verify
backendAppNameandfrontendAppNamevariables are correct - Check
resourceGroupvariable matches your resource group - Verify App Services exist in Azure
Images Not Updating
Solution:
- Check if images were pushed to ACR successfully
- Verify App Service is pulling from correct ACR
- Check container settings in App Service configuration
- Ensure Managed Identity has ACR pull permissions
Health Check Fails
Solution:
- Wait longer (apps may need time to start)
- Check App Service logs:
az webapp log tail - Verify health endpoint exists:
/api/health - Check environment variables are configured correctly
📝 Manual Deployment (Alternative)
If you prefer manual deployment after pipeline builds:
# After pipeline builds images, manually deploy:
# Restart backend to pull latest image
az webapp restart \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod
# Restart frontend to pull latest image
az webapp restart \
--name cmdb-frontend-prod \
--resource-group rg-cmdb-insight-prod
🎯 Best Practices
1. Use Deployment Slots for Production
- Deploy to staging slot first
- Test in staging
- Swap to production when ready
2. Use Specific Tags for Production
Instead of latest, use version tags:
containers: '$(acrName).azurecr.io/$(repositoryName)/backend:v1.0.0'
3. Add Approvals for Production
Configure environment approvals:
- Go to Pipelines → Environments → production
- Add Approvals check
- Require manual approval before deployment
4. Monitor Deployments
- Set up alerts in Application Insights
- Monitor pipeline runs
- Check deployment logs regularly
5. Rollback Strategy
If deployment fails:
# Rollback to previous image
az webapp config container set \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod \
--docker-custom-image-name <previous-image-tag>
🔄 Workflow Example
Typical Development Workflow
- Developer pushes code to
mainbranch - Pipeline triggers automatically
- Build stage: Builds and pushes images
- Deploy stage: Deploys to App Services
- Verify stage: Checks health
- Application updated - ready to use!
Release Workflow
- Create release tag:
git tag v1.0.0 && git push origin v1.0.0 - Pipeline triggers with tag
- Build stage: Builds versioned images (
v1.0.0) - Deploy stage: Deploys to staging slot
- Manual approval (if configured)
- Swap to production: Zero-downtime deployment
- Verify: Health checks confirm success
📚 Related Documentation
AZURE-NEW-SUBSCRIPTION-SETUP.md- Initial Azure setupAZURE-APP-SERVICE-DEPLOYMENT.md- Manual deployment guideAZURE-CONTAINER-REGISTRY.md- ACR setupAZURE-DEVOPS-SETUP.md- Pipeline setup basics
✅ Checklist
- Azure service connection created
- Pipeline variables configured
- Environment
productioncreated - App Services exist in Azure
- Permissions configured
- Pipeline tested successfully
- Deployment verified
- Health checks passing
🎉 Your automated deployment pipeline is ready!
Every push to main will now automatically build and deploy your application.