Veröffentlicht am: 6. Juli 2026
13 Minuten Lesezeit
Wie CI/CD Inputs Parameter typsicher und validiert übergeben und fehleranfällige Variablen ersetzen – für verlässlichere, wartbarere Pipelines.

GitLab CI/CD Inputs sind eine gezielt entwickelte Methode zur Parameterübergabe in Pipelines. Als Funktion, die speziell für typisierte Parameter mit Validierung, klaren Verträgen und kontrollierter Übergabe konzipiert wurde, lösen Inputs die Probleme, um die Teams jahrelang mit Variablen herumarbeiten mussten.
CI/CD-Variablen dienten lange als Standardweg, um Parameter an Pipelines zu übergeben. Ursprünglich waren sie jedoch für das Speichern von Konfigurationswerten gedacht – nicht als ausgefeilter Mechanismus zur Parameterübergabe in komplexen Abläufen. Aus dieser Diskrepanz entstanden Zuverlässigkeitsprobleme, Sicherheitsbedenken und zusätzlicher Wartungsaufwand, die sich mit Inputs vermeiden lassen.
Dieser Artikel zeigt, warum sich CI/CD Inputs als bevorzugter Ansatz für Pipeline-Parameter eignen. Dabei wird deutlich, wie Inputs Typsicherheit schaffen, häufige Pipeline-Fehler verhindern, Namenskollisionen bei Variablen ausschließen und die Automatisierung wartbarer machen. Praktische Beispiele zeigen Inputs im Einsatz und wie sie konkrete Probleme lösen – als Anstoß, von variablenbasierten Behelfslösungen zur verlässlicheren Arbeit mit Inputs zu wechseln.
Inputs bieten typisierte Parameter für wiederverwendbare Pipeline-Konfigurationen, mit eingebauter Validierung bei der Pipeline-Erstellung. Sie schaffen einen klaren Vertrag zwischen der einbindenden Pipeline und der Konfiguration und legen ausdrücklich fest, welche Parameter erwartet werden, welchen Typ sie haben und welchen Einschränkungen sie unterliegen.
Damit die Vorteile von Inputs greifbar werden, lohnt ein Blick auf die Schwächen, die der variablenbasierte Ansatz mitbringt – und die Inputs gezielt beheben.
Variablen für die Parameterübergabe zu nutzen, bringt zahlreiche und mühsame Probleme mit sich.
Keine Typvalidierung
Variablen sind Zeichenketten. Es gibt keine Typvalidierung: Eine Pipeline erwartet etwa einen Boolean oder eine Zahl, erhält aber versehentlich eine Zeichenkette. Das führt zu unerwarteten Fehlern tief im Pipeline-Ablauf. Bei einem Deployment-Workflow etwa schlägt eine kritische Produktivbereitstellung fehl, weil eine Boolean-Prüfung einen Wert nicht wie erwartet erhält – und das erst weit fortgeschritten im Ablauf.
Veränderbarkeit zur Laufzeit
Variablen lassen sich während der gesamten Pipeline-Laufzeit ändern. Das erzeugt unvorhersehbares Verhalten, wenn mehrere Jobs denselben Wert zu ändern versuchen. Ein Beispiel: deploy_job_a setzt DEPLOY_ENV=staging, doch deploy_job_b ändert den Wert von DEPLOY_ENV auf production.
Sicherheitsrisiken
Sicherheitsbedenken entstehen, weil Variablen, die als einfache Parameter gedacht sind, oft dieselben Zugriffsrechte erhalten wie sensible Secrets. Es fehlt ein klarer Vertrag, der festlegt, welche Parameter eine Pipeline erwartet, welchen Typ sie haben und welche Standardwerte gelten. Ein scheinbar harmloser Parameter wie BUILD_TYPE erhält damit plötzlich Zugriff auf Produktions-Secrets – schlicht, weil Variablen von sich aus nicht zwischen Parametern und sensiblen Daten unterscheiden.
Besonders problematisch: Fehler zeigen sich zu spät im Ablauf. Eine falsch konfigurierte Variable führt unter Umständen erst tief im Pipeline-Lauf zu einem Fehler und bindet dabei CI/CD-Ressourcen. Teams entwickeln aufwendige Behelfslösungen – eigene Validierungsskripte, ausführliche Dokumentation, komplexe Namenskonventionen –, nur um die variablenbasierte Parameterübergabe halbwegs verlässlich zu machen.
Viele Nutzende haben sich lokale Debugging-Möglichkeiten gewünscht, um Pipeline-Konfigurationen vor der Bereitstellung zu testen. So naheliegend das klingt, in der Praxis scheitert es schnell: Unternehmensweite CI/CD-Abläufe binden Dutzende externe Systeme ein – Cloud-Anbieter, Artefakt-Repositorys, Security-Scanner, Deployment-Ziele –, die sich lokal kaum nachbilden lassen. Und selbst wenn, wäre der Aufwand kaum wartbar. Diese Diskrepanz führte zu einer anderen Fragestellung. Statt „Wie lassen sich Pipelines lokal testen?“ lautete die Frage nun: „Wie lassen sich Konfigurationsprobleme durch variablenbasierte Parameterübergabe verhindern, bevor eine CI/CD-Automatisierung überhaupt läuft?“
Die folgenden Beispiele zeigen, wie Inputs die beschriebenen Probleme im Detail lösen – von der Variablenpräzedenz über die Typvalidierung bis zur schrittweisen Migration.
Das Variablensystem von GitLab kennt mehrere Präzedenzebenen, um verschiedene Anwendungsfälle flexibel abzudecken. Dieses System deckt viele sinnvolle Szenarien ab – etwa wenn Administratoren instanz- oder gruppenweite Standardwerte setzen, die einzelne Projekte bei Bedarf überschreiben. Beim Aufbau wiederverwendbarer Pipeline-Komponenten kann es jedoch zu Schwierigkeiten führen.
Bei Komponenten oder Templates, die über verschiedene Projekte und Gruppen hinweg genutzt werden, macht die Präzedenzhierarchie das Verhalten weniger vorhersehbar. Ein Template, das in einem Projekt einwandfrei funktioniert, verhält sich in einem anderen möglicherweise anders – wegen gruppen- oder instanzweiter Überschreibungen, die in der Pipeline-Konfiguration nicht sichtbar sind.
Werden mehrere Templates eingebunden, wird zudem schwer nachvollziehbar, welche Variablen wo gesetzt werden und wie sie zusammenwirken. Autor(inn)en von Komponenten müssen darüber hinaus nicht nur dokumentieren, welche Variablen ihr Template nutzt, sondern auch mögliche Konflikte mit Variablen höherer Präzedenz.
Haupt-Pipeline-Datei (.gitlab-ci.yml):
variables:
ENVIRONMENT: production # Top-level default for all jobs
DATABASE_URL: prod-db.example.com
include:
- local: 'templates/test-template.yml'
- local: 'templates/deploy-template.yml'
Test-Template (templates/test-template.yml):
run-tests:
variables:
ENVIRONMENT: test # Job-level variable overrides the default
script:
- echo "Running tests in $ENVIRONMENT environment"
- echo "Database URL is $DATABASE_URL" # Still inherits prod-db.example.com!
- run-integration-tests --env=$ENVIRONMENT --db=$DATABASE_URL
# Issue: Tests run in "test" environment but against production database
Deploy-Template (templates/deploy-template.yml):
deploy-app:
script:
- echo "Deploying to $ENVIRONMENT" # Uses production (top-level default)
- echo "Database URL is $DATABASE_URL" # Uses prod-db.example.com
- deploy --target=$ENVIRONMENT --db=$DATABASE_URL
# This will deploy to production as intended
Die Herausforderungen in diesem Beispiel zeigen sich an mehreren Stellen:
ENVIRONMENT=test, erbt aber weiterhin DATABASE_URL=prod-db.example.com – die Tests laufen also in der Testumgebung, aber gegen die Produktionsdatenbank.Ein Vorteil von Inputs liegt in ihrer Flexibilität zur Konfigurationszeit. Inputs werden während der Pipeline-Erstellung ausgewertet und im Format $[[ inputs.input-id ]] interpoliert. Dadurch lassen sie sich überall in der Pipeline-Konfiguration einsetzen – in Job-Namen, in rules-Bedingungen, bei Images und in jedem anderen YAML-Element. Das hebt eine langjährige Einschränkung der Variableninterpolation in bestimmten Kontexten auf.
Ein häufiger Anwendungsfall: Job-Namen wie test-$[[ inputs.environment ]]-deployment.
Inputs in Job-Namen verhindern Namenskollisionen, wenn dieselbe Komponente mehrfach in einer Pipeline eingebunden wird. Ohne diese Möglichkeit würde die zweite Einbindung die erste überschreiben. Input-basierte Job-Namen sorgen dafür, dass jede Einbindung eindeutig benannte Jobs erzeugt.
Vorher (mit Variablen):
test-service:
variables:
SERVICE_NAME: auth-service
ENVIRONMENT: staging
script:
- run-tests-for $SERVICE_NAME in $ENVIRONMENT
Mit Inputs:
spec:
inputs:
environment:
type: string
service_name:
type: string
test-$[[ inputs.service_name ]]-$[[ inputs.environment ]]:
script:
- run-tests-for $[[ inputs.service_name ]] in $[[ inputs.environment ]]
Wird dies mehrfach mit unterschiedlichen Inputs eingebunden, entstehen Jobs wie test-auth-service-staging, test-payment-service-production und test-notification-service-development. Jeder Job trägt einen eindeutigen, aussagekräftigen Namen, der seinen Zweck klar erkennen lässt – die Pipeline-Visualisierung wird dadurch deutlich übersichtlicher als bei mehreren gleichnamigen Jobs, die einander überschreiben.
Angewendet auf das obige Präzedenz-Beispiel, ergibt sich mit Inputs ein unmittelbarer Vorteil: Statt mehrere Template-Dateien zu pflegen, genügt ein einziges wiederverwendbares Template mit unterschiedlichen Input-Werten.
spec:
inputs:
environment:
type: string
database_url:
type: string
action:
type: string
---
$[[ inputs.action ]]-$[[ inputs.environment ]]:
script:
- echo "Running $[[ inputs.action ]] in $[[ inputs.environment ]] environment"
- echo "Database URL is $[[ inputs.database_url ]]"
- run-$[[ inputs.action ]] --env=$[[ inputs.environment ]] --db=$[[ inputs.database_url ]]
In der Haupt-Datei .gitlab-ci.yml lässt sich das Template zweimal (oder öfter) mit unterschiedlichen Werten einbinden, ohne Namenskollisionen:
include:
- local: 'templates/environment-template.yml'
inputs:
environment: test
database_url: test-db.example.com
action: tests
- local: 'templates/environment-template.yml'
inputs:
environment: production
database_url: prod-db.example.com
action: deploy
Das Ergebnis: Statt getrennter YAML-Dateien für Test- und Deployment-Jobs gibt es ein einziges wiederverwendbares Template, das beide Fälle sicher abdeckt. Der Ansatz skaliert auf beliebig viele Umgebungen oder Job-Typen, verringert den Wartungsaufwand, vermeidet Code-Duplizierung und sorgt für Konsistenz über die gesamte Pipeline-Konfiguration hinweg – ein Template statt vieler, ohne das Risiko von Variablenkollisionen oder Konfigurationsabweichungen.
Ein weiterer zentraler Unterschied zwischen Variablen und Inputs liegt in der Validierung. Inputs unterstützen verschiedene Werttypen – Zeichenketten, Zahlen, Booleans und Arrays – und validieren sie unmittelbar bei der Pipeline-Erstellung. Wird ein Input als Boolean definiert, aber eine Zeichenkette übergeben, weist GitLab die Pipeline zurück, bevor ein einziger Job ausgeführt wird.
Der Nutzen der Typvalidierung zeigt sich an einem Beispiel.
Ohne Typvalidierung (Variablen):
variables:
ENABLE_TESTS: "true" # Always a string
MAX_RETRIES: "3" # Always a string
deploy_job:
script:
- if [ "$ENABLE_TESTS" = true ]; then # This fails!
echo "Running tests"
fi
- retry_count=$((MAX_RETRIES + 1)) # String concatenation: "31"
Das Problem: Die Boolean-Prüfung schlägt fehl, weil die Zeichenkette "true" nicht gleich dem Boolean true ist.
Mit Typvalidierung (Inputs):
spec:
inputs:
enable_tests:
type: boolean
default: true
max_retries:
type: number
default: 3
deploy_job:
script:
- if [ "$[[ inputs.enable_tests ]]" = true ]; then # Works correctly
echo "Running tests"
fi
- retry_count=$(($[[ inputs.max_retries ]] + 1)) # Math works: 4
Der praktische Unterschied: Wird eine Pipeline mit ENABLE_TESTS = yes statt true ausgelöst, bemerkt der variablenbasierte Ablauf das erst, wenn der Deployment-Job startet – und die Boolean-Auswertung im Skript fehlschlägt. Mit typisierten Inputs meldet GitLab CI/CD den Typkonflikt dagegen sofort und mit einer klaren Fehlermeldung, bevor die Pipeline überhaupt startet. Der Fehler wird an der Wurzel abgefangen statt tief im Ablauf.
Inputs erhöhen die Sicherheit durch kontrollierte Parameterübergabe mit ausdrücklichen Verträgen, die genau festlegen, welche Werte erwartet und zugelassen sind. Zudem sind Inputs unveränderlich: Sobald die Pipeline startet, lassen sie sich während der Ausführung nicht mehr ändern. Das sorgt für vorhersehbares Verhalten über den gesamten Pipeline-Lebenszyklus und schließt die Risiken aus, die aus der Manipulation von Variablen zur Laufzeit entstehen.
Werden Variablen über das Schlüsselwort variables: auf oberster Ebene der .gitlab-ci.yml definiert, gelten sie als Standard für alle Jobs der gesamten Pipeline. Beim Einbinden von Templates ist deshalb zu bedenken, welche Variablen global definiert sind, da sie über die Präzedenzordnung mit dem erwarteten Verhalten des Templates zusammenwirken können.
Inputs werden dagegen in CI-Konfigurationsdateien definiert – etwa in Komponenten oder Templates – und beim Auslösen einer Pipeline mit Werten belegt. Sie existieren ausschließlich für die Pipeline-Erstellung und -Konfiguration, sind auf die CI-Konfigurationsdatei beschränkt, in der sie definiert werden, und werden mit Beginn der Ausführung zu unveränderlichen Referenzen. Da jede Komponente ihre eigenen Inputs führt, besteht kein Risiko, dass Inputs andere Komponenten oder Templates beeinflussen – Variablenkollisionen und Überschreibungen entfallen.
Teams haben viel in ihre variablenbasierten Abläufe investiert, und der Umstieg auf Inputs geschieht nicht über Nacht. Deshalb gibt es Möglichkeiten, Inputs und Variablen zusammenwirken zu lassen – als Brücke zwischen bestehenden Variablen und den Vorteilen von Inputs, die zugleich zentrale Grenzen der Variablenexpansion überwindet.
Ein praxisnahes Beispiel dazu.
Variablenexpansion in rules-Bedingungen
Eine häufige Hürde entsteht, wenn Variablen, die weitere Variablenreferenzen enthalten, in rules:if-Bedingungen verwendet werden. GitLab expandiert Variablen bei der Regelauswertung nur eine Ebene tief, was zu unerwartetem Verhalten führen kann:
# This doesn't work as expected
variables:
TARGET_ENV:
value: "${CI_COMMIT_REF_SLUG}"
deploy-job:
rules:
- if: '$TARGET_ENV == "production"' # Compares "${CI_COMMIT_REF_SLUG}" != "production"
variables:
DEPLOY_MODE: "blue-green"
Die Funktion expand_vars löst dies, indem sie in Inputs eine vollständige Variablenexpansion erzwingt:
spec:
inputs:
target_environment:
description: "Target deployment environment"
default: "${CI_COMMIT_REF_SLUG}"
---
deploy-job:
rules:
- if: '"$[[ inputs.target_environment | expand_vars ]]" == "production"'
variables:
DEPLOY_MODE: "blue-green"
APPROVAL_REQUIRED: "true"
- when: always
variables:
DEPLOY_MODE: "rolling"
APPROVAL_REQUIRED: "false"
script:
- echo "Target: $[[ inputs.target_environment | expand_vars ]]"
- echo "Deploy mode: ${DEPLOY_MODE}"
Ohne expand_vars werten Regelbedingungen die wörtliche Variablenreferenz aus (etwa "${CI_COMMIT_REF_SLUG}") statt des expandierten Werts (etwa "production"). Das führt zu Regeln, die entgegen der Erwartung nie zutreffen, und bricht die bedingte Pipeline-Logik.
Wichtige Hinweise zu expand_vars:
include verwenden lassen.expand_vars müssen korrekt in Anführungszeichen gesetzt werden: '"$[[ inputs.name | expand_vars ]]" == "value"'.Dieses Muster löst die Beschränkung auf einstufige Variablenexpansion und funktioniert für jede bedingte Logik, die vollständig aufgelöste Variablenwerte vergleicht.
Neben expand_vars lassen sich Funktionen wie truncate nutzen, um Werte für Namensbeschränkungen zu kürzen (etwa für Kubernetes-Ressourcennamen). So entstehen anspruchsvolle Verarbeitungsketten für Parameter, während Inputs sicher und vorhersehbar bleiben.
spec:
inputs:
service_identifier:
default: 'service-$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG'
---
create-resource:
script:
- resource_name=$[[ inputs.service_identifier | expand_vars | truncate(0,50) ]]
Diese Integrationsmöglichkeit erlaubt es, Inputs schrittweise einzuführen und dabei die bestehende Variableninfrastruktur weiter zu nutzen – der Migrationsweg wird dadurch deutlich sanfter.
Bis GitLab 17.11 ließen sich Inputs nur in Komponenten und Templates über die include:-Syntax verwenden. Das beschränkte ihren Einsatz auf wiederverwendbare CI/CD-Konfigurationen und deckte den umfassenderen Bedarf an dynamischer Pipeline-Anpassung nicht ab.
Seit GitLab 17.11 lassen sich Inputs über alle Ausführungskontexte hinweg einsetzen, um das Pipeline-Verhalten sicher anzupassen, und ersetzen damit die bisherige Abhängigkeit von Pipeline-Variablen. Diese erweiterte Unterstützung umfasst:
Diese Erweiterungen – weitere folgen – erlauben es Teams, ihre Pipelines schrittweise zu modernisieren und dabei die Abwärtskompatibilität zu wahren. Sobald Inputs vollständig eingeführt sind, lassen sich Pipeline-Variablen deaktivieren, was eine sicherere und vorhersehbarere CI/CD-Umgebung schafft.
Der Wechsel von Variablen zu Inputs ist mehr als eine technische Umstellung – er verschiebt den Schwerpunkt hin zu wartbareren, vorhersehbareren und sichereren CI/CD-Pipelines. Variablen erfüllen weiterhin wichtige Zwecke bei der Konfiguration; Inputs liefern die Fähigkeiten zur Parameterübergabe, um die Teams jahrelang herumarbeiten mussten.
Da Variablen tief in bestehenden Abläufen verankert sind, gibt es Brücken zwischen beiden Systemen. Die Funktion expand_vars und weitere Input-Fähigkeiten erlauben eine schrittweise Einführung, ohne die bestehende Variableninfrastruktur aufzugeben.
Wer mit neuen Komponenten und Templates beginnt und dann nach und nach wichtige Abläufe migriert, erkennt rasch den Nutzen: klarere Verträge, frühere Fehlererkennung und verlässlichere Automatisierung, die organisationsweit skaliert. Der Umstieg auf Inputs schafft zudem eine gute Grundlage für den CI/CD-Katalog von GitLab, in dem wiederverwendbare Komponenten mit typisierten Schnittstellen zu wirkungsvollen Bausteinen für DevOps-Abläufe werden.

Verwaltest du Tool-Chaos oder stellst du Innovationen bereit?
Das Quiz dauert maximal 5 Minuten.
Hat dir dieser Blogbeitrag gefallen? Hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab-Community-Forum und lass andere an deinen Eindrücken teilhaben.
Feedback teilenBeginne noch heute, schneller zu entwickeln
Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.