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,317 @@
# Shared Azure Container Registry Setup
Guide for using a shared Azure Container Registry across multiple applications.
## 🎯 Why Share ACR?
**Benefits:**
-**Cost Savings**: One ACR for all applications (€5-20/month vs multiple ACRs)
-**Centralized Management**: All images in one place
-**Easier Collaboration**: Teams can share images
-**Better Resource Utilization**: More efficient use of storage
**How it works:**
- ACR is shared, but each application uses a **unique repository name**
- Repository name (`cmdb-insight`) separates your app from others
- Images are organized by application: `acr.azurecr.io/app-name/service:tag`
## 📦 ACR Structure
```
zuyderlandacr.azurecr.io/
├── cmdb-insight/ ← This application
│ ├── backend:latest
│ ├── backend:v1.0.0
│ ├── frontend:latest
│ └── frontend:v1.0.0
├── other-app/ ← Another application
│ ├── api:latest
│ └── web:latest
└── shared-services/ ← Shared base images
├── nginx:latest
└── node:20-alpine
```
## 🔧 Setup Options
### Option 1: Use Existing ACR (Recommended)
If you already have an ACR for other applications:
```bash
# Set your existing ACR details
ACR_NAME="your-existing-acr"
ACR_RESOURCE_GROUP="rg-shared-services" # Or wherever your ACR is
# Verify it exists
az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP
# Get login server
ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query loginServer --output tsv)
echo "ACR Login Server: $ACR_LOGIN_SERVER"
```
**That's it!** Your images will be stored as:
- `your-existing-acr.azurecr.io/cmdb-insight/backend:latest`
- `your-existing-acr.azurecr.io/cmdb-insight/frontend:latest`
### Option 2: Create New Shared ACR
If you don't have an ACR yet, create one that can be shared:
```bash
# Set variables
ACR_NAME="zuyderlandacr" # Recommended: company name + "acr"
ACR_RESOURCE_GROUP="rg-shared-services" # Shared resource group
LOCATION="westeurope"
SKU="Standard" # Recommended for shared ACR
# Create resource group for shared services
az group create --name $ACR_RESOURCE_GROUP --location $LOCATION
# Create ACR
az acr create \
--resource-group $ACR_RESOURCE_GROUP \
--name $ACR_NAME \
--sku $SKU \
--admin-enabled true
# Verify
az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP
```
## 🚀 Using Shared ACR
### Build and Push Images
```bash
# Set ACR name
export ACR_NAME="zuyderlandacr"
export REPO_NAME="cmdb-insight" # This is your app identifier
# Build and push (repository name separates your app)
./scripts/build-and-push-azure.sh
# Images will be:
# - zuyderlandacr.azurecr.io/cmdb-insight/backend:latest
# - zuyderlandacr.azurecr.io/cmdb-insight/frontend:latest
```
### Configure App Services
```bash
# Backend App Service
az webapp config container set \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod \
--docker-custom-image-name "zuyderlandacr.azurecr.io/cmdb-insight/backend:latest" \
--docker-registry-server-url "https://zuyderlandacr.azurecr.io"
# Frontend App Service
az webapp config container set \
--name cmdb-frontend-prod \
--resource-group rg-cmdb-insight-prod \
--docker-custom-image-name "zuyderlandacr.azurecr.io/cmdb-insight/frontend:latest" \
--docker-registry-server-url "https://zuyderlandacr.azurecr.io"
```
### Update Pipeline Variables
In `azure-pipelines.yml`:
```yaml
variables:
acrName: 'yourcompanyacr' # Shared ACR name
repositoryName: 'cmdb-insight' # Your app repository name
# ... other variables
```
## 🔐 Permissions
### Grant App Services Access to Shared ACR
```bash
# Get App Service Managed Identity
BACKEND_PRINCIPAL_ID=$(az webapp identity show \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod \
--query principalId --output tsv)
# Get ACR Resource ID (from shared resource group)
ACR_ID=$(az acr show \
--name zuyderlandacr \
--resource-group rg-shared-services \
--query id --output tsv)
# Grant AcrPull permission
az role assignment create \
--assignee $BACKEND_PRINCIPAL_ID \
--role AcrPull \
--scope $ACR_ID
```
## 📊 Managing Multiple Applications
### List All Repositories
```bash
# See all applications in ACR
az acr repository list --name zuyderlandacr
# Output:
# cmdb-insight
# other-app
# shared-services
```
### List Images for This App
```bash
# Backend images
az acr repository show-tags \
--name zuyderlandacr \
--repository cmdb-insight/backend
# Frontend images
az acr repository show-tags \
--name zuyderlandacr \
--repository cmdb-insight/frontend
```
### Clean Up Old Images
```bash
# Delete old tags (keep last 10)
az acr repository show-tags \
--name zuyderlandacr \
--repository cmdb-insight/backend \
--orderby time_desc \
--query '[10:].name' \
--output tsv | \
xargs -I {} az acr repository delete \
--name zuyderlandacr \
--image cmdb-insight/backend:{} \
--yes
```
## 💰 Cost Optimization
### Shared ACR Costs
| SKU | Storage | Cost | Best For |
|-----|---------|------|----------|
| Basic | 10GB | €5/month | Small teams, few apps |
| Standard | 100GB | €20/month | **Recommended for shared ACR** |
| Premium | 500GB | €50/month | Large organizations |
**Recommendation**: Use **Standard** SKU for shared ACR:
- Enough storage for multiple applications
- Geo-replication available
- Good balance of cost and features
### Cost Savings Example
**Without sharing:**
- App 1 ACR: €20/month
- App 2 ACR: €20/month
- App 3 ACR: €20/month
- **Total: €60/month**
**With shared ACR:**
- Shared ACR (Standard): €20/month
- **Total: €20/month**
- **Savings: €40/month (67%)**
## 🎯 Best Practices
### 1. Naming Convention
Use consistent repository naming:
- `app-name/service:tag` (e.g., `cmdb-insight/backend:latest`)
- Avoid generic names like `backend`, `frontend`
- Include app identifier in repository name
### 2. Resource Group Organization
**Option A: Separate Resource Groups**
```
rg-shared-services/
└── ACR (shared)
rg-cmdb-insight-prod/
└── App-specific resources
```
**Option B: Single Resource Group**
```
rg-production/
├── ACR
├── App 1 resources
├── App 2 resources
└── App 3 resources
```
### 3. Access Control
- Use **Managed Identity** for App Services (recommended)
- Grant **AcrPull** role (not AcrPush) to App Services
- Use **Service Principals** for CI/CD pipelines
- Consider **Azure RBAC** for fine-grained access
### 4. Image Tagging Strategy
```bash
# Use semantic versioning
cmdb-insight/backend:v1.0.0
cmdb-insight/backend:v1.0.1
cmdb-insight/backend:latest
# Use build IDs for CI/CD
cmdb-insight/backend:12345
cmdb-insight/backend:latest
```
## 🔄 Migration from Dedicated ACR
If you have a dedicated ACR and want to migrate to shared:
```bash
# 1. Tag images with new repository name
docker tag oldacr.azurecr.io/backend:latest newacr.azurecr.io/cmdb-insight/backend:latest
docker tag oldacr.azurecr.io/frontend:latest newacr.azurecr.io/cmdb-insight/frontend:latest
# 2. Push to shared ACR
docker push newacr.azurecr.io/cmdb-insight/backend:latest
docker push newacr.azurecr.io/cmdb-insight/frontend:latest
# 3. Update App Services
az webapp config container set \
--name cmdb-backend-prod \
--resource-group rg-cmdb-insight-prod \
--docker-custom-image-name "newacr.azurecr.io/cmdb-insight/backend:latest"
# 4. Update pipeline variables
# 5. Test deployment
# 6. Delete old ACR (after verification)
```
## 📚 Related Documentation
- **`AZURE-NEW-SUBSCRIPTION-SETUP.md`** - Complete Azure setup guide
- **`AZURE-CONTAINER-REGISTRY.md`** - ACR setup and usage
- **`AZURE-PIPELINE-DEPLOYMENT.md`** - Automated deployment
## ✅ Checklist
- [ ] Decide: Use existing ACR or create new shared ACR
- [ ] Verify ACR exists or create new one
- [ ] Update pipeline variables with ACR name
- [ ] Grant App Services access to ACR
- [ ] Build and push images with repository name `cmdb-insight`
- [ ] Configure App Services to use shared ACR
- [ ] Test deployment
- [ ] Document ACR name for team
---
**💡 Remember**: The repository name (`cmdb-insight`) is what separates your application from others in the shared ACR!