Azure Deployment¶
TCM365 ist für den Produktionsbetrieb auf Microsoft Azure mit App Service, verwaltetem PostgreSQL, Key Vault und Blob Storage konzipiert. Dieser Guide behandelt die Infrastructure-as-Code Templates, Konfiguration und CI/CD Pipeline.
Azure Architektur¶
+--------------------+
| Azure Front Door |
| oder App Gateway |
+--------+-----------+
|
+--------------+--------------+
| |
+---------v----------+ +-----------v---------+
| App Service | | App Service |
| (Frontend) | | (Backend) |
| Vue 3 + Nginx | | NestJS + Node 18 |
+--------------------+ +---------+-----------+
|
+--------------------+--------------------+
| | |
+---------v------+ +---------v------+ +--------v--------+
| Azure Database | | Azure Redis | | Azure Blob |
| for PostgreSQL | | Cache | | Storage |
| (Flexible) | | (Optional) | | (Snapshots/ |
+----------------+ +----------------+ | Reports) |
+---------+-------+
|
+---------v-------+
| Azure Key Vault |
| (Secrets) |
+-----------------+
Infrastructure as Code (Bicep)¶
TCM365 beinhaltet Azure Bicep Templates für die Provisionierung aller benötigten Infrastrukturkomponenten:
infrastructure/azure/bicep/
├── main.bicep # Orchestrator -- deployt alle Module
├── webapp.bicep # App Service Plans und Web Apps
├── database.bicep # Azure Database for PostgreSQL Flexible Server
├── keyvault.bicep # Azure Key Vault für Secret Management
└── storage.bicep # Azure Blob Storage Account und Container
Deployment mit Bicep¶
# Bei Azure anmelden
az login
# Subscription festlegen
az account set --subscription "your-subscription-id"
# Resource Group erstellen
az group create --name rg-tcm365-prod --location westeurope
# Infrastruktur deployen
az deployment group create \
--resource-group rg-tcm365-prod \
--template-file infrastructure/azure/bicep/main.bicep \
--parameters \
appName=tcm365 \
environment=prod \
dbAdminUsername=tcm_admin \
dbAdminPassword="SecurePassword123!"
Passwort-Sicherheit
Verwenden Sie in Produktionsumgebungen Azure Key Vault oder Pipeline-Variablen für sensible Parameter wie dbAdminPassword. Uebergeben Sie Passwörter niemals direkt auf der Kommandozeile.
Bicep Modul-Details¶
main.bicep¶
Das Orchestrator Template, das alle Module mit korrekten Abhängigkeiten deployt:
// Vereinfachte Struktur
module database 'database.bicep' = { ... }
module storage 'storage.bicep' = { ... }
module keyvault 'keyvault.bicep' = { ... }
module webapp 'webapp.bicep' = {
dependsOn: [database, storage, keyvault]
params: {
databaseConnectionString: database.outputs.connectionString
storageConnectionString: storage.outputs.connectionString
keyVaultUri: keyvault.outputs.vaultUri
}
}
webapp.bicep¶
Konfiguriert den Azure App Service:
| Eigenschaft | Wert |
|---|---|
| App Service Plan | Linux, B2 Tier (Minimum für Produktion) |
| Web App | Node.js 18 LTS Runtime |
| Deployment Slots | Staging Slot für Zero-Downtime Deployments |
| Skalierung | Auto-Scale Regeln basierend auf CPU und Memory |
database.bicep¶
Konfiguriert Azure Database for PostgreSQL Flexible Server:
| Eigenschaft | Wert |
|---|---|
| Version | PostgreSQL 15 |
| SKU | General Purpose (GP_Standard_D2s_v3 Minimum) |
| High Availability | Zone-redundant HA (optional) |
| Backup | Automatische Backups mit 7-35 Tagen Retention |
| Networking | VNet Integration oder Public Access mit Firewall-Regeln |
keyvault.bicep¶
Konfiguriert Azure Key Vault:
| Eigenschaft | Wert |
|---|---|
| SKU | Standard |
| Access Policies | App Service Managed Identity |
| Secrets | DB-Passwort, JWT Secret, Azure AD Credentials |
| Soft Delete | Aktiviert mit 90 Tagen Retention |
storage.bicep¶
Konfiguriert Azure Blob Storage:
| Eigenschaft | Wert |
|---|---|
| Account Type | StorageV2, Standard LRS (oder GRS für Produktion) |
| Container | tcm-snapshots, tcm-reports, tcm-exports |
| Zugriff | Privat (kein öffentlicher Blob-Zugriff) |
Azure App Service Konfiguration¶
Application Settings¶
Konfigurieren Sie die folgenden Umgebungsvariablen in den App Service Application Settings:
| Einstellung | Wert / Quelle |
|---|---|
PORT |
8000 |
APP_SECRET_KEY |
@Microsoft.KeyVault(VaultName=...) |
APP_DEBUG |
false |
DATABASE_HOST |
your-db.postgres.database.azure.com |
DATABASE_PORT |
5432 |
DATABASE_USERNAME |
tcm_admin |
DATABASE_PASSWORD |
@Microsoft.KeyVault(VaultName=...) |
DATABASE_NAME |
tcm_db |
DATABASE_SSL |
true |
STORAGE_BACKEND |
azure |
AZURE_STORAGE_CONNECTION_STRING |
@Microsoft.KeyVault(VaultName=...) |
AZURE_STORAGE_CONTAINER |
tcm-data |
REDIS_URL |
rediss://your-redis.redis.cache.windows.net:6380 |
CORS_ORIGINS |
https://tcm.example.com |
AZURE_AD_TENANT_ID |
your-tenant-id |
AZURE_AD_CLIENT_ID |
your-client-id |
AZURE_AD_CLIENT_SECRET |
@Microsoft.KeyVault(VaultName=...) |
Key Vault Referenzen
Verwenden Sie die @Microsoft.KeyVault(VaultName=your-vault;SecretName=secret-name) Syntax in App Service Settings, um Secrets aus Key Vault zu referenzieren, ohne sie in Konfigurationsdateien offenzulegen.
Startup Command¶
Konfigurieren Sie den App Service Startup Command:
Health Check¶
Konfigurieren Sie den App Service Health Check Pfad:
Azure nutzt diesen Endpoint, um die Anwendungsgesundheit zu überwachen und ungesunde Instanzen automatisch neu zu starten.
Azure Key Vault¶
TCM365 verwendet Azure Key Vault für sicheres Secret Management in Produktionsumgebungen über das pluggable SecretBackend Interface.
Secret Backend Konfiguration¶
| Umgebung | Backend | Konfiguration |
|---|---|---|
| Entwicklung | LocalAES |
AES Encryption mit lokalem Key File |
| Produktion | AzureKeyVault |
Azure Key Vault mit Managed Identity |
Zu speichernde Secrets¶
| Secret Name | Zweck |
|---|---|
app-secret-key |
JWT Signing Secret |
database-password |
PostgreSQL Passwort |
azure-ad-client-secret |
Azure AD App Registration Secret |
storage-connection |
Azure Storage Connection String |
redis-password |
Redis Authentifizierungspasswort |
smtp-password |
E-Mail Notification SMTP Passwort |
openai-api-key |
OpenAI API Key (optional) |
Managed Identity Setup¶
- System-assigned Managed Identity auf dem App Service aktivieren
- Der Managed Identity Zugriff auf Key Vault gewaehren:
# App Service Managed Identity Principal ID abrufen
PRINCIPAL_ID=$(az webapp identity show \
--name tcm365-backend \
--resource-group rg-tcm365-prod \
--query principalId -o tsv)
# Key Vault Zugriff gewaehren
az keyvault set-policy \
--name your-keyvault-name \
--object-id $PRINCIPAL_ID \
--secret-permissions get list
RBAC vs. Access Policies
Azure Key Vault unterstützt sowohl Access Policies als auch Azure RBAC für die Zugriffskontrolle. Für neue Deployments wird RBAC empfohlen, da es eine feingranularere Kontrolle bietet und konsistent mit dem Azure-Sicherheitsmodell ist.
Azure Blob Storage¶
Storage Konfiguration¶
STORAGE_BACKEND=azure
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
AZURE_STORAGE_CONTAINER=tcm-data
Container-Struktur¶
| Container | Zweck |
|---|---|
tcm-snapshots |
Konfigurationssnapshotdaten |
tcm-reports |
Generierte Report-Dateien |
tcm-exports |
Diff-Export-Dateien (JSON, HTML) |
Sicherheit¶
- Alle Container sind mit privatem Zugriff konfiguriert (kein öffentlicher Blob-Zugriff)
- Zugriff wird via Connection String oder Managed Identity gewaehrt
- Soft Delete für Blob-Wiederherstellung aktivieren
CI/CD mit Azure Pipelines¶
Die CI/CD Pipeline ist in infrastructure/azure-pipelines.yml definiert:
Pipeline Stages¶
+----------+ +---------+ +----------+ +------------+
| Install |---->| Lint |---->| Test |---->| Build |
+----------+ +---------+ +----------+ +-----+------+
|
+-------------+-------------+
| |
+-------v--------+ +-------v--------+
| Deploy Staging |-------->| Deploy Prod |
| (automatisch) | | (manuelles |
+----------------+ | Approval Gate)|
+----------------+
Stage Details¶
| Stage | Aktionen | Trigger |
|---|---|---|
| Install | npm ci für Backend und Frontend |
Push auf main |
| Lint | ESLint Code Quality Checks | Automatisch |
| Test | Jest Unit Tests (780+ Tests) | Automatisch |
| Build | TypeScript + Vite Production Builds | Automatisch |
| Deploy Staging | Push auf Staging App Service Slot | Automatisch |
| Deploy Prod | Swap Staging zu Produktion | Manuelles Approval |
Pipeline Konfiguration¶
trigger:
branches:
include:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
- group: tcm365-production # Variable Group mit Secrets
stages:
- stage: Build
jobs:
- job: BackendBuild
steps:
- task: NodeTool@0
inputs:
versionSpec: '18.x'
- script: |
cd backend-js
npm ci
npm run lint
npm test
npm run build
- publish: $(System.DefaultWorkingDirectory)/backend-js/dist
artifact: backend
- job: FrontendBuild
steps:
- task: NodeTool@0
inputs:
versionSpec: '22.x'
- script: |
cd frontend
npm ci
npm run build
- publish: $(System.DefaultWorkingDirectory)/frontend/dist
artifact: frontend
- stage: Deploy
dependsOn: Build
jobs:
- deployment: Production
environment: production
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
appName: 'tcm365-backend'
package: '$(Pipeline.Workspace)/backend'
Variable Groups
Speichern Sie sensible Werte wie Datenbank-Passwörter und API Keys in einer Azure DevOps Variable Group und verknüpfen Sie diese optional mit Azure Key Vault für automatische Synchronisation.
Post-Deployment Schritte¶
Nach dem erstmaligen Deployment auf Azure:
-
Datenbank-Migrationen ausführen:
-
Health verifizieren:
-
Azure AD App Registrations konfigurieren (Read und Write App)
-
UTCM Service Principal registrieren im Microsoft 365 Tenant
-
Konnektivität testen über den TCM365 Setup Wizard
Skalierungsueberlegungen¶
| Komponente | Skalierungsstrategie | Hinweise |
|---|---|---|
| App Service | Horizontales Auto-Scaling (CPU/Memory Schwellwerte) | B2 Minimum, S2+ empfohlen |
| PostgreSQL | Vertikale Skalierung (größere SKU) | GP_Standard_D2s_v3 Minimum |
| Redis | Vertikale Skalierung | C1 Standard Minimum |
| Blob Storage | Automatisch (keine Aktion erforderlich) | Standard LRS oder GRS |
Stateless Backend
Das NestJS Backend ist stateless (Session-Daten im JWT, Shared State in PostgreSQL/Redis), sodass horizontale Skalierung ohne Weiteres funktioniert. Mehrere App Service Instanzen können gleichzeitig Requests bedienen.