Files
cmdb-insight/docs/DEPLOYMENT-ADVICE.md
Bert Hausmans cdee0e8819 UI styling improvements: dashboard headers and navigation
- Restore blue PageHeader on Dashboard (/app-components)
- Update homepage (/) with subtle header design without blue bar
- Add uniform PageHeader styling to application edit page
- Fix Rapporten link on homepage to point to /reports overview
- Improve header descriptions spacing for better readability
2026-01-21 03:24:56 +01:00

636 lines
18 KiB
Markdown

# Deployment Advies - CMDB Insight 🎯
**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
```bash
az group create \
--name rg-cmdb-gui-prod \
--location westeurope
```
#### Stap 1.2: App Service Plan Aanmaken
```bash
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
```bash
# 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/cmdb-insight/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/cmdb-insight/frontend:latest
```
---
### Fase 2: ACR Authentication (5 minuten)
#### Stap 2.1: Enable Managed Identity
```bash
# 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
```bash
# 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
```bash
# Backend
az webapp config container set \
--name cmdb-backend-prod \
--resource-group rg-cmdb-gui-prod \
--docker-custom-image-name zdlas.azurecr.io/cmdb-insight/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/cmdb-insight/frontend:latest \
--docker-registry-server-url https://zdlas.azurecr.io
```
---
### Fase 3: Environment Variabelen (10 minuten)
#### Stap 3.1: Azure Key Vault Aanmaken
```bash
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
```bash
# 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
```bash
# 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
```bash
# 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`):
```bash
# 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
```bash
# 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
```bash
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
```bash
# 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
```bash
# 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:**
```bash
# 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:**
```bash
# 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)
```bash
# 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)
```bash
# 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**
```bash
# 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.