Mise à jour : 7 août 2025
Lecture : 17 min
Les intrants CI/CD de GitLab remplacent les variables par des paramètres typés et validés pour transmettre des instructions fiables et sécurisées aux pipelines.
Les intrants CI/CD représentent une avancée majeure dans la gestion des pipelines.
Spécialement conçus pour passer des paramètres typés, validés et sécurisés, ils instaurent des contrats explicites et une sécurité renforcée entre les composants de vos workflows et résolvent enfin les limites structurelles auxquelles les équipes de développement font face depuis des années avec les variables traditionnelles.
Les variables CI/CD ont été détournées de leur usage initial. Historiquement, elles étaient conçues pour stocker des paramètres de configuration, et non comme un mécanisme sophistiqué de transmission de paramètres dans le cadre de workflows complexes. Ce décalage a entraîné son lot de problèmes : manque de fiabilité, failles de sécurité, complexité croissante en termes de maintenance.
Dans cet article, découvrez pourquoi les intrants CI/CD sont désormais l'approche recommandée pour passer des paramètres à vos pipelines, ainsi que leurs nombreux avantages (sécurité des types, prévention des échecs de pipeline, élimination des conflits entre variables, automatisation simplifiée). Des exemples concrets illustreront leur mise en œuvre et les problèmes qu'ils résolvent, dans l'espoir de vous convaincre d'abandonner les solutions de contournement à base de variables au profit d'une approche plus fiable et structurée.
Utiliser des variables pour passer des paramètres aux pipelines peut sembler pratique, mais cette approche peut être source de frustration et poser de nombreux risques.
Absence de validation des types
Les variables sont des chaînes de caractères. Sans validation des types, un pipeline peut recevoir accidentellement une chaîne à la place d'une valeur booléenne ou d'un nombre et entraîner des échecs inattendus. Un workflow de déploiement de production critique peut par exemple échouer quelques heures après son démarrage, car une vérification booléenne dans une variable n'a pas été transmise correctement.
Mutabilité pendant l'exécution
Les variables peuvent être modifiées à tout moment lors de l'exécution du pipeline, ce qui génère des comportements imprévisibles lorsque plusieurs jobs tentent de modifier les mêmes valeurs. Par exemple, deploy_job_a définit DEPLOY_ENV=staging
, mais deploy_job_b attribue la valeur production
à DEPLOY_ENV
.
Risques de sécurité
Les variables utilisées comme de simples paramètres héritent souvent des mêmes autorisations d'accès que les secrets sensibles, ce qui entraîne des problèmes de sécurité. Il n'existe aucun contrat définissant les paramètres attendus par un pipeline, leurs types ou leurs valeurs par défaut. Ainsi, un paramètre apparemment anodin comme BUILD_TYPE
peut soudainement se retrouver à tort avec un accès à des secrets de production simplement parce que les variables ne font pas intrinsèquement la distinction entre les paramètres et les données sensibles.
Pire encore, les erreurs ne sont détectées qu'au moment de l'exécution du pipeline, parfois après plusieurs minutes, voire plusieurs heures. Une simple variable mal configurée peut ainsi provoquer l'échec d'un pipeline, avec à la clé la perte de précieuses ressources CI/CD et une perte de temps pour l'équipe de développement. Pour limiter ces risques, les équipes recourent alors à des solutions de contournement, telles que des scripts de validation maison, une documentation excessive ou des conventions de nommage complexes, autant de tentatives pour renforcer du mieux possible la fiabilité de la transmission de paramètres basée sur des variables.
Nombreux sont les utilisateurs qui ont exprimé le besoin de disposer de fonctionnalités de débogage local pour tester les configurations de leurs pipelines avant le déploiement. Bien que cette solution semble logique, elle se révèle rapidement inefficace dans la pratique. Les workflows CI/CD s'appuient sur des dizaines de systèmes tiers (fournisseurs de services cloud, dépôts d'artefacts, scanners de sécurité, cibles de déploiement), qui ne peuvent tout simplement pas être répliqués localement. Même dans cette éventualité, la complexité rendrait les environnements de test locaux presque impossibles à maintenir. Face à ces limites, une remise en question s'imposait. Au lieu de chercher à mieux tester les pipelines localement, nous avons cherché à comprendre comment nous pouvions éviter les erreurs de configuration liées à la transmission de paramètres via des variables avant même l'exécution du workflow d'automatisation CI/CD.
Le système de variables de GitLab comprend plusieurs niveaux de priorité qui offrent une grande flexibilité en fonction des cas d'utilisation rencontrés. Bien que ce système soit utile dans de nombreux scénarios, comme permettre aux administrateurs de définir des valeurs par défaut à l'échelle de l'instance ou du groupe tout en autorisant les projets individuels à les remplacer si nécessaire, il peut créer des difficultés lors de la construction de composants de pipeline réutilisables.
Lorsque vous développez des composants ou des templates destinés à être partagés dans différents projets et groupes, la hiérarchie de priorité des variables peut rendre leur comportement moins prévisible. Par exemple, un template qui fonctionne parfaitement dans un projet peut produire des résultats différents dans un autre, simplement parce que certaines variables ont été redéfinies au niveau du groupe ou de l'instance et ne sont pas visibles dans la configuration locale du pipeline.
Lorsque vous combinez plusieurs templates, il devient alors difficile de savoir quelles variables sont définies ainsi qu'où et comment elles interagissent.
En outre, les auteurs de composants doivent non seulement documenter les variables que leur template utilise, mais également identifier les risques de conflits avec des variables susceptibles d'être définies à des niveaux de priorité plus élevés.
Fichier de pipeline principal (.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'
Template de test (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`
Template de déploiement (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
Défis dans cet exemple :
Héritage partiel : le job de test hérite bien de ENVIRONMENT=test
, mais conserve DATABASE_URL=prod-db.example.com
.
Coordination complexe : les auteurs de templates doivent connaître l'ensemble des variables définies en amont pour éviter les conflits.
Remplacement imprévisible : lorsqu'une variable définie au niveau du job porte le même nom qu'une variable globale, elle la remplace — un comportement qui peut être difficile à anticiper.
Dépendances cachées : les templates dépendent des noms de variables définis dans le pipeline principal.
Pour relever ces défis, GitLab a introduit les intrants CI/CD, une solution dédiée à la transmission des paramètres aux pipelines, qui offre des paramètres typés, validés dès la création du pipeline et non au moment de son exécution.
Les intrants CI/CD permettent de définir des paramètres typés pour des pipelines réutilisables, avec une validation intégrée dès leur création. Conçus spécifiquement pour fournir des valeurs au moment de l'exécution du pipeline, ils instaurent un contrat explicite entre le pipeline et ses utilisateurs : chaque paramètre attendu y est clairement défini, ainsi que son type et ses contraintes.
L'un des avantages des intrants CI/CD est leur flexibilité en termes de temps de configuration. Évalués et interpolés dès la création du pipeline à l'aide du format d'interpolation $[[ inputs.input-id ]]
, ils peuvent être utilisés dans toutes les parties de la configuration de votre pipeline, y compris les noms de jobs, les conditions de règles, les images de conteneurs et tout autre élément du fichier de configuration YAML. Ils contournent ainsi les limites liées à l'interpolation des variables dans certains contextes.
Voici un cas d'utilisation courant : vous définissez des noms de jobs comme suit : test-$[[ inputs.environment ]]-deployment
.
En intégrant des intrants CI/CD dans les noms de jobs, vous évitez les conflits lorsqu'un composant est inclus plusieurs fois dans un même pipeline. Sinon, le fait d'inclure le même composant deux fois entraînerait des conflits de noms de jobs, la deuxième inclusion écrasant la première. Les intrants CI/CD permettent au contraire de générer des noms de jobs uniques à chaque inclusion.
Voici le script sans les intrants CI/CD :
test-service:
variables:
SERVICE_NAME: auth-service
ENVIRONMENT: staging
script:
- run-tests-for $SERVICE_NAME in $ENVIRONMENT
Voici le script avec les intrants CI/CD :
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 ]]
Lorsqu'un composant est inclus plusieurs fois avec des intrants différents, il génère des jobs tels que test-auth-service-staging
, test-payment-service-production
et test-notification-service-development
. Chaque job porte ainsi un nom unique et explicite qui indique clairement son objectif, ce qui renforce la visualisation du pipeline : en effet, cela évite que plusieurs jobs avec des noms identiques se remplacent les uns les autres.
Revenons maintenant au premier exemple présenté au début de cet article, cette fois en tirant parti des intrants CI/CD. Premier avantage immédiat : au lieu de gérer plusieurs fichiers de templates, nous pouvons désormais n'en maintenir qu'un seul et le réutiliser avec des valeurs d'intrant personnalisées :
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 ]]
Dans le fichier principal gitlab-ci.yml
, nous pouvons l'inclure deux fois (ou plus) avec des valeurs différentes, en veillant à éviter les conflits de noms.
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
Résultat : au lieu de maintenir des fichiers YAML distincts pour les jobs de test et de déploiement, vous disposez désormais d'un template réutilisable unique qui gère les deux cas d'utilisation en toute sécurité. Cette approche s'adapte à un nombre illimité d'environnements ou de types de jobs, ce qui réduit les frais de maintenance, élimine la duplication du code et garantit la cohérence de l'ensemble de la configuration de votre pipeline. Vous n'avez qu'un seul template à maintenir au lieu de plusieurs, sans risque de conflit de variables ni de dérive de configuration.
L'un des grands atouts des intrants CI/CD par rapport aux variables réside dans les capacités de validation des types. Ils prennent en charge différents types de valeurs, notamment les chaînes, les nombres, les valeurs booléennes et les tableaux, et la validation a lieu dès la création du pipeline. Si vous définissez un intrant CI/CD en tant que valeur booléenne, mais que vous passez une chaîne, GitLab rejette le pipeline avant l'exécution de tout job, ce qui vous permet d'économiser du temps et des ressources.
Voici un exemple illustrant l'énorme avantage de la validation des types.
Sans validation des types (variables) :
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"
Problème : la vérification booléenne échoue, car « true
» (chaîne) n'est pas égal à true
(valeur booléenne).
Avec validation des types (intrants CI/CD) :
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
Impact réel d'un échec de validation des types via des variables : imaginons qu'un développeur ou processus déclenche un pipeline GitLab CI/CD avec ENABLE_TESTS = yes
au lieu de true
. Supposons qu'il faille en moyenne 30 minutes avant que le job de déploiement ne commence : lorsque ce job démarre, au bout de 30 minutes d'exécution du pipeline ou plus, le script de déploiement tente d'évaluer la valeur booléenne et échoue.
Cela a un impact non seulement sur le délai de mise sur le marché, mais également sur le temps de débogage requis pour trouver la raison de l'échec d'un job de déploiement apparemment basique.
Avec les intrants CI/CD basés sur la validation des types, GitLab CI/CD génère immédiatement une erreur et fournit un message d'erreur explicite concernant l'incompatibilité de type.
Les intrants CI/CD renforcent la sécurité, car ils contrôlent de façon stricte la transmission de paramètres avec des contrats explicites qui définissent précisément les valeurs attendues et autorisées. Ainsi, les limites sont claires entre les paramètres et la logique du pipeline. De plus, une fois le pipeline démarré, les intrants ne peuvent pas être modifiés pendant l'exécution, ce qui garantit un comportement prévisible tout au long du cycle de vie du pipeline et permet d'éliminer les risques de sécurité liés à la manipulation des variables en cours de route.
Les variables définies à l'aide du mot-clé variables:
au niveau supérieur de votre fichier .gitlab-ci.yml
s'appliquent par défaut à tous les jobs de votre pipeline. Lorsque vous incluez des templates, vous devez tenir compte de ces variables globales, car elles peuvent interagir avec le comportement attendu du template en raison de l'ordre de priorité des variables propre à GitLab.
À l'inverse, les intrants CI/CD sont définis dans les fichiers de configuration CI (par exemple, les composants ou les templates), puis des valeurs leur sont attribuées lorsqu'un pipeline est déclenché, ce qui vous permet de personnaliser les configurations CI réutilisables. Ils servent uniquement à la création et la configuration du pipeline et sont limités au fichier de configuration CI où ils sont définis. Une fois l'exécution du pipeline lancée, ils ne peuvent plus être modifiés. Étant donné que chaque composant conserve ses propres intrants, il n'y a aucun risque d'interférence avec d'autres composants ou templates de votre pipeline. Cette approche prévient les conflits et les remplacements de variables qui sont fréquents avec le système traditionnel basé sur les variables globales.
De nombreuses équipes utilisent de manière intensive des workflows basés sur les variables, et une migration complète vers les intrants CI/CD ne se fait pas du jour au lendemain. C'est pourquoi nous avons développé des mécanismes qui permettent d'utiliser à la fois des intrants et des variables pour favoriser la transition entre les deux systèmes et surmonter les principaux défis liés à l'expansion des variables.
Prenons un exemple concret pour illustrer cette complémentarité.
Expansion des variables dans les conditions de règles
L'utilisation de variables qui contiennent d'autres références au sein des conditions rules:if
peut s'avérer problématique. GitLab ne développe les variables que sur un niveau lors de l'évaluation de ces règles, ce qui peut entraîner des comportements inattendus :
# 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"
La fonction expand_vars
résout ce problème en forçant une expansion appropriée des variables dans les intrants :
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}"
Sans expand_vars
, les conditions de règles sont évaluées à partir de la référence littérale d'une variable (comme "${CI_COMMIT_REF_SLUG}"
) plutôt que sa variable développée (comme "production"
). Il en résulte des règles qui ne se déclenchent pas comme prévu et brisent la logique conditionnelle du pipeline.
Remarques importantes concernant expand_vars :
Seules les variables qui peuvent être utilisées avec le terme include sont prises en charge.
Les variables doivent être rendues accessibles (non marquées comme protégées/masquées).
L'expansion des variables imbriquées n'est pas prise en charge.
Les conditions de règles avec expand_vars
doivent être correctement citées : '"$[[ inputs.name | expand_vars ]]" == "value"'
.
Ce mécanisme résout la limitation d'expansion de variables à un seul niveau et fonctionne pour toute logique conditionnelle qui nécessite de comparer des valeurs de variables entièrement résolues.
En plus de expand_vars
, vous pouvez chaîner d'autres fonctions telles que truncate
pour raccourcir les valeurs aux restrictions de nommage (par exemple, celles imposées par les noms de ressources Kubernetes). Vous pouvez ainsi créer des pipelines plus sophistiqués, capables de traiter les paramètres tout en maintenant la sécurité et la prévisibilité qu'offrent les intrants CI/CD.
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) ]]
Cette capacité d'intégration vous permet d'adopter progressivement les intrants CI/CD tout en tirant parti de votre infrastructure de variables existante, ce qui facilite la migration vers le nouveau système.
Jusqu'à la version GitLab 17.11, les intrants n'étaient réservés qu'aux composants et templates inclus via la syntaxe include:
, ce qui limitait leur utilisation aux configurations CI/CD réutilisables, mais ne répondait pas au besoin plus large de personnalisation dynamique des pipelines.
À partir de GitLab 17.11, les intrants peuvent désormais être utilisés pour modifier en toute sécurité le comportement du pipeline dans tous les contextes d'exécution associés afin de remplacer le recours traditionnel aux variables de pipeline. Cette prise en charge étendue inclut notamment les pipelines suivants :
Pipelines planifiés : définissez des intrants avec des valeurs par défaut pour les exécutions automatisées et autorisez le remplacement manuel si nécessaire.
Pipelines en aval : transmettez des intrants structurés aux pipelines enfants et multi-projets, avec une validation et une sécurité des types garanties.
Pipelines manuels : proposez une interface claire et validée pour la saisie des intrants.
Ces premières améliorations, auxquelles s'ajouteront prochainement d'autres fonctionnalités, permettent aux équipes de moderniser leurs pipelines tout en assurant une rétrocompatibilité progressive. Une fois les intrants CI/CD pleinement adoptés, vous pouvez désactiver les variables de pipeline pour garantir un environnement CI/CD plus sécurisé et prévisible.
La migration des variables vers les intrants CI/CD représente plus qu'une simple mise à niveau technique : cette évolution garantit des pipelines CI/CD plus faciles à maintenir, plus prévisibles et plus sécurisés. Même si les variables continuent de servir des objectifs importants dans de nombreux scénarios de configuration, les intrants CI/CD fournissent les capacités de transmission de paramètres tant attendues par les équipes de développement.
Conscients que les variables sont profondément intégrées dans les workflows actuels, nous avons conçu des passerelles entre les deux systèmes. La fonction expand_vars
et d'autres capacités d'intrant permettent de tirer parti de ce mécanisme, mais aussi de votre infrastructure de variables existante.
En commençant par de nouveaux composants et templates, puis en migrant progressivement les workflows critiques, vous constaterez rapidement les avantages de contrats explicites, d'une détection précoce des erreurs et d'une automatisation plus fiable qui s'étend à l'ensemble de votre entreprise. De plus, l'adoption des intrants CI/CD constitue un socle idéal pour tirer pleinement parti du catalogue CI/CD de GitLab. Grâce à leurs interfaces typées, les composants réutilisables deviennent des fondamentaux puissants pour structurer vos workflows DevOps. Nous reviendrons sur ce sujet en détail dans un prochain article.
Adopter les intrants CI/CD aujourd'hui, c'est investir dans des pipelines plus robustes, plus lisibles, plus compréhensibles pour demain. Même si vous utilisez déjà un système basé sur des variables, les intrants peuvent être intégrés progressivement afin d'assurer une transition en douceur.
Nous prévoyons d'étendre les capacités actuelles des intrants en vue de résoudre deux enjeux clés : améliorer le déclenchement des pipelines avec des options en cascade qui s'ajustent dynamiquement au choix de l'utilisateur et introduire des intrants au niveau des jobs afin de pouvoir relancer des jobs spécifiques avec des paramètres différents. Nous vous encourageons à suivre ces discussions, à partager vos retours et à contribuer à façonner le développement de ces fonctionnalités via notre ticket dédié aux retours d'expérience.