Files
cmdb-insight/docs/AZURE-PIPELINE-DEPLOYMENT.md
Bert Hausmans 42a04e6cb3 Add Azure deployment automation and documentation
- 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
2026-01-21 23:03:48 +01:00

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:

  1. Go to Azure DevOps → Your Project
  2. Project SettingsService connectionsNew 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 PipelinesEnvironments
  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):

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:

# 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) 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

# 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 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:

# 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 PipelinesEnvironmentsproduction
  • 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

  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
  • 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.