# 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`: ```yaml 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: 1. **Go to Azure DevOps** → Your Project 2. **Project Settings** → **Service connections** → **New service connection** 3. Choose **Azure Resource Manager** 4. Select: - **Authentication method**: Managed identity (recommended) or Service principal - **Azure subscription**: Your subscription - **Resource group**: Your resource group (optional) 5. **Service connection name**: `zuyderland-cmdb-subscription` (match the variable name) 6. Click **Save** ### Step 3: Configure Environment The pipeline uses an `environment` called `production`: 1. **Go to Pipelines** → **Environments** 2. Click **Create environment** 3. Name: `production` 4. Add **Approvals and checks** (optional): - **Approvals**: Require manual approval before deployment - **Gate**: Health checks before deployment ### Step 4: Run Pipeline The pipeline will automatically: 1. Build Docker images 2. Push to ACR 3. Deploy to App Services 4. Verify deployment **Trigger automatically on:** - Push to `main` branch - Git tags starting with `v*` ## 🔧 Configuration Options ### Enable/Disable Deployment To skip deployment (only build images): ```yaml variables: deployToProduction: false ``` Or use pipeline variables in Azure DevOps: 1. Go to **Pipelines** → Your pipeline → **Edit** 2. Click **Variables** 3. Add variable: `deployToProduction` = `false` ### Use Specific Image Tag By default, the pipeline deploys the `latest` tag. To deploy a specific version: ```yaml # 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 ```bash # 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: ```yaml - 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)` and `latest` **Output:** - `backendImage`: Full image URL for backend - `frontendImage`: 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: 1. **App Service Contributor** role on: - Backend App Service - Frontend App Service - App Service Plan 2. **ACR Pull** permissions (if using Managed Identity): - Already configured via Managed Identity on App Services ### Grant Permissions ```bash # Get service principal ID from Azure DevOps service connection # Then grant permissions: az role assignment create \ --assignee \ --role "Website Contributor" \ --scope /subscriptions//resourceGroups/rg-cmdb-insight-prod ``` ## 🛠️ Troubleshooting ### Deployment Fails: "Service connection not found" **Solution:** - Verify service connection name matches `azureSubscription` variable - Check service connection exists in Project Settings → Service connections - Verify service connection has correct permissions ### Deployment Fails: "App Service not found" **Solution:** - Verify `backendAppName` and `frontendAppName` variables are correct - Check `resourceGroup` variable 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: ```bash # 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: ```yaml 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: ```bash # Rollback to previous image az webapp config container set \ --name cmdb-backend-prod \ --resource-group rg-cmdb-insight-prod \ --docker-custom-image-name ``` ## 🔄 Workflow Example ### Typical Development Workflow 1. **Developer pushes code** to `main` branch 2. **Pipeline triggers automatically** 3. **Build stage**: Builds and pushes images 4. **Deploy stage**: Deploys to App Services 5. **Verify stage**: Checks health 6. **Application updated** - ready to use! ### Release Workflow 1. **Create release tag**: `git tag v1.0.0 && git push origin v1.0.0` 2. **Pipeline triggers** with tag 3. **Build stage**: Builds versioned images (`v1.0.0`) 4. **Deploy stage**: Deploys to staging slot 5. **Manual approval** (if configured) 6. **Swap to production**: Zero-downtime deployment 7. **Verify**: Health checks confirm success ## 📚 Related Documentation - **`AZURE-NEW-SUBSCRIPTION-SETUP.md`** - Initial Azure setup - **`AZURE-APP-SERVICE-DEPLOYMENT.md`** - Manual deployment guide - **`AZURE-CONTAINER-REGISTRY.md`** - ACR setup - **`AZURE-DEVOPS-SETUP.md`** - Pipeline setup basics ## ✅ Checklist - [ ] Azure service connection created - [ ] Pipeline variables configured - [ ] Environment `production` created - [ ] 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.