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
This commit is contained in:
2026-01-21 23:03:48 +01:00
parent 52f851c1f3
commit 42a04e6cb3
10 changed files with 3176 additions and 0 deletions

View File

@@ -0,0 +1,337 @@
# 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 <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:
```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 <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
## 📚 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.