CI/CD-Release-Fluss und Feedbackschleifen
Prüfungsbezug: Domain 1.1: CI/CD-Pipelines implementieren. Dazu gehören Stages, Actions, Trigger, Ausführungsverhalten, Gates und Fehlerpfade, die das jeweilige Szenario erfüllen.
Lernziel
Einen Release-Fluss entwerfen, der Entwicklern schnelles Feedback gibt, eine Quellcodeversion und ihre Artefakte eindeutig erhält, objektive Beförderungskriterien verwendet und parallele Ausführungen sowie Fehler bewusst behandelt.
| Schwierigkeitsgrad | Grundlage |
| Lernzeit | 160 Minuten |
| Voraussetzungen | Git, Grundlagen des Softwaretestens und die vorherige Lektion |
Berufliches Szenario
Ein Team führt jede Nacht einen Build und jeden Freitag einen vollständigen Testlauf aus. Integrationsfehler werden mehrere Tage nach dem verantwortlichen Commit entdeckt. Da die Pipeline vier Stunden benötigt, umgehen Notfallkorrekturen den Standardprozess. Außerdem können zwei Releases gleichzeitig in die gemeinsam genutzte Testumgebung gelangen und sich gegenseitig überschreiben.
Das Problem besteht nicht nur in der langsamen Pipeline. Das Feedback kommt zu spät, für die Umgebung gibt es keine Regel für parallele Ausführungen, und das Team unterscheidet nicht zwischen günstigen deterministischen Prüfungen und teuren umgebungsabhängigen Tests.
Das Denkmodell für CodePipeline
Ein AWS-CodePipeline-Design lässt sich leichter beurteilen, wenn jeder Begriff eine eindeutige Bedeutung besitzt.
| Begriff | Bedeutung | Entwurfsfrage |
|---|---|---|
| Quellcodeversion | Der genaue Quellzustand einer Ausführung | Welcher Commit, welches Image oder Objekt startete diesen Lauf? |
| Pipeline-Ausführung | Der Weg einer Quellcodeversion durch den Ablauf | Darf sie eine andere Ausführung überholen oder parallel laufen? |
| Stage | Eine logische Release-Phase, häufig eine Umgebungsgrenze | Was muss gelten, bevor die Version diese Phase verlässt? |
| Action | Eine Arbeitseinheit innerhalb einer Stage | Welche Eingabe verbraucht und welche Ausgabe erzeugt sie? |
| Artefakt | Dateien, die Actions über den Artefaktspeicher austauschen | Erhält Produktion genau die getestete Ausgabe? |
| Trigger | Ereignis oder manueller Aufruf, der eine Ausführung startet | Können doppelte oder unbeabsichtigte Trigger auftreten? |
| Bedingung oder Gate | Nachweis, der vor oder nach einem Stage-Übergang bewertet wird | Ist die Entscheidung objektiv und wiederholbar? |
Eine Stage ist nicht nur eine optische Gruppe in der Konsole. Sie kann eine Umgebung oder eine Release-Grenze darstellen und beeinflusst, wie Ausführungen die Pipeline durchlaufen. Eine Action führt Arbeit aus, etwa Quellcode abrufen, bauen, testen, freigeben oder deployen.
Actions in derselben Stage können parallel laufen, wenn sie denselben runOrder besitzen. Eine höhere runOrder-Zahl wartet auf alle erfolgreichen Actions mit niedrigeren Werten. Parallelität ist nur sinnvoll, wenn die Actions unabhängig sind. Zwei Tests, die dieselbe Datenbank verändern, sind nicht sicher parallel, nur weil die Pipeline es technisch erlaubt.
Artefakte und Quellidentität
Die Source-Action legt die Quellcodeversion der Ausführung fest. Build-Actions verarbeiten ein Source-Artefakt und können eine kompilierte Anwendung, Container-Metadaten, Templates, Testergebnisse oder andere Artefakte erzeugen.
CodePipeline überträgt Artefakte über den S3-Artefaktspeicher. Eine Action sollte nur die benötigten Eingabeartefakte deklarieren und eindeutig benannte Ausgaben erzeugen. So bleibt der Datenfluss sichtbar, und spätere Stages können nicht unbemerkt neu bauen oder eine nicht dokumentierte Version laden.
Beispielhafter Artefaktfluss:
SourceOutput
|
v
CodeBuild -> ApplicationArtifact + TestReports + Manifest
|
v
DeployToTest
|
v
DeployToProduction
Der Testbericht ist ein Nachweis über ApplicationArtifact, aber kein Ersatz für dieses Artefakt. Das Manifest verbindet beide mit Quellcodeversion und Build-Ausführung.
Prüfungen für nützliches Feedback anordnen
Die schnellste Pipeline ist nicht automatisch die beste. Ziel ist eine möglichst kurze Zeit bis zu einem nützlichen und vertrauenswürdigen Ergebnis.
| Prüfung | Typische Position | Begründung |
|---|---|---|
| Formatierung, Lint und Richtlinienprüfung | Ganz am Anfang | Günstig und deterministisch |
| Unit-Tests | Früh | Schnelle Eingrenzung von Codefehlern |
| Statische Sicherheits- und Abhängigkeitsprüfung | Früh oder parallel zu Unit-Tests | Stoppt bekannte Richtlinienverletzungen vor dem Deployment |
| Build und Paketierung | Vor Umgebungstests | Erzeugt das Release-Artefakt |
| Integrationstests | Nach Deployment in eine isolierte Umgebung | Benötigt echte Dienstinteraktionen |
| Akzeptanz- und synthetische Tests | Vor Produktionsbeförderung | Prüft sichtbares Nutzerverhalten |
| Last- oder Resilienztests | Eigene Stage oder geplanter Ablauf | Teuer und möglicherweise störend für geteilte Umgebungen |
| Zustandsprüfung zur Laufzeit | Während und nach dem Deployment | Findet Fehler, die Vorabtests übersehen haben |
Parallele Actions verkürzen die Laufzeit nur, wenn sie nicht um denselben Zustand konkurrieren und den ersten nützlichen Fehler nicht verbergen. Ein zehnminütiger Unit-Test und ein zehnminütiger statischer Scan können parallel laufen. Zwei Migrationstests mit demselben Datenbankschema benötigen isolierte Datenbanken oder eine serielle Ausführung.
Objektive Gates und menschliche Entscheidungen
Ein Gate ist objektiv, wenn eine andere Person dieselben Nachweise auswerten und zum gleichen Ergebnis kommen kann.
Beispiele für objektive Gates:
- alle Pflichtprüfungen waren erfolgreich
- die vereinbarte Testabdeckung wurde nicht unterschritten
- es existiert keine Schwachstelle oberhalb der akzeptierten Schwere
- das Artefakt ist signiert und sein Digest stimmt mit dem Manifest überein
- der Deployment-Alarm blieb während des Beobachtungszeitraums gesund
Eine manuelle Freigabe ist sinnvoll, wenn tatsächlich Urteilsvermögen oder persönliche Verantwortlichkeit erforderlich ist, zum Beispiel bei einer geplanten geschäftlichen Release-Entscheidung. Sie ist schwach, wenn eine Person deterministische Daten prüfen soll, die die Pipeline automatisch auswerten könnte.
Eine Freigabe benötigt außerdem Kontext: Quellcodeversion, Artefaktversion, geänderte Komponenten, Testnachweise, Risiko, Rollback-Plan und Ablaufzeit. „Build 483 freigeben?“ reicht für eine professionelle Entscheidung nicht aus.
Ausführungsmodi und überlappende Änderungen
CodePipeline bietet verschiedene Verhaltensweisen für mehrere Ausführungen:
| Modus | Verhalten | Geeignet, wenn | Wichtiger Trade-off |
|---|---|---|---|
SUPERSEDED | Eine neuere Ausführung kann eine ältere überholen | Nur die neueste Version soll fortfahren | Ältere Arbeit wird möglicherweise nicht beendet |
QUEUED | Ausführungen durchlaufen die Pipeline nacheinander | Eine geteilte Umgebung muss Änderungen in Reihenfolge verarbeiten | Feedback kann in der Warteschlange warten |
PARALLEL | Ausführungen laufen gleichzeitig und unabhängig | Umgebung und Zustand sind pro Ausführung isoliert | Stage-Rollback ist im Parallelmodus nicht verfügbar |
Parallele Pipeline-Ausführungen sind nicht dasselbe wie parallele Actions in einer Stage. Der Ausführungsmodus steuert überlappende Quellcodeversionen; runOrder steuert die Reihenfolge von Actions für eine Version.
Durchgängiges Release-Beispiel
Für einen Webservice mit Entwicklungs-, Test- und Produktionskonten:
- Source-Stage: Ein geprüfter Merge startet eine Ausführung und speichert die Commit-ID.
- Validierungs-Stage: Lint, Unit-Tests, Template-Validierung und Abhängigkeitsprüfung laufen parallel, soweit sie unabhängig sind.
- Build-Stage: CodeBuild erzeugt ein Artefakt, dessen Digest, bei Bedarf eine Software-Stückliste und Testberichte.
- Test-Deployment-Stage: Das Artefakt wird in eine isolierte Testumgebung deployt.
- Akzeptanz-Stage: API-, Integrations- und synthetische Tests prüfen die deployte Version.
- Produktionsentscheidung: Objektive Nachweise werden ausgewertet; eine dokumentierte Freigabe wird nur ergänzt, wenn der Geschäftsprozess eine Ermessensentscheidung verlangt.
- Produktions-Deployment: Der Datenverkehr wird schrittweise verlagert und Alarme werden beobachtet.
- Ergebnis: Gesunder Datenverkehr beendet die Beförderung. Ein Alarm stoppt die Verlagerung und startet die festgelegte Wiederherstellung.
Jeder Fehler sollte eine verantwortliche Person mit Ausführungs-ID, Quellcodeversion, fehlgeschlagener Action, erstem relevanten Fehler und Verweis auf die Nachweise benachrichtigen. Die Nachricht „Pipeline fehlgeschlagen“ erzeugt nur einen weiteren Untersuchungsschritt.
Architekturablauf
Source
|
v
Schnelle Validierung ------------------+
| |
+--> Unit-Tests |
+--> statische und Policy-Prüfungen | gleiche Quellcodeversion
+--> Template-Validierung |
| |
v |
Unveränderliches Artefakt bauen <------+
|
v
In Test deployen -> Integrationstests -> Beförderungs-Gate
|
v
Schrittweiser Produktionsrelease
| |
gesund Alarm
| |
abschließen stoppen oder Rollback
Entscheidungsmatrix
| Anforderung | Bevorzugte Richtung | Begründung |
|---|---|---|
| Schnelles Entwicklerfeedback | Günstige deterministische Prüfungen zuerst | Fehler kehren vor teurer Arbeit zurück |
| Unabhängige Prüfungen | Parallele Actions in derselben Stage | Verkürzt die Laufzeit ohne Nachweise zu verändern |
| Geteilte Testumgebung | Deployments in Warteschlange oder anderweitig serialisieren | Verhindert Zustandskonflikte |
| Temporäre Umgebung pro Änderung | Parallele Ausführungen können passen | Jede Version besitzt isolierten Zustand |
| Riskanter Produktionsrelease | Schrittweises Deployment mit Laufzeitalarmen | Begrenzt den Blast Radius |
| Deterministische Compliance-Regel | Automatisches Gate | Wiederholbar und auditierbar |
| Geschäftliche Ermessensentscheidung | Dokumentierte Freigabe mit Kontext | Erhält verantwortliche Entscheidungsfindung |
Fehlerbilder und Fehlersuche
| Symptom | Erste Frage | Wahrscheinlicher Bereich |
|---|---|---|
| Pipeline startete nicht | Wurde das erwartete Source-Ereignis erzeugt und erkannt? | Trigger, Verbindung oder EventBridge-Regel |
| Action findet Eingabe nicht | Hat die vorherige Action den erwarteten Ausgabenamen deklariert? | Artefaktdeklaration |
| Test lokal erfolgreich, in Pipeline fehlerhaft | Sind Laufzeit, Abhängigkeiten, IAM, Netzwerk und Umgebungsvariablen identisch? | Build-Umgebung oder Konfiguration |
| Neue Ausführung überholt alte | Welcher Ausführungsmodus ist eingestellt? | Pipeline-Flusssteuerung |
| Freigabe wartet unbegrenzt | Wurde Kontext geliefert und ist die Action abgelaufen? | Freigabebenachrichtigung und Verantwortung |
| Deployment erfolgreich, Service fehlerhaft | Welche technischen oder fachlichen Zustandssignale wurden ausgewertet? | Prüfung nach dem Deployment |
| Wiederholung scheitert oder ist nicht verfügbar | Wurde die Ausführung überholt oder unterstützt der Modus keinen Rollback? | Ausführungszustand und Modus |
Beginne die Fehlersuche an der ersten fehlerhaften Grenze und nicht beim letzten Symptom. Verfolge der Reihe nach Ausführungs-ID, Quellcodeversion, Eingabeartefakt, Action-Rolle, Dienstereignis und Ausgabeartefakt.
Sicherheit und Betrieb
- Der Pipeline-Service-Rolle nur erforderliche Orchestrierungsrechte geben.
- Getrennte Action- oder Deployment-Rollen verwenden, wenn Aufgaben oder Konten getrennt sind.
- Artefaktspeicher verschlüsseln und Lese-, Schreib- sowie Löschrechte begrenzen.
- Zugangsdaten nicht in Action-Konfiguration speichern; Secrets zur Ausführungszeit über einen unterstützten sicheren Mechanismus laden.
- Testdaten mit derselben Klassifizierungsdisziplin wie Produktionsdaten behandeln.
- Action-, Freigabe- und Deployment-Nachweise entsprechend den Audit-Anforderungen aufbewahren.
- Auch Pipeline-Inaktivität überwachen; eine Pipeline, die nie startet, kann unbemerkt defekt sein.
Praxislabor: Release-Fluss für drei Umgebungen
Ziel: Eine Spezifikation erstellen, die eine andere Person ohne Vermutungen implementieren kann.
Aufgaben
- Ein Source-Ereignis auswählen und den genauen Bezeichner der Quellcodeversion definieren.
- Jede Prüfung mit Dauer, Abhängigkeiten, Ausgabe und verantwortlicher Person auflisten.
- Prüfungen nach Feedbackwert, Geschwindigkeit und Risiko anordnen.
- Actions markieren, die sicher dieselbe
runOrderverwenden können, und dies begründen. - Artefaktnamen sowie Produzent und Verbraucher jedes Artefakts definieren.
- Einen Ausführungsmodus für die geteilte Testumgebung wählen und begründen.
- Eintritts- und Austrittskriterien für jede Stage formulieren.
- Nachweise für eine Produktionsfreigabe definieren, falls sie erforderlich ist.
- Einen Laufzeitalarm und das genaue Stopp- oder Rollback-Verhalten festlegen.
- Benachrichtigungen für Triggerfehler, Action-Fehler, Freigabe-Timeout, Deployment-Alarm und erfolgreiche Wiederherstellung entwerfen.
Validierungscheckliste
- Jede Stage besitzt objektive Austrittskriterien.
- Jedes Artefakt hat einen eindeutigen Produzenten und mindestens einen vorgesehenen Verbraucher.
- Das Produktionsartefakt wird nicht neu gebaut.
- Parallele Arbeit teilt keinen veränderlichen Zustand oder isoliert ihn.
- Für überlappende Ausführungen existiert eine ausdrückliche Regel.
- Ein Pflichtfehler blockiert spätere Stages.
- Benachrichtigungen nennen Version, Ausführung, fehlerhafte Grenze und verantwortliche Person.
Kostenkontrolle: Für das Design sind keine Cloud-Ressourcen nötig. Als günstige Erweiterung können Source- und Validierungs-Stage in einer Sandbox implementiert werden.
Aufräumen
Bei der optionalen Implementierung Test-Pipelines, Artefakt-Buckets, Rollen, Ereignisregeln, Build-Projekte und Logs entfernen, nachdem geprüft wurde, dass keine gemeinsame Ressource davon abhängt.
Prüfungsfallen
- Annehmen, jede Pipeline müsse streng sequenziell sein.
- Parallele Actions und parallele Pipeline-Ausführungen verwechseln.
PARALLELwählen, obwohl Stage-Rollback erforderlich ist.- Manuelle Freigabe für eine deterministische Richtlinienregel verwenden.
- Teure Tests vor günstigen Prüfungen ausführen.
- Das Artefakt nach der Freigabe neu bauen.
- Eine Freigabe ohne Nachweise als starke Kontrolle betrachten.
Wichtigste Erkenntnisse
- Eine Pipeline bewegt eine identifizierte Quellcodeversion und ihre Artefakte durch kontrollierte Grenzen.
- Schnelles deterministisches Feedback gehört nach vorn; nur unabhängige Arbeit wird parallelisiert.
- Das Ausführungsverhalten folgt den Einschränkungen von Umgebung und Zustand.
- Gates benötigen objektive Nachweise; Freigaben benötigen Entscheidungskontext.
- Trigger-, Erfolgs-, Fehler-, Timeout- und Wiederherstellungspfade müssen modelliert werden.
Wiederholungsfragen
- Was unterscheidet eine Stage von einer Action?
- Wie beeinflusst
runOrderdie Actions einer Stage? - Was unterscheidet parallele Actions vom Ausführungsmodus
PARALLEL? - Wann ist
QUEUEDbesser alsSUPERSEDED? - Warum müssen Testberichte das geprüfte Artefakt eindeutig identifizieren?
- Was macht ein Beförderungs-Gate objektiv?
- Warum reicht ein erfolgreicher Deployment-Status nicht für die Produktionsbeförderung?
- Welche Angaben enthält eine nützliche Fehlerbenachrichtigung?
Modellantworten
- Eine Stage ist eine logische Release- oder Umgebungsgrenze. Eine Action ist eine Arbeitseinheit innerhalb einer Stage, die Eingaben verarbeitet und Ausgaben erzeugen kann.
- Actions mit derselben
runOrderkönnen parallel laufen. Eine höhere Reihenfolge wartet, bis alle Pflicht-Actions niedrigerer Reihenfolgen erfolgreich waren. - Parallele Actions bearbeiten unabhängige Aufgaben für eine Pipeline-Version. Der Modus
PARALLELerlaubt mehreren Pipeline-Versionen, gleichzeitig und unabhängig zu laufen. QUEUEDpasst, wenn Versionen eine geteilte Umgebung einzeln und in Reihenfolge betreten müssen.SUPERSEDEDpasst, wenn nur die neueste Version fortfahren soll.- Ohne diese Verbindung könnten die Nachweise einen anderen Build beschreiben. Version, Digest und Build-Identität erhalten die Herkunft.
- Es verwendet messbare Nachweise und eine wiederholbare Regel, die bei gleichen Eingaben dasselbe Ergebnis liefert.
- Der Status beweist, dass der Deployment-Dienst seine Operation abgeschlossen hat, aber nicht, dass Abhängigkeiten, Kundenerlebnis, Latenz oder fachliche Transaktionen gesund sind.
- Mindestens Quellcodeversion, Ausführungs-ID, fehlerhafte Stage und Action, erster relevanter Fehler, Verweis auf Nachweise, Umgebung und verantwortliche Person.