- 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
318 lines
8.2 KiB
Markdown
318 lines
8.2 KiB
Markdown
# 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!
|