Skip to content

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:

node dist/main.js

Health Check

Konfigurieren Sie den App Service Health Check Pfad:

/health

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

  1. System-assigned Managed Identity auf dem App Service aktivieren
  2. 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:

  1. Datenbank-Migrationen ausführen:

    az webapp ssh --name tcm365-backend --resource-group rg-tcm365-prod
    # Innerhalb des Containers:
    npm run migration:run
    npm run db:seed
    
  2. Health verifizieren:

    curl https://tcm365-backend.azurewebsites.net/health
    
  3. Azure AD App Registrations konfigurieren (Read und Write App)

  4. UTCM Service Principal registrieren im Microsoft 365 Tenant

  5. 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.