Abschnitt 1: Das Modell verstehen
Für Engineering-Leads und Entscheidungsträger: Konzept, Anwendungsfälle und Architekturprinzipien. Konfigurationsdetails folgen in Abschnitt 2.
Die meisten CI/CD-Werkzeuge können einen Build ausführen und ein Deployment anstoßen. Der Unterschied zeigt sich erst dann, wenn die Delivery-Anforderungen komplexer werden: ein Monorepo mit einem Dutzend Services, Microservices über mehrere Repositories verteilt, Deployments in Dutzende von Umgebungen gleichzeitig – oder ein Platform-Team, das organisationsweite Standards durchsetzen will, ohne dabei zum Engpass zu werden.
GitLabs Pipeline-Modell wurde für genau diese Komplexität entwickelt. Parent-Child-Pipelines, DAG-Execution, dynamische Pipeline-Generierung, Multi-Project-Trigger, Merge-Request-Pipelines mit Merged-Results-Verarbeitung und CI/CD Components lösen jeweils eine eigene Klasse von Problemen. Da sich diese Bausteine kombinieren lassen, erschließt das vollständige Modell mehr als nur kürzere Pipeline-Laufzeiten.
Dieser Artikel beschreibt die fünf Muster, bei denen das Modell seine Stärken deutlich zeigt – jeweils zugeordnet zu einem konkreten Engineering-Szenario. Konfigurationen und Implementierungsdetails folgen in Abschnitt 2.
1. Monorepos: Parent-Child-Pipelines und DAG-Execution
Das Problem: Ein Monorepo enthält Frontend, Backend und Dokumentation. Jeder Commit löst einen vollständigen Rebuild aller Komponenten aus – auch wenn sich nur eine README-Datei geändert hat.
GitLab kombiniert zwei sich ergänzende Mechanismen: Parent-Child-Pipelines ermöglichen es einer übergeordneten Pipeline, isolierte Child-Pipelines zu starten. DAG-Execution via needs bricht die starre Stage-Reihenfolge auf und startet Jobs, sobald ihre Abhängigkeiten abgeschlossen sind – nicht erst, wenn alle Jobs einer Stage fertig sind.
Eine Parent-Pipeline erkennt, welche Teile des Repos sich geändert haben, und löst ausschließlich die betroffenen Child-Pipelines aus. Jeder Service verwaltet seine eigene Pipeline-Konfiguration; Änderungen in einem Service können keine anderen beeinflussen. Damit bleibt die Komplexität beherrschbar, während das Repository und das Team wachsen.
Einen technischen Aspekt gilt es dabei zu kennen: Wenn mehrere Dateien an einen einzelnen trigger: include:-Block übergeben werden, fusioniert GitLab sie zu einer einzigen Child-Pipeline-Konfiguration. Jobs aus diesen Dateien teilen denselben Pipeline-Kontext und können sich gegenseitig per needs: referenzieren – das ist die Voraussetzung für die DAG-Optimierung. Werden die Dateien stattdessen auf separate Trigger-Jobs aufgeteilt, entsteht jeweils eine isolierte Pipeline, und dateiübergreifende needs:-Referenzen funktionieren nicht.
In großen Monorepos lassen sich Pipeline-Laufzeiten durch DAG-Execution deutlich reduzieren, da Jobs nicht mehr auf unabhängige Arbeitsschritte in derselben Stage warten.
2. Microservices: Cross-Repo-Pipelines über mehrere Projekte
Das Problem: Frontend und Backend leben in separaten Repositories. Wenn das Frontend-Team eine Änderung ausliefert, ist nicht erkennbar, ob sie die Backend-Integration beeinträchtigt – und umgekehrt.
Multi-Project-Pipelines ermöglichen es, aus einem Projekt heraus eine Pipeline in einem anderen Projekt auszulösen und auf das Ergebnis zu warten. Das auslösende Projekt sieht die verknüpfte Downstream-Pipeline direkt in seiner eigenen Pipeline-Ansicht.
In der Praxis erstellt die Frontend-Pipeline ein API-Contract-Artifact und veröffentlicht es, bevor die Backend-Pipeline ausgelöst wird. Das Backend ruft dieses Artifact über die Jobs API ab und validiert es, bevor weitere Schritte erlaubt sind. Wird eine Breaking Change erkannt, schlägt die Backend-Pipeline fehl – und mit ihr die Frontend-Pipeline. Probleme, die bisher erst in der Produktion sichtbar wurden, werden damit im Pipeline-Prozess abgefangen. Die Abhängigkeit zwischen Services wird sichtbar, nachvollziehbar und aktiv verwaltbar.
Cross-project pipelines Cross-project pipelines
3. Multi-Tenant/Matrix-Deployments: Dynamische Child-Pipelines
Das Problem: Dieselbe Anwendung wird in 15 Kundenumgebungen, drei Cloud-Regionen oder den Stages Dev/Staging/Prod deployed. Manuelle Anpassungen je Umgebung führen zu Konfigurationsdrift. Eine separate Pipeline pro Umgebung ist von Anfang an nicht wartbar.
Dynamische Child-Pipelines generieren die Pipeline-Struktur zur Laufzeit. Ein Job führt ein Skript aus, das eine YAML-Datei erzeugt – und diese YAML-Datei wird zur Pipeline für den nächsten Schritt. Die Pipeline-Struktur selbst wird damit zu Daten.
Das Generierungsskript iteriert über eine ENVIRONMENTS-Variable, statt jede Umgebung fest zu kodieren. Eine neue Umgebung lässt sich durch Anpassen der Variable hinzufügen – ohne Änderungen an der Pipeline-Konfiguration selbst. Trigger-Jobs erben mit extends: eine gemeinsame Template-Konfiguration, sodass strategy: depend einmal definiert und nicht für jeden Trigger-Job wiederholt wird. Ein when: manual-Gate für das Produktions-Deployment ist direkt in den Pipeline-Graph integriert.
Platform-Teams nutzen dieses Muster, um Dutzende von Umgebungen zu verwalten, ohne Pipeline-Logik zu duplizieren.
Dynamic pipeline
4. MR-First-Delivery: Merge-Request-Pipelines, Merged-Results und Workflow-Routing
Das Problem: Die Pipeline läuft bei jedem Push auf jeden Branch. Aufwändige Tests werden auf Feature-Branches ausgeführt, die nie gemergt werden. Gleichzeitig gibt es keine Garantie, dass das Getestete dem entspricht, was nach dem Merge auf main tatsächlich landet.
GitLab kombiniert drei ineinandergreifende Mechanismen: Merge-Request-Pipelines laufen ausschließlich dann, wenn ein Merge Request existiert – nicht bei jedem Branch-Push. Allein dadurch entfällt ein erheblicher Anteil unnötiger Compute-Ausführungen. Merged-Results-Pipelines gehen einen Schritt weiter: GitLab erstellt einen temporären Merge-Commit aus dem Branch und dem aktuellen Ziel-Branch und führt die Pipeline dagegen aus. Getestet wird damit das tatsächliche Ergebnis des Merges – nicht der Branch in Isolation. Workflow-Rules definieren schließlich, welcher Pipeline-Typ unter welchen Bedingungen ausgeführt wird. Die $CI_OPEN_MERGE_REQUESTS-Guard verhindert dabei, dass für einen Branch mit offenem MR doppelte Pipelines ausgelöst werden.
Das Ergebnis ist ein Pipeline-Verhalten, das sich je nach Kontext unterscheidet: Ein Push auf einen Feature-Branch ohne offenen MR führt nur Lint und Unit-Tests aus. Sobald ein MR geöffnet wird, wechseln die Workflow-Rules auf eine MR-Pipeline mit der vollständigen Test-Suite gegen das Merged-Result. Ein Merge auf main stellt ein manuelles Produktions-Deployment in die Warteschlange. Der Nightly-Scan läuft einmalig als geplante Pipeline – nicht bei jedem Commit.
Merged-Results-Pipelines fangen dabei die Klasse von Fehlern ab, die erst nach einem Merge sichtbar werden – bevor sie main erreichen.
5. Governed Pipelines: CI/CD Components
Das Problem: Das Platform-Team hat den richtigen Weg für Build, Test und Deploy definiert. Jedes Anwendungsteam pflegt jedoch eine eigene .gitlab-ci.yml mit subtilen Abweichungen. Security-Scanning wird übersprungen. Deployment-Standards driften. Audits werden aufwändig.
CI/CD Components ermöglichen es Platform-Teams, versionierte, wiederverwendbare Pipeline-Bausteine zu veröffentlichen. Anwendungsteams binden sie mit einer einzigen include:-Zeile ein – kein Copy-Paste, kein Drift. Components sind über den CI/CD Catalog auffindbar, sodass Teams bewährte Bausteine finden und übernehmen können, ohne das Platform-Team direkt einschalten zu müssen.
Drei Zeilen include: ersetzen hunderte von duplizierten YAML-Zeilen. Das Platform-Team kann einen Security-Fix in einer neuen Komponentenversion veröffentlichen – Teams steigen auf ihrem eigenen Zeitplan um, oder das Platform-Team fixiert alle auf eine Mindestversion. In beiden Fällen propagiert eine Änderung organisationsweit, statt repo-für-repo angewendet zu werden.
Kombiniert mit Resource Groups zur Vermeidung konkurrierender Deployments und Protected Environments für Freigabe-Gates entsteht eine governed Delivery-Plattform, auf der Compliance der Standard ist, nicht die Ausnahme. Platform-Teams setzen Vorgaben durch, ohne zum Engpass zu werden.
Component pipeline (imported jobs)
Das Modell als Ganzes
Keines dieser Muster existiert isoliert. Der Wert von GitLabs Pipeline-Modell liegt in der Kombinierbarkeit seiner Bausteine:
- Ein Monorepo nutzt Parent-Child-Pipelines, und jede Child-Pipeline nutzt DAG-Execution.
- Eine Microservices-Plattform nutzt Multi-Project-Pipelines, und jedes Projekt nutzt MR-Pipelines mit Merged-Results.
- Eine governed Plattform nutzt CI/CD Components, um die obigen Muster organisationsweit zu standardisieren.
Die meisten Teams entdecken eines dieser Muster, wenn sie auf ein konkretes Problem stoßen. Teams, die das vollständige Modell verstehen, entwickeln daraus eine Delivery-Infrastruktur, die tatsächlich abbildet, wie ihre Engineering-Organisation arbeitet – und mit ihr wächst.
Weitere Muster
Das Pipeline-Modell geht über die fünf vorgestellten Muster hinaus:
- Review Apps mit dynamischen Umgebungen erstellen für jeden Feature-Branch eine Live-Vorschau und räumen sie automatisch auf, wenn der MR geschlossen wird.
- Caching- und Artifact-Strategien sind nach der strukturellen Arbeit häufig der direkteste Weg zur weiteren Laufzeitoptimierung – ohne die Pipeline-Struktur zu verändern.
- Geplante und API-ausgelöste Pipelines eignen sich für Workloads, die nicht bei jedem Code-Push laufen sollten: Nightly-Security-Scans, Compliance-Reports und Release-Automatisierung lassen sich als geplante oder API-ausgelöste Pipelines mit
$CI_PIPELINE_SOURCE-Routing modellieren.
GitLab Ultimate kostenlos testen und Pipeline-Logik ab heute einsetzen.
Für deutsche Unternehmen: Regulatorischer Kontext
Teams, die Pipeline-Governance nach Muster 5 einführen, adressieren dabei möglicherweise auch Anforderungen, die regulatorische Frameworks an sichere Softwareentwicklungsprozesse stellen.
CI/CD Components mit erzwungenen Security-Gates könnten Anforderungen an sichere Entwicklungsprozesse betreffen – beispielsweise in Bereichen, die Frameworks wie NIS2, ISO 27001 oder BSI IT-Grundschutz an den Software-Entwicklungslebenszyklus adressieren. Protected Environments und Resource Groups betreffen ähnliche Themen im Bereich Änderungskontrolle und Umgebungstrennung, wie sie in Governance-Frameworks typischerweise explizit formuliert sind.
Multi-Project-Pipelines mit API-Contract-Validierung (Muster 2) schaffen Sichtbarkeit über Service-Abhängigkeiten hinweg – ein Aspekt, den Frameworks zur Lieferkettensicherheit adressieren.
Merged-Results-Pipelines (Muster 4) dokumentieren automatisch, dass das tatsächliche Merge-Ergebnis getestet wurde, nicht nur der Feature-Branch in Isolation. Dies könnte Anforderungen an nachvollziehbare Änderungsprozesse betreffen, wie sie in Change-Management-Kontrollen verschiedener Sicherheitsframeworks formuliert sind.
Für konkrete Compliance-Anforderungen im eigenen regulatorischen Umfeld empfiehlt sich Rücksprache mit entsprechender Fachberatung.
Abschnitt 2: Konfiguration und Implementierung
Für Entwicklungsteams und DevOps-Praktiker: ausgewählte Konfigurationsbeispiele zu den Mustern 1, 4 und 5. Für vollständige Konfigurationen aller Muster: englischer Originalartikel.
Die folgenden Konfigurationen sind illustrativ aufgebaut. Die Skripte verwenden echo-Befehle, um das Wesentliche sichtbar zu halten. Für den produktiven Einsatz werden die echo-Befehle durch die tatsächlichen Build-, Test- und Deploy-Schritte ersetzt.
Muster 1: Parent-Child-Pipelines und DAG-Execution
Eine Parent-Pipeline erkennt Änderungen und löst nur die betroffenen Child-Pipelines aus:
- trigger
trigger-services:
stage: trigger
trigger:
include:
- local: '.gitlab/ci/api-service.yml'
- local: '.gitlab/ci/web-service.yml'
- local: '.gitlab/ci/worker-service.yml'
strategy: depend
Innerhalb der Child-Pipeline ermöglicht needs: DAG-Execution – der Test startet, sobald der Build abgeschlossen ist, ohne auf andere Jobs in derselben Stage zu warten:
- build
- test
build-api:
stage: build
script:
- echo "Building API service"
test-api:
stage: test
needs: [build-api]
script:
- echo "Running API tests"
Local downstream pipelines
Muster 4: MR-First-Delivery
Workflow-Rules, MR-Pipelines und Merged-Results zusammen ergeben ein kontextabhängiges Pipeline-Verhalten:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
- if: $CI_PIPELINE_SOURCE == "schedule"
stages:
- fast-checks
- expensive-tests
- deploy
lint-code:
stage: fast-checks
script:
- echo "Running linter"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
unit-tests:
stage: fast-checks
script:
- echo "Running unit tests"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
integration-tests:
stage: expensive-tests
script:
- echo "Running integration tests (15 min)"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
e2e-tests:
stage: expensive-tests
script:
- echo "Running E2E tests (30 min)"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
nightly-comprehensive-scan:
stage: expensive-tests
script:
- echo "Running full nightly suite (2 hours)"
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
deploy-production:
stage: deploy
script:
- echo "Deploying to production"
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
Conditional pipelines (within a branch with no MR)
Conditional pipelines (within an MR)
Conditional pipelines (on the main branch)
Muster 5: CI/CD Components
Eine Komponentendefinition aus einer gemeinsamen Bibliothek:
inputs:
stage:
default: deploy
environment:
default: production
--- deploy-job:
stage: $[[ inputs.stage ]]
script:
- echo "Deploying $APP_NAME to $[[ inputs.environment ]]"
- echo "Deploy URL: $DEPLOY_URL"
environment:
name: $[[ inputs.environment ]]
So bindet ein Anwendungsteam die Komponenten ein:
APP_NAME: "my-awesome-app"
DEPLOY_URL: "https://api.example.com"
include:
- component: gitlab.com/my-org/component-library/[email protected]
- component: gitlab.com/my-org/component-library/[email protected]
- component: gitlab.com/my-org/component-library/[email protected]
inputs:
environment: staging
stages:
- build
- test
- deploy
Orientierung zu den Mustern 2 und 3
Muster 2 (Multi-Project-Pipelines): Das Frontend-Repository publiziert ein API-Contract-Artifact und löst anschließend die Backend-Pipeline aus. Das Backend ruft das Artifact über die GitLab Jobs API ab und validiert es. Der integration-test-Job läuft dabei nur dann, wenn er von einer Upstream-Pipeline ausgelöst wurde ($CI_PIPELINE_SOURCE == "pipeline"), nicht bei einem eigenständigen Push. Die Frontend-Projekt-ID wird als CI/CD-Variable gesetzt, um Hardcoding zu vermeiden. Vollständige Konfigurationen beider Repositories: englischer Originalartikel.
Muster 3 (Dynamische Child-Pipelines): Ein generate-config-Job erzeugt zur Laufzeit environment-spezifische YAML-Dateien. Trigger-Jobs nutzen extends: für gemeinsam genutzte Konfiguration und needs: für sequenzielle Promotion (dev → staging → prod mit manuellem Gate). Vollständige Konfiguration: englischer Originalartikel.
Weiterführende Artikel
- Variable and artifact sharing in GitLab parent-child pipelines
- CI/CD inputs: Secure and preferred method to pass parameters to a pipeline
- Tutorial: How to set up your first GitLab CI/CD component
- How to include file references in your CI/CD components
- FAQ: GitLab CI/CD Catalog
- Building a GitLab CI/CD pipeline for a monorepo the easy way
- A CI/CD component builder's journey
- CI/CD Catalog goes GA: No more building pipelines from scratch




