GNAI-007: Basisfunktionen für Ansible erstellt.

This commit is contained in:
2026-09-19 23:20:35 +02:00
parent 7d1a3228ef
commit de06eb6129
18 changed files with 1227 additions and 2 deletions
+16
View File
@@ -17,6 +17,8 @@
| [GNAI-006-SEC_VPN_Clients_Windows11.md](GNAI-006-SEC_VPN_Clients_Windows11.md) | offizieller Windows-Client, Import und Verwendung; Junior IT |
| [GNAI-006-SEC_VPN_Clients_Linux.md](GNAI-006-SEC_VPN_Clients_Linux.md) | Debian, Arch/CachyOS, Fedora/Kinoite; Junior IT |
| [GNAI-006-SEC_VPN_Implementation-Log.md](GNAI-006-SEC_VPN_Implementation-Log.md) | historische v14/v15-Umsetzung und Evidenzkorrekturen; Intermediate IT |
| [GNAI-007-PLAN_Ansible-Deployment.md](GNAI-007-PLAN_Ansible-Deployment.md) | nicht finaler Arbeitsentwurf zum Ansible-/Gitea-Deployment und zur geplanten Folgedokumentation; Infrastrukturadministratoren und Mitwirkende |
| [Ansible-Control-Projekt](../ansible/README.md) | Control-Node, Preflight, Deployment-Account und gemeinsame Host-Baseline; Intermediate IT |
## 2. Verbindliche, bestätigte Entscheidungen
@@ -32,6 +34,14 @@ Die getrennten Schlüsselzugänge für `ghost` und `ghost-agent` wurden am 19.09
Der KI-Server ist laut Betreiber frisch eingerichtet. Die LLM-Anwendungen sollen erst in einem späteren Sprint mit Ansible installiert werden. Bis dahin beschreiben GNAI-003 und GNAI-004 für diesen Host ein Zielbild; der lesende SSH-Abgleich betraf nur Basisbetrieb und Zugänge.
Der [Ansible-Deployment-Entwurf](GNAI-007-PLAN_Ansible-Deployment.md) persistiert den Planungsstand vom 19.09.2026. Er ist ausdrücklich keine verbindliche Spezifikation und kein Nachweis einer eingerichteten Deploymentkette. Die dort genannten Runner-, Account-, Freigabe- und Secret-Verfahren sind bis zu ihrer Prüfung und formalen Übernahme vorläufig.
Das erste Ansible-Control-Projekt mit Testing-Inventar und lesendem Preflight wurde am 19.09.2026 angelegt. Der Live-Lauf über `ghost-agent` bestätigte Hostidentität, Debian 13.6, IPv4-Adresse, Python, CPU, RAM und zwei Navi-21-Geräte mit `changed=0`, `unreachable=0` und `failed=0`. Dieser Nachweis umfasst weder privilegierten Zugriff noch eine eingerichtete Production-/Testing-Laufzeitumgebung.
Der separate Ed25519-Schlüssel mit Fingerprint `SHA256:IKEInbIo8VVI1USg5+a3ypGK8H8FweJiQu+v7KvhQDU` und das Bootstrap-Playbook wurden am 19.09.2026 verwendet, um `ansible-deploy` einzurichten. Der private Schlüssel liegt ausschließlich außerhalb des Repositories. Der Account besitzt ein gesperrtes Passwort, einen auf LAN- und WireGuard-Quellnetze beschränkten Public Key und eine mit `visudo` validierte Regel `NOPASSWD: ALL`. Ein getrenntes Prüfplaybook bestätigte anschließend Anmeldung, Modulausführung und effektive UID 0 über sudo mit `ok=5 changed=0 unreachable=0 failed=0`.
Die erste schreibende Rolle `host_baseline` wurde am 19.09.2026 nach erfolgreichem Syntax- und Check-Modus-Lauf angewendet. Sie prüft Hostname, Debian-Hauptversion, Standard-IPv4 sowie mindestens 100 GiB freien Speicher und verwaltet ausschließlich `/etc/ghostnet-ai/{production,testing}` und `/var/lib/ghostnet-ai/{production,testing,shared}` mit Root-Eigentum. Der erste reale Lauf meldete `ok=6 changed=1 unreachable=0 failed=0`; der unmittelbar folgende identische Lauf belegte Idempotenz mit `ok=6 changed=0 unreachable=0 failed=0`. Pakete, Dienste und Anwendungen wurden dabei nicht verändert.
## 3. Sicherheitsbefunde mit Priorität
| Befund | dokumentiertes Verfahren / Status |
@@ -59,4 +69,10 @@ Bei der Dokumentationskonsolidierung wurden keine Serverkonfigurationen geänder
Am 18.09.2026 wurden WireGuard-LXC und KI-Server ergänzend lesend per SSH geprüft. Der KI-Server-Teilabgleich bestätigt Hostname, Konten, Netzkonfiguration, Debian-Version, CPU, RAM, zwei Navi-21-GPUs und SSD-Partitionierung; BIOS, ROCm und die Anwendungsdienste wurden dabei nicht abgenommen. Details stehen in [GNAI-001](GNAI-001-INFRA_BaseSystem.md) und [GNAI-002](GNAI-002-INFRA_Users.md).
Am 19.09.2026 bestätigte ein erster reproduzierbarer Ansible-Preflight über das unprivilegierte Konto `ghost-agent` erneut `ghostnet-ki`, Debian 13.6, `10.0.0.90`, 14 vCPUs, 64.123 MiB RAM, Remote-Python 3.13.5 und zwei PCI-Geräte `1002:73bf`. Der Play Recap lautete `ok=5 changed=0 unreachable=0 failed=0`. Das Playbook verwendete kein `sudo` und nahm keine Serverkonfiguration vor.
Beim anschließenden Bootstrap wurden Benutzer, Home-/SSH-Verzeichnisse, `authorized_keys` und sudoers-Datei erfolgreich angelegt. Nur die letzte Assertion des ersten Laufs schlug wegen einer als Mapping interpretierten YAML-Bedingung fehl; die Bedingung wurde anschließend als String korrigiert. Da alle schreibenden Tasks vorher erfolgreich waren, bestätigte das unabhängige Prüfplaybook den wirksamen Endzustand ohne weitere Änderung. Ein vollständiger zweiter Bootstrap-Lauf zur Idempotenzprüfung steht noch aus.
Für die gemeinsame Host-Baseline bestätigte ein vorgelagerter Check-Modus genau sieben neu anzulegende Verzeichnisse und rund 1.677,7 GiB freien Platz auf `/`. Der anschließende reale Lauf legte die Verzeichniswurzeln an. Eine sofortige Wiederholung ergab `changed=0`; die Rolle konvergiert damit für ihren derzeitigen Umfang. Dieser Nachweis umfasst keine Paket-, Runtime-, GPU- oder Anwendungsinstallation.
Die WireGuard-Evidenz bleibt der Teiltest vom 12.09.2026: CachyOS-Laptop von WAN, Handshake, Ping auf Gateway/Proxmox und direkter IPv4-Internetpfad bestanden; KI-Server war ausgeschaltet. Neue Rollen, weitere Clientvarianten, Gateway-GUI-Zugriff, WAN-/IPv6-Isolation, Neustart und Restore sind noch nicht abgenommen. GNAI-006 ist erst nach Klärung der offenen Werte, Umsetzung und dokumentierter Abnahme technisch abgeschlossen.
+711
View File
@@ -0,0 +1,711 @@
# Arbeitsentwurf
**Dokumenten-ID:** GNAI-007-PLAN
**Titel:** Ansible-Deployment für den KI-Server – Planungsstand
**Stand:** 2026-09-19
**Status:** Nicht finaler Arbeitsentwurf zur Persistierung des aktuellen Planungsstands
**Referenzen:** [Projektstand](GNAI-000-DOC_Index.md), [Zielarchitektur](GNAI-003-INFRA_Architecture.md), [Zugriffskonzept](GNAI-004-SEC_Access-Control.md)
> **Abgrenzung:** Dieses Dokument hält die Ergebnisse der Planungssession vom
> 19.09.2026 fest. Es ist weder eine freigegebene technische Spezifikation noch
> eine Installationsanleitung oder ein Nachweis über bereits umgesetzte
> Komponenten. Entscheidungen, die noch geprüft oder bestätigt werden müssen,
> sind ausdrücklich als vorläufig oder offen gekennzeichnet.
---
## Änderungsverlauf
| Datum | Version | Autor | Beschreibung |
| --- | --- | --- | --- |
| 2026-09-19 | 0.1 | spektr / Codex | Planungsstand zu Ansible, Gitea Actions, Runner, Freigaben und künftiger Dokumentation aus der Session festgehalten |
| 2026-09-19 | 0.2 | spektr / Codex | vorläufige Ein-Repository-Strategie sowie logisch getrennte Production- und Testing-Umgebungen auf dem KI-Server ergänzt |
| 2026-09-19 | 0.3 | spektr / Codex | exklusiven zeitlich gestaffelten Betrieb von Production und Testing ohne physische Ressourcenaufteilung als Planungsentscheidung übernommen |
| 2026-09-19 | 0.4 | spektr / Codex | erstes Ansible-Control-Projekt und erfolgreich ausgeführten lesenden Live-Preflight als belegten Implementierungsstand ergänzt |
| 2026-09-19 | 0.5 | spektr / Codex | technischen Schlüssel sowie Bootstrap- und Prüfplaybook für `ansible-deploy` vorbereitet; Ausführung bleibt interaktiv offen |
| 2026-09-19 | 0.6 | spektr / Codex | `ansible-deploy` auf dem KI-Server eingerichtet und SSH-/sudo-Zugriff unabhängig erfolgreich verifiziert |
| 2026-09-19 | 0.7 | spektr / Codex | minimale gemeinsame Host-Baseline mit Schutzprüfungen und getrennten Verzeichniswurzeln implementiert, angewendet und auf Idempotenz geprüft |
---
## 1. Zweck
Der KI-Server `ghostnet-ki` soll reproduzierbar mit Ansible aufgebaut und
aktualisiert werden. Mehrere berechtigte Personen sollen Änderungen gemeinsam
über Gitea entwickeln, prüfen, freigeben und nachvollziehbar ausrollen können.
Gesucht wird ein Verfahren, das:
- den vollständigen Sollzustand des Servers versioniert,
- wiederholbare und möglichst idempotente Deployments ermöglicht,
- Änderungen vor der Anwendung prüft,
- einen nachvollziehbaren Freigabeweg für mehrere Mitwirkende bietet,
- Geheimnisse und privilegierte Zugänge vom Quelltext trennt,
- Fehler und Rollbacks betrieblich beherrschbar macht und
- für einen einzelnen KI-Server ohne unnötig große Managementplattform
betrieben werden kann.
Die Planung umfasst sowohl die spätere technische Implementierung als auch die
Dokumentation für Administratoren, Entwickler und Deployment-Berechtigte.
---
## 2. Ausgangslage
Nach dem dokumentierten Stand ist der KI-Server ein Debian-Basissystem unter
`10.0.0.90`. Der geplante Anwendungsstack aus `llama.cpp`, LiteLLM, OpenWebUI
und weiteren Anwendungen ist noch nicht installiert. Gitea ist im bestehenden
Serviceinventar unter `10.0.0.17:3000` geführt; Version, Actions-Konfiguration
und Registry-Funktionen müssen vor der Implementierung live geprüft werden.
Der bestehende Account `ghost-agent` ist für lesende Prüfungen vorgesehen und
besitzt nach dem letzten Abgleich keine `sudo`-Berechtigung. Er soll nach dem
aktuellen Plan nicht zum privilegierten Deployment-Account erweitert werden.
Das Repository enthält inzwischen ein minimales Ansible-Control-Projekt mit
Testing-Inventar, einem ausschließlich lesenden Preflight sowie Bootstrap- und
Prüfplaybooks für `ansible-deploy`. Der privilegierte Deployment-Account ist
eingerichtet und verifiziert. Eine erste schreibende Rolle verwaltet die
gemeinsamen Konfigurations- und Datenwurzeln des Hosts; Anwendungsrollen und ein
Production-Inventar existieren noch nicht. Der Preflight selbst nahm keine
Änderungen vor; Bootstrap und Host-Baseline blieben auf die nachfolgend
dokumentierten Zugangs- und Verzeichniszustände begrenzt.
---
## 3. Vorläufiges Zielbild
Ansible bleibt die einzige technische Quelle für den gewünschten Zustand des
KI-Servers. Gitea verwaltet Quelltext, Reviews, Freigaben und Jobprotokolle.
Getrennte Runner- beziehungsweise Berechtigungsstufen führen CI-Prüfungen,
Testing-Deployments und Production-Deployments aus. Die genaue Anzahl der
Runner wird nach Prüfung der Gitea-Berechtigungsgrenzen festgelegt.
```mermaid
flowchart LR
DEV[Feature-Branch] --> PR[Pull Request]
PR --> CI[statische CI ohne Serverzugang]
CI --> TESTOK[freigegebener Testing-Lauf]
TESTOK --> TESTRUNNER[Testing-Berechtigung]
TESTRUNNER --> TEST[Testing auf ghostnet-ki]
TEST --> REVIEW[Review und Merge nach main]
REVIEW --> RELEASE[bewusste Production-Freigabe]
RELEASE --> PRODRUNNER[Production-Berechtigung]
PRODRUNNER --> PROD[Production auf ghostnet-ki]
PROD --> VERIFY[Health- und Funktionstests]
UPSTREAM[versionierte Upstream-Artefakte] --> UPDATE[Versions-Pin im Infrastruktur-Repository]
UPDATE --> PR
```
Runner sollen keine eingehenden Verbindungen aus dem Internet benötigen. Sie
holen Jobs bei Gitea ab und benötigen ausgehend nur die für Gitea, Paket- oder
Imagequellen und den jeweiligen SSH-Zugriff zum KI-Server erforderlichen
Verbindungen. CI-Jobs erhalten keinen SSH-Zugriff zum KI-Server.
---
## 4. Ergebnisse der bisherigen Planung
Die folgende Tabelle unterscheidet bewusst zwischen einer gewählten
Planungsrichtung und noch nicht bestätigten Implementierungsdetails.
| Thema | Aktueller Planungsstand | Verbindlichkeit / Nachweis |
| --- | --- | --- |
| Konfigurationsmanagement | Ansible beschreibt Basissystem, Laufzeitumgebung, Dienste und Konfiguration | minimales Control-Projekt, lesender Preflight und angewendete erste `host_baseline` vorhanden; Runtime- und Anwendungsrollen fehlen noch |
| Quell- und Freigabeverfahren | Änderungen über Gitea-Branches und Pull Requests; kein regulärer Direkt-Push auf `main` | vorgesehen; Branch-Schutz noch nicht geprüft oder eingerichtet |
| CI | Pull Requests erhalten Lint-, YAML- und Ansible-Syntaxprüfungen ohne produktive Zugangsdaten | vorgesehen; Workflow noch nicht vorhanden |
| Produktionsausführung | Gitea Actions startet Ansible über eine dedizierte Production-Berechtigungsstufe | bevorzugte Lösung; Gitea-Version, Runner-Trennung und Actions-Funktion noch zu prüfen |
| Runner-Platzierung | eigener kleiner LXC, getrennt von Gitea und KI-Server | bevorzugt; Host, Adresse und Ressourcen noch offen |
| Job-Isolation | containerisierte Jobs; für den Gitea Runner ist nach aktueller Herstellerdokumentation Docker der unterstützte Standard | bevorzugt; lokale Freigabe und LXC-Eignung noch offen |
| Parallelität | Produktionsrunner führt höchstens einen Job gleichzeitig aus | vorgesehen; Runner-Konfiguration noch nicht vorhanden |
| Deployment-Freigabe | nach erfolgreichem Review bewusste Freigabe über geschützten `deploy-*`-Tag | bevorzugte Startvariante; Namensschema und berechtigte Teams noch offen |
| Zielzugang | eigener technischer SSH-Account `ansible-deploy` mit separatem, quellnetzbeschränktem Schlüssel und validiertem `NOPASSWD: ALL` | auf dem KI-Server eingerichtet und unabhängig verifiziert; spätere Runner-Übernahme und Rotation offen |
| Geheimnisse | verschlüsselte Ansible-Variablen plus getrennt gespeichertes Vault-Passwort und Runner-Zugangsdaten | Richtung angenommen; konkreter Secret-Workflow noch offen |
| Artefaktversionen | Pakete, Collections und Container-Images werden auf konkrete Versionen, nach Möglichkeit Digests, festgelegt | vorgesehen |
| Repository-Zuschnitt | vorerst ausschließlich das bestehende Repository `infrastructure`; weitere Quellcode-Repositories erst bei tatsächlich eigenständig entwickelten Anwendungen oder MCP-Komponenten | als aktuelle Planungsentscheidung angenommen |
| Anwendungsupdates | Upstream-Artefakte werden im Infrastruktur-Repository auf eine geprüfte Version festgelegt; eigene Build-Repositories sind vorerst nicht Bestandteil des Projekts | vorgesehen; Registry- und Buildverfahren bei späterem Eigenentwicklungsbedarf neu bewerten |
| Automatische Updates | kein unbeaufsichtigtes Produktionsupdate über `latest` oder Watchtower | vorläufige Sicherheitsentscheidung |
| Laufzeitumgebungen | Production und Testing werden als getrennte Stacks auf demselben physischen KI-Server betrieben | als aktuelle Planungsentscheidung angenommen |
| Production | stabiler, extern nutzbarer Stand mit bewusst freigegebenen Versionen | Zielbild; Dienste noch nicht eingerichtet |
| Testing | interner, kurzlebiger oder zurücksetzbarer Stand für kontrollierte Tests vor dem Merge nach `main`; nutzt während eines Wartungsfensters die vollständige Hardware exklusiv | Zielbild; Dienste, Zugriffsweg und Umschaltverfahren noch nicht eingerichtet |
| Ressourcenbetrieb | keine feste physische Aufteilung; Production und Testing laufen nicht gleichzeitig und werden über einen exklusiven Umschaltvorgang zeitlich gestaffelt | als aktuelle Planungsentscheidung angenommen |
| Betriebsnachweis | erfolgreicher Lauf dokumentiert Git-Commit, Zielhost, Zeitpunkt, Prüfungen und Ergebnis | vorgesehen |
| Rollback | Konfigurationsänderung über Revert und erneute Freigabe; persistente Daten zusätzlich über getestete Backups wiederherstellen | Grundprinzip; konkrete SOP noch zu erstellen |
Eine spätere Umstellung auf ein automatisches Deployment nach jedem Merge in
`main` bleibt möglich. Zu Beginn soll die Freigabe jedoch bewusst und
nachvollziehbar erfolgen, während die technische Ausführung vollständig
automatisiert wird.
---
## 5. Verworfene oder zurückgestellte Varianten
### 5.1 Ausschließliche Ausführung vom Admin-PC
Lokale Ansible-Ausführung bleibt für Entwicklung, Diagnose und Notfälle
sinnvoll. Sie soll nicht der reguläre Produktionsweg werden, weil Ausführung,
Werkzeugversionen und Protokolle sonst von einem einzelnen Arbeitsplatz
abhängen.
### 5.2 `ansible-pull` auf dem KI-Server
Der Zielserver könnte das Repository periodisch selbst abrufen und lokal
anwenden. Für den einzelnen zentral erreichbaren Server bietet das derzeit
weniger klare Freigaben und eine ungünstigere Trennung zwischen Zielsystem und
Deployment-Steuerung. Die Variante bleibt zurückgestellt.
### 5.3 AWX
AWX bietet eine eigene Oberfläche, Rollen, Zeitpläne und Inventarverwaltung.
Der zusätzliche Plattformbetrieb erscheint für den aktuellen Umfang zu groß.
AWX kann erneut bewertet werden, wenn mehrere Zielsysteme, feinere delegierte
Rechte oder umfangreiche Jobpläne verwaltet werden müssen.
---
## 6. Repository-Verantwortung
Vorerst wird ausschließlich das bestehende Repository `infrastructure`
verwendet. Es soll den vollständigen Sollzustand des KI-Servers, beide
Laufzeitumgebungen und die zugehörigen Workflows besitzen. Damit verändern
nicht mehrere unabhängige Deployment-Repositories denselben Host.
Vorgesehene grobe Struktur:
```text
ansible/
├── ansible.cfg
├── collections/
│ └── requirements.yml
├── inventories/
│ ├── production/
│ └── testing/
├── playbooks/
│ ├── host.yml
│ ├── environment.yml
│ └── verify.yml
└── roles/
├── host_baseline/
├── environment_stack/
└── weitere_fachrollen/
.gitea/workflows/
├── validate.yml
├── deploy-testing.yml
└── deploy-production.yml
```
Diese Struktur ist ein Ausgangspunkt und noch keine Festlegung aller Rollen.
`host.yml` und `environment.yml` sollen gemeinsam den unterstützten
Gesamtzustand herstellen. Ansible-Tags können Diagnose und gezielte Wartung
unterstützen, dürfen aber nicht zu ungetesteten alternativen Installationswegen
führen.
Unveränderte Drittanbieterkomponenten wie `llama.cpp`, LiteLLM oder OpenWebUI
erhalten derzeit kein eigenes Repository. Ihre freigegebenen Versionen oder
Image-Digests werden im Infrastruktur-Repository geführt. Ein weiteres
Repository wird erst angelegt, wenn tatsächlich eigener, unabhängig
versionierter Quellcode für eine Anwendung, einen MCP Router oder MCP Server
entwickelt wird. Diese spätere Erweiterung ändert nichts daran, dass das
Infrastruktur-Repository allein festlegt, welche Artefaktversion in welcher
Umgebung läuft.
---
## 7. Production und Testing auf einem Host
### 7.1 Geltungsbereich der Trennung
Production und Testing laufen zunächst auf demselben physischen KI-Server.
Damit können Anwendungscontainer, Konfigurationen und Daten sauber logisch
getrennt werden. Die Hardware kann wegen des hohen Leistungsbedarfs nicht
dauerhaft zwischen beiden Umgebungen aufgeteilt werden. Stattdessen erhält die
jeweils aktive Umgebung CPU, RAM und beide GPUs exklusiv. Es entstehen dennoch
keine getrennten Fehlerdomänen:
- Kernel, AMD-Treiber beziehungsweise ROCm, Podman und systemd werden gemeinsam
verwendet;
- ein Hostausfall betrifft beide Umgebungen;
- ein fehlerhafter Testing-Stand kann den gemeinsamen Host beeinträchtigen und
dadurch den Wiederanlauf von Production verzögern;
- Kernel-, Treiber- und Host-Runtime-Updates können nicht realitätsnah in
Testing geprüft werden, ohne den gemeinsamen Host zu verändern.
Testing ist deshalb für neue Anwendungsstände, Konfigurationen, MCP-Komponenten
und Integrationen vorgesehen. Für risikoarme Vorabtests von Kernel-, Treiber-
oder Podman-Upgrades wäre später ein zweiter Host oder eine ausreichend
vergleichbare separate Maschine erforderlich.
Die von externen Nutzern erwartete Stabilität von Production gilt außerhalb
angekündigter Test- und Wartungsfenster. Solange nur dieser eine ausgelastete
Host verfügbar ist, verursachen realistische Tests mit voller Hardware eine
geplante Unterbrechung von Production.
### 7.2 Isolationsziele
| Bereich | Production | Testing |
| --- | --- | --- |
| Erreichbarkeit | für freigegebene Dienste über NPM; Backend- und Managementports bleiben intern | nur aus freigegebenem LAN/VPN; keine öffentliche NPM-Route |
| Container- und Unit-Namen | eigener eindeutiger Präfix | eigener eindeutiger Präfix |
| Podman-Netz | eigenes internes Netz | eigenes internes Netz ohne Verbindung zum Production-Netz |
| Konfiguration | eigener Verzeichnisbaum | eigener Verzeichnisbaum |
| Persistente Daten | eigene Volumes mit Backup- und Restore-Verfahren | eigene zurücksetzbare Volumes; keine Production-Datenkopie ohne Bereinigung und Freigabe |
| Secrets und API-Keys | ausschließlich Production-Credentials | eigene eingeschränkte Test-Credentials |
| Ports und Hostnamen | stabile freigegebene Endpunkte | getrennte interne Ports und noch festzulegende Testhostnamen |
| Ressourcen | erhält im Normalbetrieb die vollständige Hardware exklusiv | erhält ausschließlich im freigegebenen Testfenster die vollständige Hardware exklusiv |
| GPU | beide GPUs, solange Production aktiv ist | beide GPUs, nachdem Production vollständig beendet wurde |
| Ausführungszustand | standardmäßig aktiv | standardmäßig gestoppt |
| Verfügbarkeit | stabiler Betriebsstand außerhalb angekündigter Wartungsfenster | best effort; wird nach jedem Testlauf wieder vollständig gestoppt |
Eine gleichzeitige Inferenzlast beider Umgebungen ist nicht vorgesehen. Vor dem
Start von Testing muss nachweisbar sein, dass Production beendet wurde und
keine zugehörigen Prozesse mehr CPU-, RAM- oder GPU-Ressourcen halten. Vor dem
Wiederanlauf von Production muss Testing entsprechend vollständig beendet und
sein temporärer Zustand bereinigt sein. Speicherplatz- und Prozessgrenzen
bleiben auch bei exklusiver Rechenleistung sinnvoll, damit ein Test nicht den
gemeinsamen Datenträger füllt oder den Host dauerhaft beeinträchtigt.
Große schreibgeschützte Modelldateien können später aus einem gemeinsamen,
nur lesbar eingebundenen Modellspeicher bereitgestellt werden. Datenbanken,
Uploads, Caches mit Schreibzugriff, Benutzerkonten und Anwendungsschlüssel
bleiben vollständig getrennt. Ob ein gemeinsamer Modellspeicher technisch und
betrieblich sinnvoll ist, wird erst mit dem Modell- und Backupkonzept
entschieden.
### 7.3 Exklusives Umschaltverfahren
Ein Testing-Deployment ist zugleich ein geplantes Wartungsfenster für
Production. Der vorläufige Ablauf lautet:
1. konkreten PR-Commit und Testumfang festlegen;
2. Testing-Lauf durch eine berechtigte Person freigeben und Wartungsfenster
dokumentieren;
3. letzten funktionsfähigen Production-Stand und erforderlichen Backupstatus
feststellen;
4. neue externe Anfragen nach Möglichkeit kontrolliert abweisen und Production
geordnet beenden;
5. prüfen, dass alle Production-Units, -Container und GPU-Prozesse beendet
sind;
6. einen hostweiten exklusiven Deployment-Lock setzen;
7. Testing für den festgelegten Commit ausrollen und mit der vollständigen
Hardware starten;
8. Health Checks und fachliche Tests ausführen und Ergebnisse dem Pull Request
zuordnen;
9. Testing unabhängig vom Testergebnis vollständig stoppen;
10. prüfen, dass alle Testing-Units, -Container und GPU-Prozesse beendet sind;
11. Production unverändert auf dem zuletzt freigegebenen Stand starten;
12. Production-Health- und Inferenztests ausführen und erst danach das
Wartungsfenster beenden.
Der Wiederanlauf von Production darf nicht ausschließlich von einem letzten
Schritt im Gitea-Job abhängen. Runner-Abbruch, Netzwerkverlust oder ein
fehlgeschlagener Test müssen durch einen hostseitigen Recovery-Mechanismus und
eine dokumentierte manuelle SOP beherrscht werden. Die konkrete Umsetzung kann
beispielsweise einen systemd-gesteuerten Umschaltdienst, einen exklusiven Lock,
Timeouts und einen definierten Rückfall auf Production kombinieren; sie wird
erst in der technischen Spezifikation festgelegt.
Der Testing-Deployment-Account soll Production nicht frei verwalten können. Er
darf lediglich eine eng definierte hostseitige Umschaltoperation starten und
deren Status abfragen. Der Umschaltdienst besitzt die notwendigen Rechte zum
geordneten Stoppen und Wiederanlaufen der beiden Stacks, stellt dem Testing-Job
aber weder Production-Secrets noch allgemeine Production-Verwaltungsrechte zur
Verfügung.
Production und Testing dürfen niemals gleichzeitig als aktiv markiert sein.
Jeder Start prüft den Gegenstatus und bricht bei einem widersprüchlichen oder
unklaren Zustand ab.
### 7.4 Vorgesehene Ansible-Abbildung
Gemeinsame Hostaufgaben und umgebungsspezifische Anwendungsaufgaben werden
getrennt:
```text
ansible/
├── inventories/
│ ├── production/
│ │ ├── hosts.yml
│ │ ├── group_vars/
│ │ └── host_vars/
│ └── testing/
│ ├── hosts.yml
│ ├── group_vars/
│ └── host_vars/
├── playbooks/
│ ├── host.yml
│ ├── environment.yml
│ └── verify.yml
└── roles/
├── host_baseline/
└── environment_stack/
```
Beide Inventare zeigen auf `ghostnet-ki`, enthalten aber ausschließlich die
für ihre Umgebung zulässigen Variablen und Secrets. `host.yml` verwaltet
gemeinsame Pakete, Treiber, Benutzer und Runtime-Komponenten einmalig.
`environment.yml` muss genau eine explizit gewählte Umgebung verwalten und vor
Änderungen prüfen, ob Namen, Pfade, Ports und Zielvariablen zur Auswahl passen.
Hoständerungen dürfen nicht beiläufig durch einen Testing-Lauf erfolgen.
Für den ersten umgesetzten Baseline-Stand gelten getrennte Konfigurationsbäume
unter `/etc/ghostnet-ai/{production,testing}` und getrennte persistente
Datenbäume unter `/var/lib/ghostnet-ai/{production,testing}`. Der Pfad
`/var/lib/ghostnet-ai/shared` ist für später ausdrücklich freigegebene
gemeinsame Daten reserviert. Konkrete Unterverzeichnisse, Eigentümer sowie
Unit- und Container-Namen werden mit den jeweiligen Fachrollen festgelegt.
---
## 8. Vorgesehener Workflow
### 8.1 Änderung und Prüfung
1. Repository klonen und dokumentierte lokale Ansible-Umgebung einrichten.
2. Feature-Branch anlegen.
3. Rollen, Variablen, Templates und zugehörige Dokumentation ändern.
4. lokale Lint-, Syntax- und nach Möglichkeit Check-Mode-Prüfungen ausführen.
5. Pull Request erstellen.
6. automatisierte CI-Prüfungen ohne produktive SSH- oder Vault-Zugangsdaten
ausführen.
7. erste menschliche Prüfung und einen Testing-Lauf für den konkreten Commit
freigeben;
8. Testing-Ergebnis im Pull Request dokumentieren;
9. fachliches Abschlussreview und Freigabe durch eine zweite berechtigte
Person und
10. nach erfolgreichem Statuscheck in den geschützten `main`-Branch mergen.
### 8.2 Testing-Deployment vor dem Merge
Ein Pull Request führt zunächst nur statische CI-Prüfungen in einer isolierten
Jobumgebung ohne SSH-, Vault- oder Serverzugang aus. Nach einer ersten
menschlichen Prüfung kann eine berechtigte Person einen kontrollierten
Testing-Lauf für den konkreten Commit auslösen.
Der Testing-Lauf:
1. verwendet ausschließlich den Testing-Deployment-Account und
Testing-Secrets;
2. erhält erst nach einem freigegebenen Wartungsfenster Zugriff auf den
Umschaltvorgang;
3. fordert über die fest definierte hostseitige Umschaltoperation den
kontrollierten Production-Stopp an und prüft den vollständigen Stillstand;
4. darf im aktiven Testabschnitt nur Testing-Pfade, -Units, -Container und
-Netze verwalten;
5. zeichnet den getesteten Commit unverwechselbar auf;
6. führt technische Health Checks und die für die Änderung notwendigen
Funktionstests aus;
7. veröffentlicht keine Testdienste im Internet;
8. kann die Testing-Daten vor oder nach dem Lauf auf einen bekannten Stand
zurücksetzen und
9. muss Testing stoppen sowie den letzten freigegebenen Production-Stand
wieder starten und prüfen, auch wenn der eigentliche Test fehlschlägt.
Beliebiger Pull-Request-Code darf nicht automatisch mit privilegierten
Serverzugängen ausgeführt werden. Runner-Labels allein gelten nicht als
ausreichende Berechtigungsgrenze. Vor der Implementierung ist zu prüfen, wie
Gitea in der eingesetzten Version Secrets, interne Branches, Forks und manuell
freigegebene Jobs behandelt. Production-Credentials werden keinem
Pull-Request-Workflow bereitgestellt.
### 8.3 Production-Deployment
1. berechtigte Person erzeugt einen geschützten Deployment-Tag auf einem
geprüften Commit;
2. der repository-spezifische Runner übernimmt den Job mit einer Parallelität
von eins;
3. der Job prüft erneut Syntax und Abhängigkeiten;
4. optionaler Check-Modus zeigt erwartete Änderungen, soweit die verwendeten
Module ihn zuverlässig unterstützen;
5. `environment.yml` wendet den Production-Sollzustand auf `ghostnet-ki` an;
6. `verify.yml` prüft Dienste, interne Endpunkte, Containerzustand und später
einen kleinen Inferenztest;
7. der Lauf hält Commit, Imageversionen oder Digests sowie Prüfergebnis fest;
8. erst nach allen Prüfungen gilt das Deployment als erfolgreich.
Ein Production-Deployment verwendet ausschließlich einen Commit aus dem
geschützten `main`-Branch und eine eigene bewusste Freigabe. Ein erfolgreicher
Testing-Lauf ist Voraussetzung für fachlich relevante Änderungen, ersetzt aber
weder Review noch Production-Backup und Freigabe.
Check Mode ist nur eine zusätzliche Kontrolle. Module und Shell-Kommandos, die
keine vollständige Simulation unterstützen, müssen durch gezielte Tests und
idempotente Implementierung abgesichert werden.
---
## 9. Zugangsdaten und Sicherheitsgrenzen
Der Produktionsrunner verarbeitet privilegierte Zugangsdaten und muss daher
wie ein Administrationssystem behandelt werden. Vorgesehen sind:
- repository-spezifische Runner-Registrierung und eindeutiges Runner-Label,
- keine Ausführung fremder oder öffentlicher Repositories,
- ein technischer Zielaccount getrennt von persönlichen Konten und
`ghost-agent`,
- getrennte technische Berechtigungen und Schlüssel für Production und
Testing, soweit dies mit der gewählten Podman-/systemd-Verwaltung belastbar
durchsetzbar ist,
- ein eigener SSH-Schlüssel ausschließlich für das Deployment,
- geprüfter und fest hinterlegter SSH-Host-Key,
- keine Passwort- oder Root-Anmeldung per SSH,
- möglichst eng begrenzter Netzwerkzugang des Runner-LXC,
- keine Secrets in Repository, Jobausgaben oder diff-fähigen Templates,
- `no_log` und deaktivierte Diffs für geheimnishaltige Tasks,
- getrennte Aufbewahrung des Vault-Passworts im Runner und im administrativen
Passwortmanager sowie
- dokumentierte Rotation und Sperrung von Runner-, SSH- und Vault-Zugangsdaten.
Der Testing-Zugang darf keinen Zugriff auf Production-Secrets oder
Production-Daten erhalten. Die Produktionsberechtigung darf nicht allein durch
die Auswahl eines frei benennbaren Runner-Labels erreichbar sein. Das genaue
Verfahren wird nach Prüfung der eingesetzten Gitea-Version festgelegt. Die
notwendige zeitliche Umschaltung wird über eine eng definierte hostseitige
Operation vermittelt und ist keine allgemeine Production-Berechtigung des
Testing-Accounts.
Der Deployment-Account besitzt derzeit bewusst `NOPASSWD: ALL`, weil
Paketverwaltung, systemd, Treiber und rootful Containerverwaltung weitreichende
Rechte erfordern. Eine formal kleine Befehlsliste wäre nur sinnvoll, wenn sie
den tatsächlichen Ansible-Betrieb nicht durch unsichere Umgehungen oder fragile
Sonderfälle ersetzt. Schlüssel, Account und berechtigte Workflows sind deshalb
als root-äquivalente Sicherheitsgrenze zu behandeln. Die spätere Trennung von
Production- und Testing-Berechtigungen bleibt davon unabhängig zu spezifizieren.
---
## 10. Zu erstellende technische Dokumentation und SOPs
Die folgenden Dokumente sind vorgesehen. Titel, Dokumenten-IDs und Zuschnitt
werden bei der Ausarbeitung final festgelegt.
| Arbeitsname | Inhalt | Zielgruppe |
| --- | --- | --- |
| Technische Spezifikation der Ansible-Plattform | Komponenten, Vertrauensgrenzen, Repository-Struktur, Inventar, Rollenmodell, Runner, Netzpfade, Production-/Testing-Isolation, Secret-Konzept, Versionierung und Abnahmekriterien | Infrastrukturadministratoren und Reviewer |
| SOP: Gitea Runner einrichten | LXC-Voraussetzungen, Installation, Registrierung, Labels, Job-Isolation, Netzwerkregeln, Logging, Updates, Backup und Funktionsabnahme | Server Admin |
| SOP: KI-Server für Ansible vorbereiten | Deployment-Account, SSH-Key, Host-Key, `sudo`, Python-Voraussetzungen, Bootstrap und negative Zugriffstests | Server Admin |
| SOP: Lokales Ansible-Environment einrichten | unterstütztes Betriebssystem, Repository-Checkout, Python-/Ansible-Versionen, Collections, Linting, Vault-Zugriff und lokale Prüfkommandos | Mitwirkende und Reviewer |
| SOP: Änderung und Pull Request | Branching, Rollen- und Variablenänderungen, Dokumentationspflicht, lokale Tests, Review und Merge | Mitwirkende |
| SOP: Deployment ausführen und prüfen | Freigabe-Tag, Actions-Lauf, erwartete Prüfungen, Auswertung, Betriebsnachweis und Fehlerbehandlung | Deployment-Berechtigte |
| SOP: Testing-Umgebung verwenden | Teststand und Wartungsfenster auswählen, kontrollierten Lauf freigeben, Production geordnet umschalten, interne Endpunkte verwenden, Testdaten zurücksetzen, Production wiederherstellen und Ergebnisse im Pull Request dokumentieren | Mitwirkende und Reviewer |
| SOP: Rollback und Wiederherstellung | Revert, erneutes Deployment, Image-Rückkehr, Backup/Restore, Datenmigrationen und Abnahmetests | Server Admin |
| SOP: Geheimnisse verwalten | Vault-Dateien, Passwortaufbewahrung, Runner-Secrets, Rotation, Widerruf und Verhalten bei möglicher Offenlegung | Server Admin und Security-Verantwortliche |
Die Nutzer-SOPs sollen konkrete Voraussetzungen, Befehle, erwartete Ergebnisse,
Fehlerfälle und Abnahmekriterien enthalten. Eine Zielbeschreibung allein gilt
nicht als Nachweis einer erfolgreichen Einrichtung.
---
## 11. Vorgesehene Umsetzungsphasen
### Phase A – Ist-Aufnahme und Festlegung
- Gitea-Version, Actions, Runner-Kompatibilität und Registry prüfen;
- vorbereitete Repositories und Zuständigkeiten aufnehmen;
- Runner-LXC, Netzwerkpfad und Ressourcen festlegen;
- Isolation, exklusiven Umschaltmechanismus, Wartungsfenster und interne
Erreichbarkeit von Production und Testing festlegen;
- eingerichteten Deployment-Account in das endgültige Secret-, Rotations- und
Runner-Verfahren überführen;
- Backup- und Restore-Voraussetzungen klären.
### Phase B – Ansible-Grundgerüst
- Repository-Struktur, Inventar und `ansible.cfg` anlegen;
- Werkzeug- und Collection-Versionen festlegen;
- Basisrolle und Verifikationsplaybook entwickeln;
- getrennte Inventare und Variablenvalidierung für Production und Testing
erstellen;
- lokale Entwickler-SOP erstellen und gegen einen frischen Checkout testen.
### Phase C – Gitea-Integration
- Runner-LXC reproduzierbar einrichten und abnehmen;
- Validierungsworkflow ohne Produktionszugang einführen;
- Branch- und Tag-Schutz konfigurieren;
- Deployment-Workflow mit einem ungefährlichen Testplaybook abnehmen;
- Testing-Deployment vor dem Merge und Production-Freigabe nach dem Merge
getrennt abnehmen.
### Phase D – KI-Laufzeit
- Podman und systemd-Integration;
- AMD-GPU-/ROCm- oder alternative Laufzeit nach technischer Prüfung;
- `llama.cpp` und lokaler Funktionstest;
- Wiederanlauf nach geplantem Reboot prüfen.
### Phase E – Anwendungen und Veröffentlichung
- LiteLLM, OpenWebUI und weitere beschlossene Anwendungen;
- persistente Daten, Backups und Restore-Test;
- interne Dienste und NPM-Veröffentlichung getrennt abnehmen;
- Authentifizierung, API-Keys, Health Monitoring und Betriebs-SOPs ergänzen.
---
## 12. Offene Entscheidungen und Nachweise
Vor der technischen Spezifikation sind mindestens folgende Punkte zu klären:
1. Welche Gitea-Version läuft, und sind Actions sowie geschützte Tags in der
eingesetzten Version aktiviert und geeignet?
2. Welche Komponenten werden zunächst ausschließlich als versionierte
Upstream-Artefakte eingebunden, und für welche ist mittelfristig eigener
Quellcode zu erwarten?
3. Wo wird der Runner-LXC betrieben, welche Adresse erhält er, und darf dort
Docker für isolierte Jobs eingesetzt werden?
4. Soll die erste Produktionsfreigabe über einen geschützten Tag oder zunächst
über einen manuell gestarteten Workflow erfolgen?
5. Welche Personen oder Gitea-Teams dürfen reviewen, mergen und Deployments
freigeben?
6. Wie wird der bestehende root-äquivalente Schlüssel von der lokalen
Control-Umgebung auf den späteren Runner überführt beziehungsweise rotiert,
und wie werden Production- und Testing-Berechtigungen dabei getrennt?
7. Wird Ansible Vault verwendet, oder soll ein anderer vorhandener
Secret-Store angebunden werden?
8. Werden eigene Images in der Gitea Registry gebaut, und wie werden
Registry-Credentials und Image-Signaturen behandelt?
9. Welche Backupziele, Aufbewahrungsfristen und nachgewiesenen Restore-Verfahren
gelten für Konfiguration, Modelle und Anwendungsdaten?
10. Welche Versionen und Installationswege werden für AMD-GPU-Laufzeit,
`llama.cpp`, LiteLLM, OpenWebUI und weitere Anwendungen unterstützt?
11. Welche ausgehenden Internetzugriffe erhalten Runner und KI-Server für
Pakete, Collections, Images und Modelle?
12. Welche Health Checks und fachlichen Inferenztests bilden die verbindliche
Abnahme eines Deployments?
13. Welche maximale Dauer, Häufigkeit und Ankündigungsfrist gelten für
Testing-Wartungsfenster, in denen Production nicht verfügbar ist?
14. Welcher hostseitige Lock-, Timeout- und Recovery-Mechanismus stellt den
Wiederanlauf von Production sicher, wenn Runner oder Testing ausfallen?
15. Welche internen Hostnamen und Ports erhält Testing, und welche LAN-/VPN-
Rollen dürfen darauf zugreifen?
16. Können Production und Testing mit getrennten unprivilegierten Accounts
verwaltet werden, oder erfordert die gewählte Podman-/systemd-Architektur
einen stärker privilegierten gemeinsamen Deploymentpfad?
17. Wie wird ein Testing-Deployment eines Pull-Request-Commits in der
eingesetzten Gitea-Version autorisiert, ohne Production-Secrets oder
Production-Runner für veränderbaren PR-Code verfügbar zu machen?
18. Welche Testdaten dürfen verwendet werden, und wie wird ausgeschlossen,
dass personenbezogene oder geheime Production-Daten nach Testing kopiert
werden?
Diese Fragen werden nicht durch Annahmen in Playbooks ersetzt. Entscheidungen
werden zunächst in der technischen Spezifikation dokumentiert und anschließend
in Implementierung und SOPs übernommen.
---
## 13. Referenzstand der Planung
Für die weitere Ausarbeitung wurden am 19.09.2026 insbesondere folgende
Herstellerdokumentationen herangezogen:
- [Gitea Actions – Überblick](https://docs.gitea.com/usage/actions/)
- [Gitea Runner](https://docs.gitea.com/runner/)
- [Gitea Actions – Secrets](https://docs.gitea.com/usage/actions/secrets/)
- [Gitea Actions – Job-Token-Berechtigungen](https://docs.gitea.com/usage/actions/token-permissions/)
- [Gitea – geschützte Tags](https://docs.gitea.com/usage/protected-tags/)
- [Ansible Playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html)
- [Ansible Check- und Diff-Modus](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_checkmode.html)
- [Ansible Vault](https://docs.ansible.com/projects/ansible/latest/vault_guide/vault.html)
Vor der Implementierung sind versionsspezifische Aussagen gegen die dann
tatsächlich eingesetzten Gitea-, Runner- und Ansible-Versionen zu prüfen.
---
## 14. Belegter Ansible-Implementierungsstand
Am 19.09.2026 wurde `ansible-core` 2.21.4 in einer lokalen, von Git
ausgeschlossenen virtuellen Umgebung installiert. Das neue Control-Projekt
enthält:
- `ansible.cfg` mit festem Testing-Inventar, Host-Key-Prüfung und lokalem
Ansible-Arbeitsverzeichnis;
- ein Testing-Inventar für `ghostnet-ki` unter `10.0.0.90` mit dem
unprivilegierten Konto `ghost-agent`;
- ein Preflight-Playbook ohne `become` und ohne konfigurationsändernde Tasks;
- eine kurze Anleitung für Control-Node-Setup, SSH-Agent, Syntaxprüfung und
Live-Lauf.
Inventardarstellung und Syntaxprüfung waren erfolgreich. Der Live-Lauf
bestätigte:
| Merkmal | Ergebnis |
| --- | --- |
| Hostname | `ghostnet-ki` |
| Betriebssystem | Debian 13.6 |
| Standard-IPv4 | `10.0.0.90` |
| CPU | 14 vCPUs |
| RAM | 64.123 MiB |
| Remote-Python | 3.13.5 |
| GPUs | zwei Navi-21-PCI-Geräte `1002:73bf` |
| Play Recap | `ok=5 changed=0 unreachable=0 failed=0` |
Dieser Lauf ist ein Zugriffs- und Identitätsnachweis. Er bestätigt weder ROCm
noch Inferenzfunktion, privilegierte Deploymentrechte, Containerbetrieb oder
die geplante Umschaltung zwischen Production und Testing.
Für den folgenden Bootstrap wurden ein eigener Ed25519-Schlüssel, ein
Account-/sudoers-Playbook und ein getrenntes Prüfplaybook erstellt. Der
öffentliche Schlüssel ist mit Fingerprint
`SHA256:IKEInbIo8VVI1USg5+a3ypGK8H8FweJiQu+v7KvhQDU` versioniert; der private
Schlüssel liegt mit Modus `0600` außerhalb des Repositories. Syntaxprüfung und
Bootstrap-Inventar waren erfolgreich.
Der Bootstrap wurde anschließend über das persönliche Administratorkonto
ausgeführt. Benutzer, Home-/SSH-Verzeichnisse, eingeschränkter Public Key und
die mit `visudo` geprüfte sudoers-Datei wurden erfolgreich angelegt. Die letzte
Assertion des ersten Laufs schlug ausschließlich fehl, weil die nicht vollständig
quotierte Bedingung mit `NOPASSWD: ALL` als YAML-Mapping statt als String
interpretiert wurde. Die Bedingung wurde korrigiert. Das getrennte Prüfplaybook
bestätigte danach die Anmeldung als `ansible-deploy`, normale Modulausführung
und nicht-interaktive Eskalation auf UID 0 mit
`ok=5 changed=0 unreachable=0 failed=0`. Ein vollständiger zweiter
Bootstrap-Lauf zur praktischen Idempotenzprüfung wurde noch nicht ausgeführt.
Als erste gemeinsame Hostrolle wurde anschließend `host_baseline` mit eigenem
Host-Inventar und `playbooks/host.yml` implementiert. Vor Änderungen prüft sie
Hostname, Debian-Hauptversion, Standard-IPv4, die Erkennung des
Root-Dateisystems und mindestens 100 GiB freien Speicher. Sie verwaltet derzeit
ausschließlich folgende root-eigenen Verzeichniswurzeln:
```text
/etc/ghostnet-ai/production
/etc/ghostnet-ai/testing
/var/lib/ghostnet-ai/production
/var/lib/ghostnet-ai/testing
/var/lib/ghostnet-ai/shared
```
Inventar- und Syntaxprüfung waren erfolgreich. Der Check-Modus zeigte nur die
sieben erwarteten Verzeichnisse einschließlich ihrer Eltern als Änderungen und
meldete 1.677,7 GiB freien Platz auf `/`. Der erste reale Lauf endete mit
`ok=6 changed=1 unreachable=0 failed=0`. Der unmittelbar folgende identische
Lauf endete mit `ok=6 changed=0 unreachable=0 failed=0` und belegt die
Idempotenz des aktuellen Rollenumfangs. Es wurden keine Pakete installiert und
keine Dienste, Container oder GPU-Komponenten verändert.
---
## 15. Abschlussgrenze dieses Entwurfs
Mit Version 0.7 sind der aktuelle Planungsstand, der ausdrücklich begrenzte
Ansible-Preflight, der verifizierte Deployment-Account und die angewendete
minimale Host-Baseline persistiert.
Insbesondere wurden noch nicht:
- ein Gitea Runner angelegt,
- Gitea Actions oder Schutzregeln konfiguriert,
- Runtime- oder Anwendungsrollen, ein Production-Inventar oder ein Vault erstellt,
- eine Production- oder Testing-Umgebung eingerichtet oder voneinander
abgenommen,
- Pakete oder Anwendungen auf dem KI-Server installiert,
- Backups oder Rollbacks praktisch getestet oder
- die geplante Deploymentkette technisch abgenommen.
Der nächste Dokumentationsschritt ist die Ist-Aufnahme aus Phase A. Auf deren
Ergebnissen baut die verbindliche technische Spezifikation auf.