← KI-Engineering und Agentic AI
Deployment-Infrastruktur · Produktion AKS · Bicep-IaC

Agentisches ERP: die Deployment-Infrastruktur

Die Pipeline, die den Copilot auf echte Infrastruktur bringt, mit den 6 Prüfungen, die vor jedem Release bestehen müssen.

7
Bicep-Infrastrukturmodule
AKS, ACR, Postgres, Redis, Cosmos DB, Monitor, AI Search
2
Kustomize-Overlays
Staging und Produktion
6
Prüfungen im Smoke-Test
Health, Doku, WebSocket, Human-Gate, Injection, Frontend
1
Freigabe-Gate
jedes Produktions-Deployment wartet auf eine prüfende Person

Eine CI/CD-Architektur aus zwei Repositories

Das Entwicklungs-Repository fährt bei jedem Push auf master eine GitHub-Actions-Pipeline aus 6 Jobs: Qualitäts-Gates im Backend (ruff, black, mypy, bandit, pytest-Unittests), tsc im Frontend, Integrationstests, ein Red-Team-Job (promptfoo und pytest) und ein Build, der die Images von API und Frontend in die Azure Container Registry schiebt. Ein repository_dispatch-Ereignis stößt danach dieses Deployment-Repository an.

Dieses Deployment-Repository nimmt das Ereignis auf und startet einen Deploy-Job, der über eine GitHub-Umgebung auf eine manuelle Freigabe wartet. Nach der Freigabe wendet der Job die Manifeste mit kubectl apply -k an, setzt die neuen Image-Tags und wartet auf den Rollout. Der Smoke-Test mit 6 Prüfungen läuft danach als eigener Job. Derselbe Workflow lässt sich auch von Hand starten, mit ausdrücklich angegebenen Image-Tags. Das Deployment in einem eigenen Repository zieht die Produktionsgrenze dorthin, wo eine prüfende Person sie sieht: kein Commit erreicht die Produktion ohne ein zweites Augenpaar.

Infrastruktur als Code: die Bicep-Module

Modul Detail
AKS Kubernetes 1.31 auf einem System-Knotenpool aus Standard_B2s (2 Knoten in den Produktionsparametern), mit Container Insights. OIDC-Issuer und Workload Identity sind im Cluster aktiviert, und eine AcrPull-Rolle lässt die Knoten Images ohne Registry-Passwort ziehen.
Azure Container Registry Basic-SKU. Der CI-Build schiebt die Images von API und Frontend hierher, mit dem Commit getaggt.
Postgres (Flexible Server) Burstable Standard_B1ms, mit den ERP-Daten und den pgvector-Embeddings der Verträge. Eine Firewall-Regel lässt Azure-Dienste zu.
Redis Cache Basic C0, nur TLS 1.2, mit LRU-Verdrängung. Trägt den semantischen Cache und die Entscheidungsdatensätze des Human-Gates (Lebensdauer 24 Stunden).
Cosmos DB Gremlin-API in der Gratisstufe, gedacht für den Wissensgraphen. East US hatte beim Deployment keine Kapazität, daher läuft der Graph auf Neo4j 5.26 im Cluster, auf einem 5-Gi-Volume.
Azure Monitor / App Insights Ein Log-Analytics-Workspace und Application Insights, gespeist vom OTel-DaemonSet. Die Alarmregeln stehen in alerts.bicep.
Azure AI Search Gratisstufe (50 MB, 3 Indizes).

Die Kustomize-Overlays

Ein Basissatz an Kubernetes-Manifesten gilt für alle Umgebungen: Deployments und Services für API, Frontend und Neo4j, eine ConfigMap, der Ingress und ein Job, der den Graphen befüllt. Die Overlays patchen nur, was sich unterscheidet. Staging setzt ein Namenspräfix, fährt 1 API-Replica und setzt eigenen Host und Log-Level. Produktion setzt Host, Log-Level und CORS-Origin. Kein Manifest wird dupliziert. Der Deploy-Workflow wendet derzeit die Basis an.

Der NGINX-Ingress-Controller leitet /api, /ws, /docs, /openapi.json und /health an das FastAPI-Backend und / an das Frontend. Der Ingress leitet über HTTP/1.1 mit einem Lese-Timeout von 1 Stunde weiter, damit der WebSocket mit dem Freigabe-Banner das Upgrade schafft und offen bleibt.

Observability: das OTel-DaemonSet

Ein DaemonSet mit dem OpenTelemetry Collector läuft auf jedem AKS-Knoten, nimmt OTLP-Traces und -Metriken aus den Anwendungs-Pods über gRPC oder HTTP entgegen und leitet sie über den azuremonitor-Exporter an Azure Monitor weiter. Eine Dashboard-Definition im Repository zeigt Anfragerate, Fehlerquote, P95-Latenz, die Latenz der LangGraph-Knoten je Intent, die Trefferquote des Solver-Caches und die offenen Freigaben.

Der Smoke-Test: 6 Prüfungen

Sobald kubectl rollout status einen gesunden Stand meldet, läuft das Skript smoke-test.sh mit 6 Prüfungen nacheinander und lässt den Job scheitern, wenn eine davon fehlschlägt:

  • Health-Endpunkt. GET /health liefert 200.
  • OpenAPI-Doku. GET /docs liefert 200, was bestätigt, dass FastAPI korrekt gestartet ist.
  • WebSocket-Erreichbarkeit. Eine WebSocket-Upgrade-Anfrage an /ws/chat bekommt eine Antwort (101, 400, 403 oder 404) statt eines Timeouts.
  • Router des Human-Gates. GET /api/approve/ mit einer unbekannten Entscheidungs-ID liefert 404 statt 500, was zeigt, dass die Freigabe-Route angebunden ist.
  • Injection-Sonde. Ein POST an den Freigabe-Endpunkt trägt eine Prompt-Injection, die Datenbank-Zugangsdaten verlangt, und die Antwort darf keines der Wörter password, secret, api_key, token oder credential enthalten.
  • Erreichbarkeit des Frontends. GET / liefert 200 vom Frontend.

Die Sicherheitslage

Die Workflows lesen ihren Azure-Zugang aus GitHub-Secrets, und die AKS-Knoten ziehen Images über eine AcrPull-Rolle statt über ein Registry-Passwort. Workload Identity ist im Cluster aktiviert, doch die Pods lesen ihre Dienst-Zugangsdaten noch aus einem Kubernetes-Secret, eine Lücke, die das Abweichungsprotokoll des Repositorys festhält. Redis nimmt nur TLS an. Postgres lässt Azure-Dienste über eine Firewall-Regel zu, und die Datendienste behalten den öffentlichen Netzwerkzugang, also sind private Endpunkte der nächste Schritt. Die Demo lief über einfaches HTTP auf einem nip.io-Hostnamen, und TLS über cert-manager steht noch aus.

  • Azure AKS
  • Bicep
  • Kustomize
  • GitHub Actions
  • OIDC
  • OTel
  • Azure Monitor
  • NGINX ingress
  • Postgres + pgvector
  • Redis
  • Neo4j
  • ACR