Files
cmdb-insight/docs/DEPLOYMENT-ADVICE.md
Bert Hausmans f3637b85e1 Add comprehensive deployment advice and App Service deployment guide
- Add DEPLOYMENT-ADVICE.md with detailed analysis and recommendations
- Add AZURE-APP-SERVICE-DEPLOYMENT.md with step-by-step instructions
- Include NEN 7510 compliance considerations
- Include VPN/private network options for future
- Include monitoring and Elastic stack integration guidance
2026-01-14 18:09:42 +01:00

18 KiB

Deployment Advies - Zuyderland CMDB GUI 🎯

Datum: {{ vandaag }}
Aanbeveling: Azure App Service (Basic Tier)
Geschatte kosten: ~€20-25/maand


📊 Analyse van Jouw Situatie

Jouw Requirements:

  • Managed service (geen serverbeheer) - Jouw voorkeur
  • Interne productie (niet bedrijfskritisch)
  • 20 gebruikers (kleine team)
  • Downtime acceptabel (kan zelfs 's avonds/weekend uit)
  • Budget geen probleem (~€20-25/maand is prima)
  • Monitoring via Elastic stack (kan geïntegreerd worden)
  • NEN 7510 compliance (vereist)
  • Updates: Initieel dagelijks, daarna wekelijks/maandelijks

Waarom Azure App Service Perfect Past:

  1. Managed Service

    • Geen serverbeheer, SSH, Linux configuratie
    • Azure beheert alles (updates, security patches, scaling)
    • Perfect voor jouw voorkeur: "liever niet als het niet hoeft"
  2. Eenvoudig & Snel

    • Setup in ~15 minuten
    • Automatische SSL/TLS certificaten
    • Integratie met Azure DevOps (je pipeline werkt al!)
  3. Kosten-Effectief

    • Basic B1 plan: ~€15-25/maand
    • Voldoende voor 20 gebruikers
    • Geen verborgen kosten
  4. Flexibel

    • Deployment slots voor testen (staging → productie)
    • Eenvoudige rollback
    • Integratie met Azure Key Vault voor secrets
  5. Monitoring & Compliance

    • Integratie met Azure Monitor → kan naar Elastic stack
    • Logging en audit trails (NEN 7510 compliance)
    • Health checks ingebouwd

🚀 Aanbevolen Architectuur

┌─────────────────────────────────────────┐
│     Azure App Service Plan (B1)        │
│                                         │
│  ┌──────────────┐  ┌──────────────┐    │
│  │   Frontend   │  │   Backend    │    │
│  │  Web App     │  │  Web App     │    │
│  │  (Container) │  │  (Container) │    │
│  └──────────────┘  └──────┬───────┘    │
└──────────────────────────┼─────────────┘
                           │
            ┌──────────────┼──────────────┐
            │              │              │
    ┌───────▼──────┐ ┌─────▼──────┐ ┌────▼─────┐
    │ Azure Key    │ │ Azure      │ │ Elastic  │
    │ Vault        │ │ Monitor    │ │ Stack    │
    │ (Secrets)    │ │ (Logs)     │ │ (Export) │
    └──────────────┘ └────────────┘ └──────────┘

Componenten:

  • App Service Plan B1: 1 vCPU, 1.75GB RAM (voldoende voor 20 gebruikers)
  • 2 Web Apps: Frontend + Backend (delen dezelfde plan = kostenbesparend)
  • Azure Key Vault: Voor secrets (Jira credentials, session secrets)
  • Azure Monitor: Logging → kan geëxporteerd worden naar Elastic stack
  • Azure Storage: Voor SQLite database (als je SQLite blijft gebruiken)

Kosten Breakdown:

  • App Service Plan B1: ~€15-20/maand
  • Azure Key Vault: ~€1-2/maand
  • Azure Storage (SQLite): ~€1-2/maand
  • Totaal: ~€17-24/maand

📋 Stap-voor-Stap Deployment Plan

Fase 1: Basis Setup (15 minuten)

Stap 1.1: Resource Group Aanmaken

az group create \
  --name rg-cmdb-gui-prod \
  --location westeurope

Stap 1.2: App Service Plan Aanmaken

az appservice plan create \
  --name plan-cmdb-gui-prod \
  --resource-group rg-cmdb-gui-prod \
  --sku B1 \
  --is-linux

Waarom B1?

  • 1 vCPU, 1.75GB RAM
  • Voldoende voor 20 gebruikers
  • Goede prijs/prestatie verhouding

Stap 1.3: Web Apps Aanmaken

# Backend Web App
az webapp create \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --plan plan-cmdb-gui-prod \
  --deployment-container-image-name zdlas.azurecr.io/zuyderland-cmdb-gui/backend:latest

# Frontend Web App
az webapp create \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --plan plan-cmdb-gui-prod \
  --deployment-container-image-name zdlas.azurecr.io/zuyderland-cmdb-gui/frontend:latest

Fase 2: ACR Authentication (5 minuten)

Stap 2.1: Enable Managed Identity

# Backend
az webapp identity assign \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod

# Frontend
az webapp identity assign \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod

Stap 2.2: Grant ACR Pull Permissions

# Get managed identity principal ID
BACKEND_PRINCIPAL_ID=$(az webapp identity show \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --query principalId -o tsv)

FRONTEND_PRINCIPAL_ID=$(az webapp identity show \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --query principalId -o tsv)

# Get ACR resource ID
ACR_ID=$(az acr show \
  --name zdlas \
  --resource-group <acr-resource-group> \
  --query id -o tsv)

# Grant AcrPull role
az role assignment create \
  --assignee $BACKEND_PRINCIPAL_ID \
  --role AcrPull \
  --scope $ACR_ID

az role assignment create \
  --assignee $FRONTEND_PRINCIPAL_ID \
  --role AcrPull \
  --scope $ACR_ID

Stap 2.3: Configure Container Settings

# Backend
az webapp config container set \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --docker-custom-image-name zdlas.azurecr.io/zuyderland-cmdb-gui/backend:latest \
  --docker-registry-server-url https://zdlas.azurecr.io

# Frontend
az webapp config container set \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --docker-custom-image-name zdlas.azurecr.io/zuyderland-cmdb-gui/frontend:latest \
  --docker-registry-server-url https://zdlas.azurecr.io

Fase 3: Environment Variabelen (10 minuten)

Stap 3.1: Azure Key Vault Aanmaken

az keyvault create \
  --name kv-cmdb-gui-prod \
  --resource-group rg-cmdb-gui-prod \
  --location westeurope \
  --sku standard

Stap 3.2: Secrets Toevoegen aan Key Vault

# Jira Personal Access Token (of OAuth credentials)
az keyvault secret set \
  --vault-name kv-cmdb-gui-prod \
  --name JiraPat \
  --value "your-jira-pat-token"

# Session Secret
az keyvault secret set \
  --vault-name kv-cmdb-gui-prod \
  --name SessionSecret \
  --value "$(openssl rand -hex 32)"

# Jira Schema ID
az keyvault secret set \
  --vault-name kv-cmdb-gui-prod \
  --name JiraSchemaId \
  --value "your-schema-id"

# Anthropic API Key (optioneel)
az keyvault secret set \
  --vault-name kv-cmdb-gui-prod \
  --name AnthropicApiKey \
  --value "your-anthropic-key"

Stap 3.3: Grant Web Apps Access tot Key Vault

# Backend
az keyvault set-policy \
  --name kv-cmdb-gui-prod \
  --object-id $BACKEND_PRINCIPAL_ID \
  --secret-permissions get list

# Frontend (als nodig)
az keyvault set-policy \
  --name kv-cmdb-gui-prod \
  --object-id $FRONTEND_PRINCIPAL_ID \
  --secret-permissions get list

Stap 3.4: Configure App Settings met Key Vault References

# Backend App Settings
az webapp config appsettings set \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --settings \
    NODE_ENV=production \
    PORT=3001 \
    JIRA_BASE_URL=https://jira.zuyderland.nl \
    JIRA_SCHEMA_ID="@Microsoft.KeyVault(SecretUri=https://kv-cmdb-gui-prod.vault.azure.net/secrets/JiraSchemaId/)" \
    JIRA_PAT="@Microsoft.KeyVault(SecretUri=https://kv-cmdb-gui-prod.vault.azure.net/secrets/JiraPat/)" \
    SESSION_SECRET="@Microsoft.KeyVault(SecretUri=https://kv-cmdb-gui-prod.vault.azure.net/secrets/SessionSecret/)" \
    ANTHROPIC_API_KEY="@Microsoft.KeyVault(SecretUri=https://kv-cmdb-gui-prod.vault.azure.net/secrets/AnthropicApiKey/)" \
    FRONTEND_URL=https://cmdb-frontend-prod.azurewebsites.net

# Frontend App Settings
az webapp config appsettings set \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --settings \
    VITE_API_URL=https://cmdb-backend-prod.azurewebsites.net/api

Fase 4: SSL/TLS & Domain (10 minuten)

Stap 4.1: Gratis SSL via App Service

App Service heeft automatisch SSL voor *.azurewebsites.net:

  • Frontend: https://cmdb-frontend-prod.azurewebsites.net
  • Backend: https://cmdb-backend-prod.azurewebsites.net

Geen configuratie nodig! SSL werkt automatisch.

Stap 4.2: Custom Domain (Optioneel - Later)

Als je later een custom domain wilt (bijv. cmdb.zuyderland.nl):

# Add custom domain
az webapp config hostname add \
  --webapp-name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --hostname cmdb.zuyderland.nl

# Bind SSL certificate (App Service Certificate of Let's Encrypt)
az webapp config ssl bind \
  --name cmdb-frontend-prod \
  --resource-group rg-cmdb-gui-prod \
  --certificate-thumbprint <thumbprint> \
  --ssl-type SNI

Fase 5: Monitoring & Logging (15 minuten)

Stap 5.1: Enable Application Insights

# Create Application Insights
az monitor app-insights component create \
  --app cmdb-gui-prod \
  --location westeurope \
  --resource-group rg-cmdb-gui-prod \
  --application-type web

# Get Instrumentation Key
INSTRUMENTATION_KEY=$(az monitor app-insights component show \
  --app cmdb-gui-prod \
  --resource-group rg-cmdb-gui-prod \
  --query instrumentationKey -o tsv)

# Configure App Settings
az webapp config appsettings set \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --settings \
    APPINSIGHTS_INSTRUMENTATIONKEY=$INSTRUMENTATION_KEY \
    APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=$INSTRUMENTATION_KEY"

Stap 5.2: Export naar Elastic Stack (Later)

Azure Monitor kan geëxporteerd worden naar Elastic stack via:

  • Azure Monitor → Log Analytics Workspace → Export naar Elastic
  • Of gebruik Azure Function om logs te streamen naar Elastic

Zie: docs/ELASTIC-STACK-INTEGRATION.md (te maken als nodig)


Fase 6: Test & Start (5 minuten)

Stap 6.1: Start Web Apps

az webapp start --name cmdb-backend-prod --resource-group rg-cmdb-gui-prod
az webapp start --name cmdb-frontend-prod --resource-group rg-cmdb-gui-prod

Stap 6.2: Test Health Endpoints

# Backend health check
curl https://cmdb-backend-prod.azurewebsites.net/api/health

# Frontend
curl https://cmdb-frontend-prod.azurewebsites.net

Stap 6.3: Check Logs

# Backend logs
az webapp log tail --name cmdb-backend-prod --resource-group rg-cmdb-gui-prod

# Frontend logs
az webapp log tail --name cmdb-frontend-prod --resource-group rg-cmdb-gui-prod

🔒 NEN 7510 Compliance

Wat App Service Biedt:

  1. Encryption

    • Data at rest: Azure Storage encryption
    • Data in transit: TLS 1.2+ (automatisch)
    • Secrets: Azure Key Vault (encrypted)
  2. Access Control

    • Azure AD integratie (RBAC)
    • Managed Identity (geen credentials in code)
    • Network isolation (optioneel via VNet integration)
  3. Logging & Audit

    • Application Insights (alle API calls)
    • Azure Monitor (resource logs)
    • Activity Logs (wie deed wat)
    • Export naar Elastic stack mogelijk
  4. Backup & Recovery

    • App Service backups (optioneel)
    • Key Vault soft delete (recovery)
    • ⚠️ Opmerking: Jouw data wordt gesynchroniseerd vanuit Jira, dus backup is minder kritisch

Compliance Checklist:

  • Secrets in Azure Key Vault (niet in code)
  • HTTPS only (automatisch via App Service)
  • Logging ingeschakeld (Application Insights)
  • Access control (Azure AD RBAC)
  • Audit trail (Activity Logs)
  • Encryption at rest (Azure Storage)
  • Encryption in transit (TLS 1.2+)

Zie: docs/NEN-7510-COMPLIANCE.md (te maken als nodig)


🔐 VPN/Private Network Opties (Voor Later)

Optie 1: App Service VNet Integration

Wat het doet:

  • Web App verbindt met Azure Virtual Network
  • Toegang tot resources in VNet (bijv. database, andere services)
  • Niet: Maakt de app niet privé (app blijft publiek bereikbaar)

Wanneer gebruiken:

  • Als je een database in VNet hebt
  • Als je andere Azure services in VNet moet bereiken

Setup:

# Create VNet (als nog niet bestaat)
az network vnet create \
  --name vnet-cmdb-gui \
  --resource-group rg-cmdb-gui-prod \
  --address-prefix 10.0.0.0/16

# Create subnet
az network vnet subnet create \
  --name subnet-app-service \
  --resource-group rg-cmdb-gui-prod \
  --vnet-name vnet-cmdb-gui \
  --address-prefix 10.0.1.0/24

# Integrate Web App with VNet
az webapp vnet-integration add \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --vnet vnet-cmdb-gui \
  --subnet subnet-app-service

Optie 2: Private Endpoint (Maakt App Privé)

Wat het doet:

  • Maakt de Web App alleen bereikbaar via private IP
  • Vereist VPN/ExpressRoute om toegang te krijgen
  • Kosten: ~€7-10/maand per Private Endpoint

Wanneer gebruiken:

  • Als je de app alleen via VPN wilt bereiken
  • Als je geen publieke toegang wilt

Setup:

# Create Private Endpoint
az network private-endpoint create \
  --name pe-cmdb-backend \
  --resource-group rg-cmdb-gui-prod \
  --vnet-name vnet-cmdb-gui \
  --subnet subnet-private-endpoint \
  --private-connection-resource-id /subscriptions/<sub-id>/resourceGroups/rg-cmdb-gui-prod/providers/Microsoft.Web/sites/cmdb-backend-prod \
  --group-id sites \
  --connection-name pe-connection-backend

Optie 3: App Service Environment (ASE) - Enterprise

Wat het doet:

  • Volledig geïsoleerde App Service omgeving
  • Alleen bereikbaar via VNet
  • Kosten: ~€1000+/maand (te duur voor jouw use case)

Niet aanbevolen voor jouw situatie (te duur, overkill).


🔄 Updates Deployen

Automatische Deployment (Via Pipeline)

Je Azure DevOps pipeline bouwt al automatisch images. Voor automatische deployment:

Optie A: Continuous Deployment (Aanbevolen)

# Enable continuous deployment
az webapp deployment container config \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --enable-cd true

# Configure deployment slot (staging)
az webapp deployment slot create \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --slot staging

# Swap staging → production (zero-downtime)
az webapp deployment slot swap \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --slot staging \
  --target-slot production

Optie B: Manual Deployment (Eenvoudig)

# Pull nieuwe image en restart
az webapp restart --name cmdb-backend-prod --resource-group rg-cmdb-gui-prod
az webapp restart --name cmdb-frontend-prod --resource-group rg-cmdb-gui-prod

Workflow:

  1. Push code naar main branch
  2. Pipeline bouwt nieuwe images → zdlas.azurecr.io/.../backend:88767
  3. Images worden getagged als latest
  4. Restart Web Apps → pull nieuwe latest image

📊 Monitoring Setup

Azure Monitor → Elastic Stack Export

Optie 1: Log Analytics Workspace Export

# Create Log Analytics Workspace
az monitor log-analytics workspace create \
  --workspace-name law-cmdb-gui-prod \
  --resource-group rg-cmdb-gui-prod \
  --location westeurope

# Configure App Service to send logs
az webapp log config \
  --name cmdb-backend-prod \
  --resource-group rg-cmdb-gui-prod \
  --application-logging filesystem \
  --detailed-error-messages true \
  --failed-request-tracing true \
  --web-server-logging filesystem

# Export to Elastic (via Azure Function of Event Hub)
# Zie: docs/ELASTIC-STACK-INTEGRATION.md

Optie 2: Application Insights → Elastic

Application Insights kan geëxporteerd worden via:

  • Continuous Export (deprecated, maar werkt nog)
  • Azure Function die Application Insights API gebruikt
  • Log Analytics Workspace → Export naar Elastic

Deployment Checklist

Pre-Deployment:

  • Resource Group aangemaakt
  • App Service Plan aangemaakt (B1)
  • Web Apps aangemaakt (backend + frontend)
  • ACR authentication geconfigureerd
  • Key Vault aangemaakt
  • Secrets toegevoegd aan Key Vault
  • App Settings geconfigureerd (met Key Vault references)
  • Application Insights ingeschakeld

Post-Deployment:

  • Health checks werken
  • SSL/TLS werkt (automatisch)
  • Logging werkt
  • Monitoring ingesteld
  • Team geïnformeerd over URLs
  • Documentatie bijgewerkt

🎯 Volgende Stappen

  1. Start met Fase 1-3 (Basis setup + ACR + Environment variabelen)
  2. Test de applicatie (Fase 6)
  3. Configureer monitoring (Fase 5)
  4. Documenteer voor team (URLs, credentials, etc.)

📚 Gerelateerde Documentatie

  • Quick Deployment Guide: docs/QUICK-DEPLOYMENT-GUIDE.md
  • Production Deployment: docs/PRODUCTION-DEPLOYMENT.md
  • Azure Deployment Summary: docs/AZURE-DEPLOYMENT-SUMMARY.md

Vragen?

Veelgestelde vragen:

Q: Moet ik PostgreSQL gebruiken of kan ik SQLite houden?
A: SQLite is prima voor 20 gebruikers. Als je later groeit, kun je migreren naar PostgreSQL.

Q: Hoe update ik de applicatie?
A: Push naar main → Pipeline bouwt images → Restart Web Apps (of gebruik deployment slots voor zero-downtime).

Q: Kan ik de app 's avonds/weekend uitzetten?
A: Ja! az webapp stop --name cmdb-backend-prod --resource-group rg-cmdb-gui-prod (bespaart kosten).

Q: Hoe integreer ik met Elastic stack?
A: Exporteer Azure Monitor logs via Log Analytics Workspace → Elastic (zie Fase 5).


🎉 Success!

Je hebt nu een compleet deployment plan voor Azure App Service!

Start met Fase 1 en laat me weten als je hulp nodig hebt bij een specifieke stap.