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:
165
docs/AZURE-ACR-NAMING-RECOMMENDATION.md
Normal file
165
docs/AZURE-ACR-NAMING-RECOMMENDATION.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Azure Container Registry Naming Recommendation
|
||||
|
||||
Recommendations for naming your Azure Container Registry for Zuyderland Application Services.
|
||||
|
||||
## 🎯 Requirements
|
||||
|
||||
Azure Container Registry names must:
|
||||
- Be **globally unique** (across all Azure subscriptions)
|
||||
- Be **5-50 characters** long
|
||||
- Contain **only lowercase alphanumeric characters** (no hyphens, underscores, or special characters)
|
||||
- Be **descriptive** but not too long
|
||||
|
||||
## 💡 Recommended Options
|
||||
|
||||
### Option 1: `zuyderlandacr` ⭐ **RECOMMENDED**
|
||||
|
||||
**Pros:**
|
||||
- ✅ Clear company identification
|
||||
- ✅ Short and memorable (15 characters)
|
||||
- ✅ Generic enough for all Application Services apps
|
||||
- ✅ Easy to type and remember
|
||||
- ✅ Professional appearance
|
||||
|
||||
**Cons:**
|
||||
- ⚠️ Might be taken if Zuyderland already has an ACR
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
ACR_NAME="zuyderlandacr"
|
||||
# Images: zuyderlandacr.azurecr.io/cmdb-insight/backend:latest
|
||||
```
|
||||
|
||||
### Option 2: `zuyderlandsharedacr`
|
||||
|
||||
**Pros:**
|
||||
- ✅ Clearly indicates it's a shared registry
|
||||
- ✅ Company identification
|
||||
- ✅ Good for documentation ("shared ACR")
|
||||
|
||||
**Cons:**
|
||||
- ⚠️ Longer (20 characters)
|
||||
- ⚠️ "shared" might be redundant (ACRs are typically shared)
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
ACR_NAME="zuyderlandsharedacr"
|
||||
# Images: zuyderlandsharedacr.azurecr.io/cmdb-insight/backend:latest
|
||||
```
|
||||
|
||||
### Option 3: `zyldacr` (Abbreviated)
|
||||
|
||||
**Pros:**
|
||||
- ✅ Very short (7 characters)
|
||||
- ✅ Easy to type
|
||||
- ✅ Less likely to be taken
|
||||
|
||||
**Cons:**
|
||||
- ⚠️ Less clear what "zyld" means
|
||||
- ⚠️ Might not be obvious it's Zuyderland
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
ACR_NAME="zyldacr"
|
||||
# Images: zyldacr.azurecr.io/cmdb-insight/backend:latest
|
||||
```
|
||||
|
||||
### Option 4: `zuyderlandappsvcsacr`
|
||||
|
||||
**Pros:**
|
||||
- ✅ Includes department name (Application Services)
|
||||
- ✅ Very specific
|
||||
|
||||
**Cons:**
|
||||
- ⚠️ Long (23 characters)
|
||||
- ⚠️ Less flexible if other departments want to use it
|
||||
- ⚠️ Harder to type
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
ACR_NAME="zuyderlandappsvcsacr"
|
||||
# Images: zuyderlandappsvcsacr.azurecr.io/cmdb-insight/backend:latest
|
||||
```
|
||||
|
||||
## 🏆 Final Recommendation
|
||||
|
||||
**Use: `zuyderlandacr`**
|
||||
|
||||
**Reasoning:**
|
||||
1. **Clear and professional**: Immediately identifies as Zuyderland
|
||||
2. **Appropriate length**: Not too short (unclear) or too long (hard to type)
|
||||
3. **Generic enough**: Can be used by all Application Services applications
|
||||
4. **Future-proof**: Works for any department or team within Zuyderland
|
||||
5. **Standard pattern**: Follows common naming convention (`companynameacr`)
|
||||
|
||||
## 🔍 Check Availability
|
||||
|
||||
Before creating, check if the name is available:
|
||||
|
||||
```bash
|
||||
# Try to check if name exists (will fail if available, which is good)
|
||||
az acr show --name zuyderlandacr --resource-group dummy-rg 2>&1 | grep -q "could not be found" && echo "Name available!" || echo "Name might be taken"
|
||||
|
||||
# Or try to create (will fail if taken)
|
||||
az acr check-name --name zuyderlandacr
|
||||
```
|
||||
|
||||
## 📝 Alternative if Name is Taken
|
||||
|
||||
If `zuyderlandacr` is already taken, try:
|
||||
|
||||
1. `zuyderlandacr01` - Add number suffix
|
||||
2. `zuyderlandacrprod` - Add environment suffix
|
||||
3. `zyldacr` - Use abbreviation
|
||||
4. `zuyderlandregistry` - Use full word "registry"
|
||||
5. `zuyderlandcontainers` - Use "containers" instead of "acr"
|
||||
|
||||
## 🎯 Naming Pattern
|
||||
|
||||
For consistency across Zuyderland, consider this pattern:
|
||||
|
||||
```
|
||||
zuyderlandacr ← Shared ACR for all apps (recommended)
|
||||
zuyderlandacrdev ← Development ACR (if needed)
|
||||
zuyderlandacrprod ← Production ACR (if separate)
|
||||
```
|
||||
|
||||
**But for most cases, one shared ACR (`zuyderlandacr`) is sufficient.**
|
||||
|
||||
## 📋 Update Your Configuration
|
||||
|
||||
Once you've chosen a name, update:
|
||||
|
||||
### 1. Setup Script
|
||||
```bash
|
||||
# In scripts/setup-azure-resources.sh
|
||||
ACR_NAME="zuyderlandacr"
|
||||
ACR_RESOURCE_GROUP="rg-shared-services" # Or rg-zuyderland-shared
|
||||
```
|
||||
|
||||
### 2. Pipeline Variables
|
||||
```yaml
|
||||
# In azure-pipelines.yml
|
||||
variables:
|
||||
acrName: 'zuyderlandacr'
|
||||
repositoryName: 'cmdb-insight'
|
||||
```
|
||||
|
||||
### 3. Build Scripts
|
||||
```bash
|
||||
# In scripts/build-and-push-azure.sh
|
||||
export ACR_NAME="zuyderlandacr"
|
||||
```
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
- [ ] Choose ACR name: `zuyderlandacr` (recommended)
|
||||
- [ ] Check name availability
|
||||
- [ ] Create ACR with chosen name
|
||||
- [ ] Update all configuration files
|
||||
- [ ] Document name for team
|
||||
- [ ] Share ACR name with other Application Services teams
|
||||
|
||||
---
|
||||
|
||||
**Recommended: `zuyderlandacr`** - Clear, professional, and reusable for all Zuyderland Application Services applications.
|
||||
317
docs/AZURE-ACR-SHARED-SETUP.md
Normal file
317
docs/AZURE-ACR-SHARED-SETUP.md
Normal 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!
|
||||
943
docs/AZURE-NEW-SUBSCRIPTION-SETUP.md
Normal file
943
docs/AZURE-NEW-SUBSCRIPTION-SETUP.md
Normal file
@@ -0,0 +1,943 @@
|
||||
# Azure New Subscription Setup Guide
|
||||
|
||||
Complete guide for setting up all required Azure resources for CMDB Insight in a new Azure subscription.
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide will help you create and configure all necessary Azure resources to deploy the CMDB Insight application. The setup includes:
|
||||
|
||||
### Required Resources
|
||||
|
||||
1. **Resource Group** - Container for all resources
|
||||
2. **Azure Container Registry (ACR)** - Store Docker images
|
||||
3. **Azure Database for PostgreSQL** - Production database (recommended)
|
||||
4. **Azure Key Vault** - Secure storage for secrets
|
||||
5. **Azure App Service Plan** - Hosting plan for web apps
|
||||
6. **Azure App Service (Backend)** - Backend API service
|
||||
7. **Azure App Service (Frontend)** - Frontend web application
|
||||
8. **Application Insights** - Monitoring and logging
|
||||
9. **DNS & SSL** - Custom domain and HTTPS certificate
|
||||
|
||||
### Estimated Costs
|
||||
|
||||
- **Basic Setup (SQLite)**: €17-35/month
|
||||
- **Recommended Setup (PostgreSQL)**: €36-62/month
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prerequisites
|
||||
|
||||
Before starting, ensure you have:
|
||||
|
||||
- [ ] Azure CLI installed (`az --version`)
|
||||
- [ ] Azure subscription with appropriate permissions
|
||||
- [ ] Docker installed (for local testing)
|
||||
- [ ] Access to Azure Portal
|
||||
- [ ] Jira credentials (OAuth client ID/secret or Personal Access Token)
|
||||
|
||||
### Install Azure CLI (if needed)
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install azure-cli
|
||||
|
||||
# Linux
|
||||
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
|
||||
|
||||
# Windows
|
||||
# Download from: https://aka.ms/installazurecliwindows
|
||||
```
|
||||
|
||||
### Login to Azure
|
||||
|
||||
```bash
|
||||
az login
|
||||
az account list --output table
|
||||
az account set --subscription "<subscription-id-or-name>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Step 1: Create Resource Group
|
||||
|
||||
Create a resource group to organize all resources:
|
||||
|
||||
```bash
|
||||
# Set variables (customize as needed)
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
LOCATION="westeurope" # or your preferred region
|
||||
|
||||
# Create resource group
|
||||
az group create \
|
||||
--name $RESOURCE_GROUP \
|
||||
--location $LOCATION
|
||||
|
||||
# Verify
|
||||
az group show --name $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
**Note**: Choose a location close to your users. Common options:
|
||||
- `westeurope` (Netherlands, Germany)
|
||||
- `northeurope` (Ireland, UK)
|
||||
- `eastus` (US East)
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Step 2: Create or Use Existing Azure Container Registry (ACR)
|
||||
|
||||
**Important**: Azure Container Registry can be **shared across multiple applications**. The repository name (`cmdb-insight`) is what separates this application from others in the same ACR.
|
||||
|
||||
### Option A: Use Existing ACR (Recommended if you have one)
|
||||
|
||||
If you already have an ACR for other applications, you can reuse it:
|
||||
|
||||
```bash
|
||||
# Set variables - use your existing ACR name
|
||||
ACR_NAME="your-existing-acr" # Your existing ACR name
|
||||
ACR_RESOURCE_GROUP="rg-shared-services" # Resource group where ACR exists
|
||||
|
||||
# Verify ACR exists
|
||||
az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP
|
||||
|
||||
# Get ACR 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"
|
||||
```
|
||||
|
||||
**Benefits of reusing ACR**:
|
||||
- ✅ Cost savings (one ACR for all apps)
|
||||
- ✅ Centralized image management
|
||||
- ✅ Easier to share images across teams
|
||||
- ✅ Better resource utilization
|
||||
|
||||
### Option B: Create New ACR
|
||||
|
||||
If you don't have an ACR yet, create one:
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
ACR_NAME="yourcompanyacr" # Must be globally unique, lowercase, 5-50 chars, alphanumeric only
|
||||
ACR_RESOURCE_GROUP="rg-shared-services" # Or use your app resource group
|
||||
SKU="Standard" # Options: Basic, Standard, Premium
|
||||
|
||||
# Create resource group for shared services (if needed)
|
||||
az group create --name $ACR_RESOURCE_GROUP --location westeurope
|
||||
|
||||
# Create ACR
|
||||
az acr create \
|
||||
--resource-group $ACR_RESOURCE_GROUP \
|
||||
--name $ACR_NAME \
|
||||
--sku $SKU \
|
||||
--admin-enabled true
|
||||
|
||||
# Get ACR 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"
|
||||
|
||||
# Get admin credentials (save these securely)
|
||||
az acr credential show --name $ACR_NAME
|
||||
```
|
||||
|
||||
**ACR SKU Comparison**:
|
||||
- **Basic**: €5/month - Development/test, 10GB storage
|
||||
- **Standard**: €20/month - Production, 100GB storage, geo-replication (recommended)
|
||||
- **Premium**: €50/month - Enterprise, 500GB storage, advanced security
|
||||
|
||||
**Repository Structure in ACR**:
|
||||
```
|
||||
yourcompanyacr.azurecr.io/
|
||||
├── cmdb-insight/ ← This application
|
||||
│ ├── backend:latest
|
||||
│ └── frontend:latest
|
||||
├── other-app/ ← Other applications
|
||||
│ ├── api:latest
|
||||
│ └── web:latest
|
||||
└── shared-services/ ← Shared images
|
||||
└── nginx:latest
|
||||
```
|
||||
|
||||
### Test ACR Connection
|
||||
|
||||
```bash
|
||||
# Login to ACR
|
||||
az acr login --name $ACR_NAME
|
||||
|
||||
# Verify
|
||||
az acr repository list --name $ACR_NAME
|
||||
|
||||
# List repositories (you'll see cmdb-insight after first push)
|
||||
az acr repository list --name $ACR_NAME --output table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Step 3: Create Azure Database for PostgreSQL
|
||||
|
||||
PostgreSQL is recommended for production. Alternatively, you can use SQLite with Azure Storage (see Step 3B).
|
||||
|
||||
### Step 3A: PostgreSQL (Recommended)
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
DB_SERVER_NAME="cmdb-postgres-prod" # Must be globally unique
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
DB_ADMIN_USER="cmdbadmin"
|
||||
DB_ADMIN_PASSWORD="<generate-secure-password>" # Use a strong password!
|
||||
DB_NAME="cmdb"
|
||||
SKU="Standard_B1ms" # Burstable tier, 1 vCore, 2GB RAM
|
||||
|
||||
# Generate secure password (save this!)
|
||||
DB_ADMIN_PASSWORD=$(openssl rand -base64 32)
|
||||
echo "Database Password: $DB_ADMIN_PASSWORD"
|
||||
|
||||
# Create PostgreSQL Flexible Server
|
||||
az postgres flexible-server create \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--name $DB_SERVER_NAME \
|
||||
--location westeurope \
|
||||
--admin-user $DB_ADMIN_USER \
|
||||
--admin-password $DB_ADMIN_PASSWORD \
|
||||
--sku-name $SKU \
|
||||
--tier Burstable \
|
||||
--storage-size 32 \
|
||||
--version 15 \
|
||||
--public-access 0.0.0.0 # Allow Azure services (restrict later if needed)
|
||||
|
||||
# Create database
|
||||
az postgres flexible-server db create \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--server-name $DB_SERVER_NAME \
|
||||
--database-name $DB_NAME
|
||||
|
||||
# Get connection string
|
||||
DB_CONNECTION_STRING="postgresql://${DB_ADMIN_USER}:${DB_ADMIN_PASSWORD}@${DB_SERVER_NAME}.postgres.database.azure.com:5432/${DB_NAME}?sslmode=require"
|
||||
echo "Database Connection String: $DB_CONNECTION_STRING"
|
||||
|
||||
# Save connection details securely
|
||||
echo "DB_HOST=${DB_SERVER_NAME}.postgres.database.azure.com" > .env.azure
|
||||
echo "DB_USER=${DB_ADMIN_USER}" >> .env.azure
|
||||
echo "DB_PASSWORD=${DB_ADMIN_PASSWORD}" >> .env.azure
|
||||
echo "DB_NAME=${DB_NAME}" >> .env.azure
|
||||
```
|
||||
|
||||
**PostgreSQL SKU Options**:
|
||||
- **Standard_B1ms**: €20-30/month - 1 vCore, 2GB RAM (recommended for 20 users)
|
||||
- **Standard_B2s**: €40-50/month - 2 vCores, 4GB RAM (for growth)
|
||||
- **Standard_D2s_v3**: €100+/month - 2 vCores, 8GB RAM (high performance)
|
||||
|
||||
### Step 3B: SQLite with Azure Storage (Alternative)
|
||||
|
||||
If you prefer to use SQLite (simpler, but less scalable):
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
STORAGE_ACCOUNT_NAME="cmdbstorage$(openssl rand -hex 4)" # Must be globally unique, lowercase
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
|
||||
# Create storage account
|
||||
az storage account create \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--name $STORAGE_ACCOUNT_NAME \
|
||||
--location westeurope \
|
||||
--sku Standard_LRS
|
||||
|
||||
# Get storage account key
|
||||
STORAGE_KEY=$(az storage account keys list \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--account-name $STORAGE_ACCOUNT_NAME \
|
||||
--query "[0].value" --output tsv)
|
||||
|
||||
echo "Storage Account: $STORAGE_ACCOUNT_NAME"
|
||||
echo "Storage Key: $STORAGE_KEY"
|
||||
```
|
||||
|
||||
**Note**: SQLite works but has limitations with concurrent users. PostgreSQL is recommended for production.
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Step 4: Create Azure Key Vault
|
||||
|
||||
Key Vault securely stores secrets like API keys, passwords, and tokens.
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
KEY_VAULT_NAME="kv-cmdb-insight-prod" # Must be globally unique
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
|
||||
# Create Key Vault
|
||||
az keyvault create \
|
||||
--name $KEY_VAULT_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--location westeurope \
|
||||
--sku standard
|
||||
|
||||
# Verify
|
||||
az keyvault show --name $KEY_VAULT_NAME --resource-group $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
### Add Secrets to Key Vault
|
||||
|
||||
```bash
|
||||
# Set your actual values
|
||||
JIRA_PAT="your-jira-personal-access-token"
|
||||
SESSION_SECRET=$(openssl rand -hex 32)
|
||||
JIRA_OAUTH_CLIENT_ID="your-oauth-client-id"
|
||||
JIRA_OAUTH_CLIENT_SECRET="your-oauth-client-secret"
|
||||
JIRA_SCHEMA_ID="your-schema-id"
|
||||
|
||||
# Add secrets
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "JiraPat" \
|
||||
--value "$JIRA_PAT"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "SessionSecret" \
|
||||
--value "$SESSION_SECRET"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "JiraOAuthClientId" \
|
||||
--value "$JIRA_OAUTH_CLIENT_ID"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "JiraOAuthClientSecret" \
|
||||
--value "$JIRA_OAUTH_CLIENT_SECRET"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "JiraSchemaId" \
|
||||
--value "$JIRA_SCHEMA_ID"
|
||||
|
||||
# If using PostgreSQL, add database password
|
||||
az keyvault secret set \
|
||||
--vault-name $KEY_VAULT_NAME \
|
||||
--name "DatabasePassword" \
|
||||
--value "$DB_ADMIN_PASSWORD"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Step 5: Create Application Insights
|
||||
|
||||
Application Insights provides monitoring, logging, and performance metrics.
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
APP_INSIGHTS_NAME="appi-cmdb-insight-prod"
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
|
||||
# Create Application Insights
|
||||
az monitor app-insights component create \
|
||||
--app $APP_INSIGHTS_NAME \
|
||||
--location westeurope \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--application-type web
|
||||
|
||||
# Get Instrumentation Key
|
||||
INSTRUMENTATION_KEY=$(az monitor app-insights component show \
|
||||
--app $APP_INSIGHTS_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--query instrumentationKey --output tsv)
|
||||
|
||||
echo "Instrumentation Key: $INSTRUMENTATION_KEY"
|
||||
```
|
||||
|
||||
**Note**: Application Insights Basic tier is free up to 5GB/month, which is sufficient for most small applications.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Step 6: Create App Service Plan
|
||||
|
||||
App Service Plan defines the compute resources for your web apps.
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
APP_SERVICE_PLAN_NAME="plan-cmdb-insight-prod"
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
SKU="B1" # Basic tier, 1 vCore, 1.75GB RAM
|
||||
|
||||
# Create App Service Plan (Linux)
|
||||
az appservice plan create \
|
||||
--name $APP_SERVICE_PLAN_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--sku $SKU \
|
||||
--is-linux
|
||||
|
||||
# Verify
|
||||
az appservice plan show --name $APP_SERVICE_PLAN_NAME --resource-group $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
**App Service Plan SKU Options**:
|
||||
- **B1**: €15-25/month - 1 vCore, 1.75GB RAM (recommended for 20 users)
|
||||
- **B2**: €30-40/month - 2 vCores, 3.5GB RAM
|
||||
- **S1**: €50-70/month - 1 vCore, 1.75GB RAM (Standard tier, better performance)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Step 7: Create App Services (Backend & Frontend)
|
||||
|
||||
Create two web apps: one for backend API and one for frontend.
|
||||
|
||||
### Step 7A: Create Backend App Service
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
BACKEND_APP_NAME="cmdb-backend-prod" # Must be globally unique
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
APP_SERVICE_PLAN_NAME="plan-cmdb-insight-prod"
|
||||
ACR_NAME="cmdbinsightacr" # From Step 2
|
||||
|
||||
# Create backend web app
|
||||
az webapp create \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--plan $APP_SERVICE_PLAN_NAME \
|
||||
--deployment-container-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/backend:latest"
|
||||
|
||||
# Enable Managed Identity (for ACR access)
|
||||
az webapp identity assign \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP
|
||||
|
||||
# Get Managed Identity Principal ID
|
||||
BACKEND_PRINCIPAL_ID=$(az webapp identity show \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--query principalId --output tsv)
|
||||
|
||||
# Grant ACR pull permissions
|
||||
ACR_ID=$(az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP --query id --output tsv)
|
||||
az role assignment create \
|
||||
--assignee $BACKEND_PRINCIPAL_ID \
|
||||
--role AcrPull \
|
||||
--scope $ACR_ID
|
||||
|
||||
# Configure container settings
|
||||
az webapp config container set \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--docker-custom-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/backend:latest" \
|
||||
--docker-registry-server-url "https://${ACR_NAME}.azurecr.io"
|
||||
|
||||
# Set environment variables
|
||||
az webapp config appsettings set \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--settings \
|
||||
NODE_ENV=production \
|
||||
PORT=3001 \
|
||||
DATABASE_TYPE=postgres \
|
||||
DATABASE_URL="@Microsoft.KeyVault(SecretUri=https://${KEY_VAULT_NAME}.vault.azure.net/secrets/DatabasePassword/)" \
|
||||
JIRA_HOST=https://jira.zuyderland.nl \
|
||||
JIRA_AUTH_METHOD=oauth \
|
||||
JIRA_OAUTH_CLIENT_ID="@Microsoft.KeyVault(SecretUri=https://${KEY_VAULT_NAME}.vault.azure.net/secrets/JiraOAuthClientId/)" \
|
||||
JIRA_OAUTH_CLIENT_SECRET="@Microsoft.KeyVault(SecretUri=https://${KEY_VAULT_NAME}.vault.azure.net/secrets/JiraOAuthClientSecret/)" \
|
||||
JIRA_OAUTH_CALLBACK_URL="https://${BACKEND_APP_NAME}.azurewebsites.net/api/auth/callback" \
|
||||
JIRA_SCHEMA_ID="@Microsoft.KeyVault(SecretUri=https://${KEY_VAULT_NAME}.vault.azure.net/secrets/JiraSchemaId/)" \
|
||||
SESSION_SECRET="@Microsoft.KeyVault(SecretUri=https://${KEY_VAULT_NAME}.vault.azure.net/secrets/SessionSecret/)" \
|
||||
FRONTEND_URL="https://${FRONTEND_APP_NAME}.azurewebsites.net" \
|
||||
APPINSIGHTS_INSTRUMENTATIONKEY="${INSTRUMENTATION_KEY}"
|
||||
|
||||
# Grant Key Vault access to backend
|
||||
az keyvault set-policy \
|
||||
--name $KEY_VAULT_NAME \
|
||||
--object-id $BACKEND_PRINCIPAL_ID \
|
||||
--secret-permissions get list
|
||||
|
||||
# Enable HTTPS only
|
||||
az webapp update \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--https-only true
|
||||
```
|
||||
|
||||
### Step 7B: Create Frontend App Service
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
FRONTEND_APP_NAME="cmdb-frontend-prod" # Must be globally unique
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
APP_SERVICE_PLAN_NAME="plan-cmdb-insight-prod"
|
||||
ACR_NAME="cmdbinsightacr" # From Step 2
|
||||
|
||||
# Create frontend web app
|
||||
az webapp create \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--plan $APP_SERVICE_PLAN_NAME \
|
||||
--deployment-container-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/frontend:latest"
|
||||
|
||||
# Enable Managed Identity
|
||||
az webapp identity assign \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP
|
||||
|
||||
# Get Managed Identity Principal ID
|
||||
FRONTEND_PRINCIPAL_ID=$(az webapp identity show \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--query principalId --output tsv)
|
||||
|
||||
# Grant ACR pull permissions
|
||||
az role assignment create \
|
||||
--assignee $FRONTEND_PRINCIPAL_ID \
|
||||
--role AcrPull \
|
||||
--scope $ACR_ID
|
||||
|
||||
# Configure container settings
|
||||
az webapp config container set \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--docker-custom-image-name "${ACR_NAME}.azurecr.io/cmdb-insight/frontend:latest" \
|
||||
--docker-registry-server-url "https://${ACR_NAME}.azurecr.io"
|
||||
|
||||
# Set environment variables
|
||||
az webapp config appsettings set \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--settings \
|
||||
VITE_API_URL="https://${BACKEND_APP_NAME}.azurewebsites.net/api"
|
||||
|
||||
# Enable HTTPS only
|
||||
az webapp update \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--https-only true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Step 8: Build and Push Docker Images
|
||||
|
||||
Before the apps can run, you need to build and push Docker images to ACR.
|
||||
|
||||
### Option A: Using Script (Recommended)
|
||||
|
||||
```bash
|
||||
# Navigate to project root
|
||||
cd /path/to/cmdb-insight
|
||||
|
||||
# Set environment variables
|
||||
export ACR_NAME="cmdbinsightacr" # Your ACR name
|
||||
export REPO_NAME="cmdb-insight"
|
||||
|
||||
# Build and push
|
||||
./scripts/build-and-push-azure.sh
|
||||
```
|
||||
|
||||
### Option B: Manual Build and Push
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
ACR_NAME="cmdbinsightacr"
|
||||
REGISTRY="${ACR_NAME}.azurecr.io"
|
||||
REPO_NAME="cmdb-insight"
|
||||
|
||||
# Login to ACR
|
||||
az acr login --name $ACR_NAME
|
||||
|
||||
# Build backend
|
||||
docker build -t ${REGISTRY}/${REPO_NAME}/backend:latest \
|
||||
-f backend/Dockerfile.prod ./backend
|
||||
|
||||
# Build frontend
|
||||
docker build -t ${REGISTRY}/${REPO_NAME}/frontend:latest \
|
||||
-f frontend/Dockerfile.prod ./frontend
|
||||
|
||||
# Push images
|
||||
docker push ${REGISTRY}/${REPO_NAME}/backend:latest
|
||||
docker push ${REGISTRY}/${REPO_NAME}/frontend:latest
|
||||
|
||||
# Verify
|
||||
az acr repository list --name $ACR_NAME
|
||||
az acr repository show-tags --name $ACR_NAME --repository ${REPO_NAME}/backend
|
||||
az acr repository show-tags --name $ACR_NAME --repository ${REPO_NAME}/frontend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Step 9: Configure Custom Domain and SSL (Optional)
|
||||
|
||||
If you have a custom domain (e.g., `cmdb.yourcompany.com`):
|
||||
|
||||
### Step 9A: Add Custom Domain
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
FRONTEND_APP_NAME="cmdb-frontend-prod"
|
||||
BACKEND_APP_NAME="cmdb-backend-prod"
|
||||
CUSTOM_DOMAIN="cmdb.yourcompany.com"
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
|
||||
# Add custom domain to frontend
|
||||
az webapp config hostname add \
|
||||
--webapp-name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--hostname $CUSTOM_DOMAIN
|
||||
|
||||
# Add custom domain to backend (if needed)
|
||||
az webapp config hostname add \
|
||||
--webapp-name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--hostname "api.${CUSTOM_DOMAIN}"
|
||||
```
|
||||
|
||||
### Step 9B: Configure SSL Certificate
|
||||
|
||||
**Option 1: App Service Managed Certificate (Free, Recommended)**
|
||||
|
||||
```bash
|
||||
# Create managed certificate for frontend
|
||||
az webapp config ssl create \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--hostname $CUSTOM_DOMAIN
|
||||
|
||||
# Bind certificate
|
||||
az webapp config ssl bind \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--certificate-thumbprint <thumbprint> \
|
||||
--ssl-type SNI
|
||||
```
|
||||
|
||||
**Option 2: Import Existing Certificate**
|
||||
|
||||
```bash
|
||||
# Upload certificate
|
||||
az webapp config ssl upload \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--certificate-file /path/to/certificate.pfx \
|
||||
--certificate-password <password>
|
||||
```
|
||||
|
||||
**Note**: You'll need to update DNS records to point to your App Service. Get the IP address:
|
||||
|
||||
```bash
|
||||
az webapp show --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP --query defaultHostName
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Step 10: Verify Deployment
|
||||
|
||||
### Check App Status
|
||||
|
||||
```bash
|
||||
# Check backend
|
||||
az webapp show --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP --query state
|
||||
|
||||
# Check frontend
|
||||
az webapp show --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP --query state
|
||||
|
||||
# Start apps if needed
|
||||
az webapp start --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
az webapp start --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
### Test Health Endpoints
|
||||
|
||||
```bash
|
||||
# Backend health check
|
||||
curl https://${BACKEND_APP_NAME}.azurewebsites.net/api/health
|
||||
|
||||
# Frontend
|
||||
curl https://${FRONTEND_APP_NAME}.azurewebsites.net
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Backend logs
|
||||
az webapp log tail --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
|
||||
# Frontend logs
|
||||
az webapp log tail --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Step 11: Configure Database Schema
|
||||
|
||||
If using PostgreSQL, you need to initialize the database schema:
|
||||
|
||||
```bash
|
||||
# Connect to database and run schema initialization
|
||||
# Option 1: Using psql
|
||||
psql "postgresql://${DB_ADMIN_USER}:${DB_ADMIN_PASSWORD}@${DB_SERVER_NAME}.postgres.database.azure.com:5432/${DB_NAME}?sslmode=require"
|
||||
|
||||
# Option 2: Using Azure Cloud Shell or local script
|
||||
# The application will create tables automatically on first run
|
||||
# Or use the migration scripts in backend/scripts/
|
||||
```
|
||||
|
||||
**Note**: The application will automatically create the required database schema on first startup if it doesn't exist.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Step 12: Update Environment Variables (If Needed)
|
||||
|
||||
If you need to update any configuration:
|
||||
|
||||
```bash
|
||||
# Update backend settings
|
||||
az webapp config appsettings set \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--settings \
|
||||
NEW_SETTING=value
|
||||
|
||||
# Update frontend settings
|
||||
az webapp config appsettings set \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--settings \
|
||||
VITE_API_URL="https://${BACKEND_APP_NAME}.azurewebsites.net/api"
|
||||
|
||||
# Restart apps to apply changes
|
||||
az webapp restart --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
az webapp restart --name $FRONTEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Step 13: Set Up CI/CD with Automated Deployment
|
||||
|
||||
### Azure DevOps Pipeline Setup
|
||||
|
||||
The project includes an automated pipeline that builds, pushes, and deploys your application.
|
||||
|
||||
1. **Create Service Connections**:
|
||||
|
||||
**A) Docker Registry Connection (for building images)**:
|
||||
- Go to Azure DevOps → Project Settings → Service connections
|
||||
- Create new **Docker Registry** connection
|
||||
- Select **Azure Container Registry**
|
||||
- Choose your subscription and ACR
|
||||
- Name: `zuyderland-cmdb-acr-connection` (or match your variable)
|
||||
|
||||
**B) Azure Resource Manager Connection (for deployment)**:
|
||||
- Create new **Azure Resource Manager** connection
|
||||
- Select your subscription
|
||||
- Name: `zuyderland-cmdb-subscription` (or match your variable)
|
||||
|
||||
2. **Configure Pipeline Variables**:
|
||||
|
||||
Update `azure-pipelines.yml` with your values:
|
||||
```yaml
|
||||
variables:
|
||||
acrName: 'cmdbinsightacr' # Your ACR name
|
||||
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
|
||||
dockerRegistryServiceConnection: 'zuyderland-cmdb-acr-connection'
|
||||
```
|
||||
|
||||
3. **Create Environment**:
|
||||
- Go to **Pipelines** → **Environments**
|
||||
- Create environment: `production`
|
||||
- (Optional) Add approvals for manual deployment control
|
||||
|
||||
4. **Run Pipeline**:
|
||||
- Push to `main` branch → **Automatically builds AND deploys**
|
||||
- Pipeline will:
|
||||
- Build Docker images
|
||||
- Push to ACR
|
||||
- Deploy to App Services
|
||||
- Verify deployment
|
||||
|
||||
### Zero-Downtime Deployment (Optional)
|
||||
|
||||
For production with zero downtime, use deployment slots:
|
||||
|
||||
1. **Create Staging Slots**:
|
||||
```bash
|
||||
az webapp deployment slot create \
|
||||
--name $BACKEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--slot staging
|
||||
|
||||
az webapp deployment slot create \
|
||||
--name $FRONTEND_APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--slot staging
|
||||
```
|
||||
|
||||
2. **Use Advanced Pipeline**:
|
||||
- Use `azure-pipelines-slots.yml` instead
|
||||
- Deploys to staging first
|
||||
- Swaps to production after verification
|
||||
|
||||
**See `docs/AZURE-PIPELINE-DEPLOYMENT.md` for complete setup guide.**
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Troubleshooting
|
||||
|
||||
### App Service Won't Start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
az webapp log tail --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
|
||||
# Check container logs
|
||||
az webapp log show --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP
|
||||
|
||||
# Check app status
|
||||
az webapp show --name $BACKEND_APP_NAME --resource-group $RESOURCE_GROUP --query state
|
||||
```
|
||||
|
||||
### ACR Authentication Issues
|
||||
|
||||
```bash
|
||||
# Re-authenticate
|
||||
az acr login --name $ACR_NAME
|
||||
|
||||
# Check Managed Identity permissions
|
||||
az role assignment list --assignee $BACKEND_PRINCIPAL_ID --scope $ACR_ID
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
|
||||
```bash
|
||||
# Test database connection
|
||||
psql "postgresql://${DB_ADMIN_USER}:${DB_ADMIN_PASSWORD}@${DB_SERVER_NAME}.postgres.database.azure.com:5432/${DB_NAME}?sslmode=require"
|
||||
|
||||
# Check firewall rules
|
||||
az postgres flexible-server firewall-rule list \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--name $DB_SERVER_NAME
|
||||
```
|
||||
|
||||
### Key Vault Access Issues
|
||||
|
||||
```bash
|
||||
# Check Key Vault policies
|
||||
az keyvault show --name $KEY_VAULT_NAME --resource-group $RESOURCE_GROUP
|
||||
|
||||
# Verify Managed Identity has access
|
||||
az keyvault show-policy --name $KEY_VAULT_NAME
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Application Insights
|
||||
|
||||
1. Go to Azure Portal → Application Insights → Your app
|
||||
2. View:
|
||||
- **Live Metrics**: Real-time performance
|
||||
- **Application Map**: Service dependencies
|
||||
- **Logs**: Query application logs
|
||||
- **Metrics**: Performance metrics
|
||||
|
||||
### Set Up Alerts
|
||||
|
||||
```bash
|
||||
# Create alert for app downtime
|
||||
az monitor metrics alert create \
|
||||
--name "Backend-Down" \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--scopes "/subscriptions/<subscription-id>/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Web/sites/${BACKEND_APP_NAME}" \
|
||||
--condition "avg AvailabilityPercentage < 99" \
|
||||
--window-size 5m \
|
||||
--evaluation-frequency 1m
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💰 Cost Optimization
|
||||
|
||||
### Current Setup Costs
|
||||
|
||||
| Resource | SKU | Estimated Monthly Cost |
|
||||
|----------|-----|------------------------|
|
||||
| App Service Plan | B1 | €15-25 |
|
||||
| PostgreSQL | Standard_B1ms | €20-30 |
|
||||
| Container Registry | Basic | €5 |
|
||||
| Key Vault | Standard | €1-2 |
|
||||
| Application Insights | Basic | €0-5 (free tier) |
|
||||
| **Total** | | **€41-67/month** |
|
||||
|
||||
### Cost Saving Tips
|
||||
|
||||
1. **Use Basic tier ACR** for development (€5 vs €20)
|
||||
2. **Application Insights Basic** is free up to 5GB/month
|
||||
3. **Stop App Services** when not in use (dev/test environments)
|
||||
4. **Use SQLite** instead of PostgreSQL (saves €20-30/month, but less scalable)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Next Steps
|
||||
|
||||
1. **Configure DNS**: Point your domain to App Service
|
||||
2. **Set up SSL**: Configure HTTPS certificate
|
||||
3. **Test Application**: Verify all features work
|
||||
4. **Set up Monitoring**: Configure alerts
|
||||
5. **Document Access**: Share URLs and credentials with team
|
||||
6. **Backup Strategy**: Plan for database backups (if needed)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Useful Commands Reference
|
||||
|
||||
```bash
|
||||
# List all resources
|
||||
az resource list --resource-group $RESOURCE_GROUP --output table
|
||||
|
||||
# Get resource IDs
|
||||
az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP --query id
|
||||
az postgres flexible-server show --name $DB_SERVER_NAME --resource-group $RESOURCE_GROUP --query id
|
||||
|
||||
# Export resource configuration
|
||||
az group export --name $RESOURCE_GROUP --output-file resources.json
|
||||
|
||||
# Delete all resources (careful!)
|
||||
az group delete --name $RESOURCE_GROUP --yes --no-wait
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Additional Resources
|
||||
|
||||
- [Azure App Service Documentation](https://docs.microsoft.com/azure/app-service/)
|
||||
- [Azure Container Registry Documentation](https://docs.microsoft.com/azure/container-registry/)
|
||||
- [Azure Database for PostgreSQL Documentation](https://docs.microsoft.com/azure/postgresql/)
|
||||
- [Azure Key Vault Documentation](https://docs.microsoft.com/azure/key-vault/)
|
||||
- [Application Insights Documentation](https://docs.microsoft.com/azure/azure-monitor/app/app-insights-overview)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Deployment Checklist
|
||||
|
||||
- [ ] Resource Group created
|
||||
- [ ] Azure Container Registry created and accessible
|
||||
- [ ] PostgreSQL database created (or SQLite storage configured)
|
||||
- [ ] Key Vault created with all secrets
|
||||
- [ ] Application Insights created
|
||||
- [ ] App Service Plan created
|
||||
- [ ] Backend App Service created and configured
|
||||
- [ ] Frontend App Service created and configured
|
||||
- [ ] Docker images built and pushed to ACR
|
||||
- [ ] Apps started and running
|
||||
- [ ] Health checks passing
|
||||
- [ ] Custom domain configured (if applicable)
|
||||
- [ ] SSL certificate configured (if applicable)
|
||||
- [ ] Monitoring and alerts configured
|
||||
- [ ] Team access configured
|
||||
- [ ] Documentation updated
|
||||
|
||||
---
|
||||
|
||||
**🎉 Congratulations! Your CMDB Insight application is now deployed to Azure!**
|
||||
|
||||
For questions or issues, refer to:
|
||||
- `AZURE-APP-SERVICE-DEPLOYMENT.md` - Detailed App Service deployment guide
|
||||
- `AZURE-CONTAINER-REGISTRY.md` - ACR setup and usage
|
||||
- `PRODUCTION-DEPLOYMENT.md` - General production deployment guide
|
||||
337
docs/AZURE-PIPELINE-DEPLOYMENT.md
Normal file
337
docs/AZURE-PIPELINE-DEPLOYMENT.md
Normal 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.
|
||||
152
docs/AZURE-PIPELINE-QUICK-REFERENCE.md
Normal file
152
docs/AZURE-PIPELINE-QUICK-REFERENCE.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Azure Pipeline Quick Reference
|
||||
|
||||
Quick reference for configuring and using the automated deployment pipeline.
|
||||
|
||||
## 📋 Pipeline Variables
|
||||
|
||||
Update these in `azure-pipelines.yml`:
|
||||
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `acrName` | Azure Container Registry name | `cmdbinsightacr` |
|
||||
| `repositoryName` | Docker repository name | `cmdb-insight` |
|
||||
| `dockerRegistryServiceConnection` | ACR service connection name | `zuyderland-cmdb-acr-connection` |
|
||||
| `resourceGroup` | Azure resource group | `rg-cmdb-insight-prod` |
|
||||
| `backendAppName` | Backend App Service name | `cmdb-backend-prod` |
|
||||
| `frontendAppName` | Frontend App Service name | `cmdb-frontend-prod` |
|
||||
| `azureSubscription` | Azure service connection for deployment | `zuyderland-cmdb-subscription` |
|
||||
| `deployToProduction` | Enable/disable deployment | `true` or `false` |
|
||||
| `useDeploymentSlots` | Use staging slots for zero-downtime | `true` or `false` |
|
||||
|
||||
## 🔧 Required Service Connections
|
||||
|
||||
### 1. Docker Registry Connection
|
||||
|
||||
**Purpose**: Push Docker images to ACR
|
||||
|
||||
**Setup**:
|
||||
- Type: Docker Registry → Azure Container Registry
|
||||
- Name: Match `dockerRegistryServiceConnection` variable
|
||||
- Subscription: Your Azure subscription
|
||||
- Registry: Your ACR
|
||||
|
||||
### 2. Azure Resource Manager Connection
|
||||
|
||||
**Purpose**: Deploy to App Services
|
||||
|
||||
**Setup**:
|
||||
- Type: Azure Resource Manager
|
||||
- Name: Match `azureSubscription` variable
|
||||
- Subscription: Your Azure subscription
|
||||
- Authentication: Managed Identity (recommended) or Service Principal
|
||||
|
||||
## 🚀 Pipeline Stages
|
||||
|
||||
### 1. Build Stage
|
||||
- Builds backend Docker image
|
||||
- Builds frontend Docker image
|
||||
- Pushes both to ACR with tags: `$(Build.BuildId)` and `latest`
|
||||
|
||||
### 2. Deploy Stage
|
||||
- Deploys backend to App Service
|
||||
- Deploys frontend to App Service
|
||||
- Restarts both services
|
||||
- Verifies deployment
|
||||
|
||||
### 3. Verify Stage
|
||||
- Health check on backend (`/api/health`)
|
||||
- Accessibility check on frontend
|
||||
- Reports status
|
||||
|
||||
## 🎯 Triggers
|
||||
|
||||
**Automatic triggers:**
|
||||
- Push to `main` branch
|
||||
- Git tags starting with `v*` (e.g., `v1.0.0`)
|
||||
|
||||
**Manual trigger:**
|
||||
- Go to Pipelines → Your pipeline → Run pipeline
|
||||
|
||||
## 📝 Common Commands
|
||||
|
||||
### Check Pipeline Status
|
||||
```bash
|
||||
# View in Azure DevOps Portal
|
||||
# Or use Azure CLI (if configured)
|
||||
az pipelines runs list --organization <org> --project <project>
|
||||
```
|
||||
|
||||
### View Pipeline Logs
|
||||
- Go to Azure DevOps → Pipelines → Select run → View logs
|
||||
|
||||
### Cancel Running Pipeline
|
||||
- Go to Azure DevOps → Pipelines → Select run → Cancel
|
||||
|
||||
## 🔄 Deployment Flow
|
||||
|
||||
```
|
||||
Code Push → Build Images → Push to ACR → Deploy to App Services → Verify
|
||||
```
|
||||
|
||||
**With Slots:**
|
||||
```
|
||||
Code Push → Build Images → Push to ACR → Deploy to Staging → Swap to Production → Verify
|
||||
```
|
||||
|
||||
## ⚙️ Configuration Examples
|
||||
|
||||
### Basic Deployment (Current)
|
||||
```yaml
|
||||
deployToProduction: true
|
||||
useDeploymentSlots: false
|
||||
```
|
||||
→ Direct deployment to production
|
||||
|
||||
### Zero-Downtime Deployment
|
||||
```yaml
|
||||
deployToProduction: true
|
||||
useDeploymentSlots: true
|
||||
```
|
||||
→ Deploy to staging, then swap to production
|
||||
|
||||
### Build Only (No Deployment)
|
||||
```yaml
|
||||
deployToProduction: false
|
||||
```
|
||||
→ Only build and push images, don't deploy
|
||||
|
||||
## 🛠️ Troubleshooting
|
||||
|
||||
### Pipeline Fails: "Service connection not found"
|
||||
- Check service connection name matches variable
|
||||
- Verify connection exists in Project Settings
|
||||
|
||||
### Deployment Fails: "App Service not found"
|
||||
- Verify app names match your Azure resources
|
||||
- Check resource group name is correct
|
||||
|
||||
### Images Not Updating
|
||||
- Check ACR has new images
|
||||
- Verify App Service container settings
|
||||
- Check Managed Identity has ACR pull permissions
|
||||
|
||||
## 📚 Related Files
|
||||
|
||||
- **`azure-pipelines.yml`** - Main pipeline (basic deployment)
|
||||
- **`azure-pipelines-slots.yml`** - Advanced pipeline (with slots)
|
||||
- **`docs/AZURE-PIPELINE-DEPLOYMENT.md`** - Complete setup guide
|
||||
- **`docs/AZURE-NEW-SUBSCRIPTION-SETUP.md`** - Initial Azure setup
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
- [ ] Service connections created
|
||||
- [ ] Pipeline variables configured
|
||||
- [ ] Environment `production` created
|
||||
- [ ] App Services exist in Azure
|
||||
- [ ] Pipeline tested successfully
|
||||
- [ ] Deployment verified
|
||||
- [ ] Health checks passing
|
||||
|
||||
---
|
||||
|
||||
**Quick Start**: Update variables in `azure-pipelines.yml` and push to `main` branch!
|
||||
222
docs/AZURE-PIPELINES-USAGE.md
Normal file
222
docs/AZURE-PIPELINES-USAGE.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# Azure Pipelines Usage Guide
|
||||
|
||||
Guide for using the separate build and deployment pipelines.
|
||||
|
||||
## 📋 Pipeline Files
|
||||
|
||||
### 1. `azure-pipelines.yml` - Build and Push Images
|
||||
|
||||
**Purpose**: Builds Docker images and pushes them to Azure Container Registry.
|
||||
|
||||
**What it does:**
|
||||
- ✅ Builds backend Docker image
|
||||
- ✅ Builds frontend Docker image
|
||||
- ✅ Pushes both to ACR with tags: `$(Build.BuildId)` and `latest`
|
||||
|
||||
**When to use:**
|
||||
- First time setup (to test image building)
|
||||
- After code changes (to build new images)
|
||||
- Before deployment (to ensure images are in ACR)
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
variables:
|
||||
acrName: 'zdlas' # Your ACR name
|
||||
repositoryName: 'cmdb-insight'
|
||||
dockerRegistryServiceConnection: 'zuyderland-cmdb-acr-connection'
|
||||
```
|
||||
|
||||
### 2. `azure-pipelines-deploy.yml` - Deploy to App Service
|
||||
|
||||
**Purpose**: Deploys existing images from ACR to Azure App Services.
|
||||
|
||||
**What it does:**
|
||||
- ✅ Deploys backend container to App Service
|
||||
- ✅ Deploys frontend container to App Service
|
||||
- ✅ Restarts both App Services
|
||||
- ✅ Verifies deployment with health checks
|
||||
|
||||
**When to use:**
|
||||
- After images are built and pushed to ACR
|
||||
- When you want to deploy/update the application
|
||||
- For production deployments
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
variables:
|
||||
acrName: 'zdlas' # Your ACR name
|
||||
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
|
||||
imageTag: 'latest' # Image tag to deploy
|
||||
```
|
||||
|
||||
## 🚀 Workflow
|
||||
|
||||
### Step 1: Build and Push Images
|
||||
|
||||
1. **Configure `azure-pipelines.yml`**:
|
||||
- Update `acrName` with your ACR name
|
||||
- Update `dockerRegistryServiceConnection` with your service connection name
|
||||
|
||||
2. **Create Pipeline in Azure DevOps**:
|
||||
- Go to **Pipelines** → **New pipeline**
|
||||
- Select **Existing Azure Pipelines YAML file**
|
||||
- Choose `azure-pipelines.yml`
|
||||
- Run the pipeline
|
||||
|
||||
3. **Verify Images in ACR**:
|
||||
```bash
|
||||
az acr repository list --name zdlas
|
||||
az acr repository show-tags --name zdlas --repository cmdb-insight/backend
|
||||
az acr repository show-tags --name zdlas --repository cmdb-insight/frontend
|
||||
```
|
||||
|
||||
### Step 2: Deploy Application
|
||||
|
||||
1. **Ensure App Services exist**:
|
||||
- Backend App Service: `cmdb-backend-prod`
|
||||
- Frontend App Service: `cmdb-frontend-prod`
|
||||
- See `AZURE-NEW-SUBSCRIPTION-SETUP.md` for setup instructions
|
||||
|
||||
2. **Configure `azure-pipelines-deploy.yml`**:
|
||||
- Update all variables with your Azure resource names
|
||||
- Create Azure service connection for App Service deployment
|
||||
- Create `production` environment in Azure DevOps
|
||||
|
||||
3. **Create Deployment Pipeline**:
|
||||
- Go to **Pipelines** → **New pipeline**
|
||||
- Select **Existing Azure Pipelines YAML file**
|
||||
- Choose `azure-pipelines-deploy.yml`
|
||||
- Run the pipeline
|
||||
|
||||
4. **Verify Deployment**:
|
||||
- Check backend: `https://cmdb-backend-prod.azurewebsites.net/api/health`
|
||||
- Check frontend: `https://cmdb-frontend-prod.azurewebsites.net`
|
||||
|
||||
## 🔧 Setup Requirements
|
||||
|
||||
### For Build Pipeline (`azure-pipelines.yml`)
|
||||
|
||||
**Required:**
|
||||
- ✅ Docker Registry service connection (for ACR)
|
||||
- ✅ ACR exists and is accessible
|
||||
- ✅ Service connection has push permissions
|
||||
|
||||
**Setup:**
|
||||
1. Create Docker Registry service connection:
|
||||
- **Project Settings** → **Service connections** → **New service connection**
|
||||
- Choose **Docker Registry** → **Azure Container Registry**
|
||||
- Select your ACR
|
||||
- Name: `zuyderland-cmdb-acr-connection`
|
||||
|
||||
### For Deployment Pipeline (`azure-pipelines-deploy.yml`)
|
||||
|
||||
**Required:**
|
||||
- ✅ Azure Resource Manager service connection
|
||||
- ✅ App Services exist in Azure
|
||||
- ✅ `production` environment created in Azure DevOps
|
||||
- ✅ Images exist in ACR
|
||||
|
||||
**Setup:**
|
||||
1. Create Azure service connection:
|
||||
- **Project Settings** → **Service connections** → **New service connection**
|
||||
- Choose **Azure Resource Manager**
|
||||
- Select your subscription
|
||||
- Name: `zuyderland-cmdb-subscription`
|
||||
|
||||
2. Create environment:
|
||||
- **Pipelines** → **Environments** → **Create environment**
|
||||
- Name: `production`
|
||||
- (Optional) Add approvals for manual control
|
||||
|
||||
## 📝 Typical Usage Scenarios
|
||||
|
||||
### Scenario 1: First Time Setup
|
||||
|
||||
```bash
|
||||
# 1. Build and push images
|
||||
# Run azure-pipelines.yml → Images in ACR
|
||||
|
||||
# 2. Create App Services (manual or via script)
|
||||
# See AZURE-NEW-SUBSCRIPTION-SETUP.md
|
||||
|
||||
# 3. Deploy application
|
||||
# Run azure-pipelines-deploy.yml → App deployed
|
||||
```
|
||||
|
||||
### Scenario 2: Code Update
|
||||
|
||||
```bash
|
||||
# 1. Push code to main branch
|
||||
git push origin main
|
||||
|
||||
# 2. Build pipeline runs automatically
|
||||
# azure-pipelines.yml → New images in ACR
|
||||
|
||||
# 3. Deploy new version
|
||||
# Run azure-pipelines-deploy.yml → App updated
|
||||
```
|
||||
|
||||
### Scenario 3: Deploy Specific Version
|
||||
|
||||
```bash
|
||||
# 1. Update azure-pipelines-deploy.yml
|
||||
imageTag: 'v1.0.0' # Or specific build ID
|
||||
|
||||
# 2. Run deployment pipeline
|
||||
# Deploys specific version
|
||||
```
|
||||
|
||||
## 🔄 Combining Pipelines (Future)
|
||||
|
||||
Once you're comfortable with both pipelines, you can:
|
||||
|
||||
1. **Combine them** into one pipeline with conditional deployment
|
||||
2. **Use deployment slots** for zero-downtime updates
|
||||
3. **Add approval gates** for production deployments
|
||||
|
||||
See `azure-pipelines-slots.yml` for an advanced example with deployment slots.
|
||||
|
||||
## 🛠️ Troubleshooting
|
||||
|
||||
### Build Pipeline Fails
|
||||
|
||||
**Issue**: "Service connection not found"
|
||||
- **Solution**: Verify service connection name matches `dockerRegistryServiceConnection` variable
|
||||
|
||||
**Issue**: "ACR not found"
|
||||
- **Solution**: Check `acrName` variable matches your ACR name
|
||||
|
||||
### Deployment Pipeline Fails
|
||||
|
||||
**Issue**: "App Service not found"
|
||||
- **Solution**: Verify app names match your Azure resources
|
||||
|
||||
**Issue**: "Environment not found"
|
||||
- **Solution**: Create `production` environment in Azure DevOps
|
||||
|
||||
**Issue**: "Image not found in ACR"
|
||||
- **Solution**: Run build pipeline first to push images to ACR
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
### Build Pipeline Setup
|
||||
- [ ] Docker Registry service connection created
|
||||
- [ ] `azure-pipelines.yml` variables configured
|
||||
- [ ] Pipeline created in Azure DevOps
|
||||
- [ ] Test run successful
|
||||
- [ ] Images visible in ACR
|
||||
|
||||
### Deployment Pipeline Setup
|
||||
- [ ] Azure Resource Manager service connection created
|
||||
- [ ] `production` environment created
|
||||
- [ ] App Services exist in Azure
|
||||
- [ ] `azure-pipelines-deploy.yml` variables configured
|
||||
- [ ] Deployment pipeline created in Azure DevOps
|
||||
- [ ] Test deployment successful
|
||||
|
||||
---
|
||||
|
||||
**Workflow**: Build first → Deploy second → Verify success!
|
||||
242
docs/AZURE-RESOURCES-OVERVIEW.md
Normal file
242
docs/AZURE-RESOURCES-OVERVIEW.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Azure Resources Overview
|
||||
|
||||
Quick reference of all Azure resources needed for CMDB Insight deployment.
|
||||
|
||||
## 📋 Resources Summary
|
||||
|
||||
| Resource Type | Resource Name | Purpose | SKU/Tier | Estimated Cost | Shared? |
|
||||
|--------------|---------------|---------|----------|----------------|--------|
|
||||
| **Resource Group** | `rg-cmdb-insight-prod` | Container for all resources | - | Free | No |
|
||||
| **Container Registry** | `yourcompanyacr` | Store Docker images (can be shared) | Basic/Standard | €5-20/month | ✅ Yes |
|
||||
| **PostgreSQL Database** | `cmdb-postgres-prod` | Production database | Standard_B1ms | €20-30/month | No |
|
||||
| **Key Vault** | `kv-cmdb-insight-prod` | Store secrets securely | Standard | €1-2/month | No |
|
||||
| **App Service Plan** | `plan-cmdb-insight-prod` | Hosting plan | B1 | €15-25/month | No |
|
||||
| **App Service (Backend)** | `cmdb-backend-prod` | Backend API | - | Included in plan | No |
|
||||
| **App Service (Frontend)** | `cmdb-frontend-prod` | Frontend web app | - | Included in plan | No |
|
||||
| **Application Insights** | `appi-cmdb-insight-prod` | Monitoring & logging | Basic | €0-5/month | No |
|
||||
|
||||
**Total Estimated Cost: €41-82/month** (depending on ACR tier and usage)
|
||||
|
||||
**💡 Note**: Container Registry can be **shared across multiple applications**. The repository name (`cmdb-insight`) separates this app from others. If you already have an ACR, reuse it to save costs!
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Resource Dependencies
|
||||
|
||||
```
|
||||
Resource Group (App-specific)
|
||||
├── PostgreSQL Database
|
||||
│ └── Stores: Application data
|
||||
├── Key Vault
|
||||
│ └── Stores: Secrets (JIRA tokens, passwords, etc.)
|
||||
├── Application Insights
|
||||
│ └── Monitors: Backend & Frontend apps
|
||||
└── App Service Plan
|
||||
├── Backend App Service
|
||||
│ ├── Pulls from: Shared ACR (cmdb-insight/backend:latest)
|
||||
│ ├── Connects to: PostgreSQL
|
||||
│ ├── Reads from: Key Vault
|
||||
│ └── Sends logs to: Application Insights
|
||||
└── Frontend App Service
|
||||
├── Pulls from: Shared ACR (cmdb-insight/frontend:latest)
|
||||
└── Connects to: Backend App Service
|
||||
|
||||
Shared Resources (can be in separate resource group)
|
||||
└── Container Registry (ACR) ← Shared across multiple applications
|
||||
├── cmdb-insight/ ← This application
|
||||
│ ├── backend:latest
|
||||
│ └── frontend:latest
|
||||
├── other-app/ ← Other applications
|
||||
│ └── api:latest
|
||||
└── shared-services/ ← Shared images
|
||||
└── nginx:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Endpoints
|
||||
|
||||
After deployment, your application will be available at:
|
||||
|
||||
- **Frontend**: `https://cmdb-frontend-prod.azurewebsites.net`
|
||||
- **Backend API**: `https://cmdb-backend-prod.azurewebsites.net/api`
|
||||
- **Health Check**: `https://cmdb-backend-prod.azurewebsites.net/api/health`
|
||||
|
||||
If custom domain is configured:
|
||||
- **Frontend**: `https://cmdb.yourcompany.com`
|
||||
- **Backend API**: `https://api.cmdb.yourcompany.com` (or subdomain of your choice)
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Required Secrets
|
||||
|
||||
These secrets should be stored in Azure Key Vault:
|
||||
|
||||
| Secret Name | Description | Example |
|
||||
|-------------|-------------|---------|
|
||||
| `JiraPat` | Jira Personal Access Token (if using PAT auth) | `ATATT3xFfGF0...` |
|
||||
| `SessionSecret` | Session encryption secret | `a1b2c3d4e5f6...` (32+ chars) |
|
||||
| `JiraOAuthClientId` | Jira OAuth Client ID | `OAuthClientId123` |
|
||||
| `JiraOAuthClientSecret` | Jira OAuth Client Secret | `OAuthSecret456` |
|
||||
| `JiraSchemaId` | Jira Assets Schema ID | `schema-123` |
|
||||
| `DatabasePassword` | PostgreSQL admin password | `SecurePassword123!` |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Resource Sizing Recommendations
|
||||
|
||||
### For 20 Users (Current)
|
||||
|
||||
| Resource | Recommended SKU | Alternative |
|
||||
|----------|----------------|-------------|
|
||||
| App Service Plan | B1 (1 vCore, 1.75GB RAM) | B2 if experiencing slowness |
|
||||
| PostgreSQL | Standard_B1ms (1 vCore, 2GB RAM) | Standard_B2s for growth |
|
||||
| Container Registry | Basic (10GB) | Standard for production |
|
||||
| Key Vault | Standard | Standard (only option) |
|
||||
|
||||
### For 50+ Users (Future Growth)
|
||||
|
||||
| Resource | Recommended SKU | Notes |
|
||||
|----------|----------------|-------|
|
||||
| App Service Plan | B2 or S1 | Better performance |
|
||||
| PostgreSQL | Standard_B2s (2 vCores, 4GB RAM) | More concurrent connections |
|
||||
| Container Registry | Standard (100GB) | More storage, geo-replication |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Update/Deployment Flow
|
||||
|
||||
1. **Code Changes** → Push to repository
|
||||
2. **CI/CD Pipeline** → Builds Docker images
|
||||
3. **Push to ACR** → Images stored in Container Registry
|
||||
4. **Restart App Services** → Pulls new images from ACR
|
||||
5. **Application Updates** → New version live
|
||||
|
||||
### Manual Deployment
|
||||
|
||||
```bash
|
||||
# Restart apps to pull latest images
|
||||
az webapp restart --name cmdb-backend-prod --resource-group rg-cmdb-insight-prod
|
||||
az webapp restart --name cmdb-frontend-prod --resource-group rg-cmdb-insight-prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Security Configuration
|
||||
|
||||
### Network Security
|
||||
|
||||
- **HTTPS Only**: Enabled on both App Services
|
||||
- **Database Firewall**: Restricted to Azure services (can be further restricted)
|
||||
- **Key Vault Access**: Managed Identity only (no shared keys)
|
||||
|
||||
### Authentication
|
||||
|
||||
- **App Services**: Managed Identity for ACR and Key Vault access
|
||||
- **Database**: Username/password (stored in Key Vault)
|
||||
- **Application**: Jira OAuth 2.0 or Personal Access Token
|
||||
|
||||
---
|
||||
|
||||
## 📈 Monitoring & Logging
|
||||
|
||||
### Application Insights
|
||||
|
||||
- **Metrics**: Response times, request rates, errors
|
||||
- **Logs**: Application logs, exceptions, traces
|
||||
- **Alerts**: Configured for downtime, errors, performance issues
|
||||
|
||||
### Access Logs
|
||||
|
||||
```bash
|
||||
# Backend logs
|
||||
az webapp log tail --name cmdb-backend-prod --resource-group rg-cmdb-insight-prod
|
||||
|
||||
# Frontend logs
|
||||
az webapp log tail --name cmdb-frontend-prod --resource-group rg-cmdb-insight-prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration Files
|
||||
|
||||
### Environment Variables (Backend)
|
||||
|
||||
- `NODE_ENV=production`
|
||||
- `PORT=3001`
|
||||
- `DATABASE_TYPE=postgres`
|
||||
- `DATABASE_URL` (from Key Vault)
|
||||
- `JIRA_HOST=https://jira.zuyderland.nl`
|
||||
- `JIRA_AUTH_METHOD=oauth`
|
||||
- `JIRA_OAUTH_CLIENT_ID` (from Key Vault)
|
||||
- `JIRA_OAUTH_CLIENT_SECRET` (from Key Vault)
|
||||
- `JIRA_OAUTH_CALLBACK_URL`
|
||||
- `JIRA_SCHEMA_ID` (from Key Vault)
|
||||
- `SESSION_SECRET` (from Key Vault)
|
||||
- `FRONTEND_URL`
|
||||
- `APPINSIGHTS_INSTRUMENTATIONKEY`
|
||||
|
||||
### Environment Variables (Frontend)
|
||||
|
||||
- `VITE_API_URL` (points to backend API)
|
||||
|
||||
---
|
||||
|
||||
## 🗑️ Cleanup (If Needed)
|
||||
|
||||
To delete all resources:
|
||||
|
||||
```bash
|
||||
# Delete entire resource group (deletes all resources)
|
||||
az group delete --name rg-cmdb-insight-prod --yes --no-wait
|
||||
|
||||
# Or delete individual resources
|
||||
az acr delete --name cmdbinsightacr --resource-group rg-cmdb-insight-prod
|
||||
az postgres flexible-server delete --name cmdb-postgres-prod --resource-group rg-cmdb-insight-prod
|
||||
az keyvault delete --name kv-cmdb-insight-prod --resource-group rg-cmdb-insight-prod
|
||||
az appservice plan delete --name plan-cmdb-insight-prod --resource-group rg-cmdb-insight-prod
|
||||
```
|
||||
|
||||
**⚠️ Warning**: This will permanently delete all resources and data. Make sure you have backups if needed.
|
||||
|
||||
---
|
||||
|
||||
## 📞 Quick Commands Reference
|
||||
|
||||
```bash
|
||||
# Set variables
|
||||
RESOURCE_GROUP="rg-cmdb-insight-prod"
|
||||
BACKEND_APP="cmdb-backend-prod"
|
||||
FRONTEND_APP="cmdb-frontend-prod"
|
||||
|
||||
# Check app status
|
||||
az webapp show --name $BACKEND_APP --resource-group $RESOURCE_GROUP --query state
|
||||
|
||||
# View logs
|
||||
az webapp log tail --name $BACKEND_APP --resource-group $RESOURCE_GROUP
|
||||
|
||||
# Restart apps
|
||||
az webapp restart --name $BACKEND_APP --resource-group $RESOURCE_GROUP
|
||||
az webapp restart --name $FRONTEND_APP --resource-group $RESOURCE_GROUP
|
||||
|
||||
# List all resources
|
||||
az resource list --resource-group $RESOURCE_GROUP --output table
|
||||
|
||||
# Get app URLs
|
||||
echo "Frontend: https://${FRONTEND_APP}.azurewebsites.net"
|
||||
echo "Backend: https://${BACKEND_APP}.azurewebsites.net/api"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Related Documentation
|
||||
|
||||
- **`AZURE-NEW-SUBSCRIPTION-SETUP.md`** - Complete step-by-step setup guide
|
||||
- **`AZURE-APP-SERVICE-DEPLOYMENT.md`** - Detailed App Service deployment
|
||||
- **`AZURE-CONTAINER-REGISTRY.md`** - ACR setup and usage
|
||||
- **`AZURE-QUICK-REFERENCE.md`** - Quick reference guide
|
||||
- **`PRODUCTION-DEPLOYMENT.md`** - General production deployment
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-21
|
||||
Reference in New Issue
Block a user