Aller au contenu
CI/CD & Automatisation medium

Templates GitLab CI/CD (include, extends)

24 min de lecture

logo gitlab

Vous copiez-collez les mêmes jobs entre vos projets ? Les templates GitLab CI/CD permettent de centraliser et réutiliser vos configurations. Modifiez en un seul endroit, propagez partout.

À la fin de ce module, vous saurez :

  • Utiliser les 5 types d’include : local, project, remote, template, component
  • Créer un projet de templates : structure et organisation recommandées
  • Versionner vos templates : ref avec tags pour la stabilité
  • Partager entre projets : une source de vérité pour 50+ repos
  • Conditionner les includes : rules pour inclure selon le contexte
  • Sécuriser vos templates : éviter les risques de supply chain
  • Débugger avec le Pipeline Editor : visualiser la config merged

Avant de continuer, assurez-vous de maîtriser :

Sans factorisation, voici ce qui se passe :

SituationImpact concret
DuplicationMême job Node.js copié dans 50 projets
DériveChaque projet diverge : Node 16 ici, Node 18 là, Node 20 ailleurs
MaintenanceVulnérabilité découverte ? 50 merge requests à créer…
IncohérenceProjet A teste avec coverage, projet B non

Exemple concret : Vous découvrez que npm ci est plus rapide et fiable que npm install. Pour mettre à jour 50 projets, il faut :

  • 50 branches
  • 50 merge requests
  • 50 reviews
  • 50 merges

→ 1 journée de travail pour un changement de 2 mots.

Avec les templates :

AvantageRésultat
Une source de véritéLe template définit la “bonne façon” de builder Node.js
Cohérence garantieTous les projets utilisent la même version
Mise à jour simple1 merge request dans le projet de templates = 50 projets mis à jour
Standards enforcésTests, linting, sécurité inclus par défaut

Le mot-clé include permet d’importer du YAML depuis d’autres fichiers. C’est la base de la réutilisation.

GitLab propose 5 façons d’inclure des fichiers, selon leur emplacement :

TypeSyntaxeOù est le fichier ?Cas d’usage typique
locallocal: '/path/file.yml'Même repositoryDécouper un gros .gitlab-ci.yml
projectproject: 'group/project'Autre projet GitLabTemplates partagés (recommandé)
remoteremote: 'https://...'URL externeTemplates open source
templatetemplate: 'Jobs/Build.gitlab-ci.yml'Templates officiels GitLabSAST, DAST, License Scanning
componentcomponent: 'gitlab.com/org/comp@v1'CI/CD CatalogBriques versionnées réutilisables

Les 5 types d'include : local, project, remote, template, component

Quand votre .gitlab-ci.yml dépasse 200-300 lignes, il devient difficile à lire. La solution : découper en fichiers par catégorie.

# .gitlab-ci.yml (fichier principal, court et lisible)
include:
- local: '/ci/build.yml' # Jobs de build
- local: '/ci/test.yml' # Jobs de test
- local: '/ci/deploy.yml' # Jobs de déploiement
stages:
- build
- test
- deploy
# ci/build.yml (dédié au build)
build:
stage: build
script:
- npm ci
- npm run build

Pourquoi c’est mieux ?

  1. Lisibilité : chaque fichier a une seule responsabilité
  2. Collaboration : l’équipe infra modifie deploy.yml, les devs modifient test.yml
  3. Navigation : on trouve rapidement ce qu’on cherche

C’est le type d’include le plus utile. Il permet d’importer des templates depuis un projet GitLab dédié.

include:
- project: 'devops/ci-templates' # Projet contenant les templates
file: '/templates/nodejs.yml' # Chemin du fichier dans ce projet
ref: 'main' # Branche, tag ou commit

Déconstruction de la syntaxe :

OptionCe qu’elle faitExemple
projectChemin complet du projet GitLab'devops/ci-templates'
fileChemin du fichier dans le projet'/templates/nodejs.yml'
refVersion à utiliser (optionnel)'main', 'v1.0.0', 'a1b2c3d'

Le chemin project expliqueé :

devops/ci-templates
└──┬── └────┬─────────
groupe nom du projet

Si votre projet est dans un sous-groupe : 'company/devops/ci-templates'

Fichier externe via URL :

include:
- remote: 'https://example.com/templates/ci.yml'

GitLab fournit des templates prêts à l’emploi :

include:
- template: Jobs/Build.gitlab-ci.yml
- template: Security/SAST.gitlab-ci.yml

Documentation officielle : GitLab CI/CD Templates — cette page liste tous les templates maintenus par GitLab avec leur documentation d’utilisation.

Créez un projet devops/ci-templates avec cette structure :

ci-templates/
├── templates/
│ ├── nodejs.yml
│ ├── python.yml
│ ├── docker.yml
│ └── deploy/
│ ├── kubernetes.yml
│ └── aws.yml
├── jobs/
│ ├── lint.yml
│ ├── test.yml
│ └── security.yml
└── README.md

Deux approches sont possibles. Choisissez-en une seule pour éviter la confusion :

Principe : Chaque job fait npm ci, mais le cache accélère le téléchargement.

# templates/nodejs.yml — Pattern Cache (recommandé pour débuter)
variables:
NODE_VERSION: "18"
# Configuration de base partagée
.nodejs_base:
image: "node:${NODE_VERSION}"
cache:
key:
files:
- package-lock.json # Invalide si deps changent
paths:
- .npm/ # Cache npm, PAS node_modules/
policy: pull-push
before_script:
- npm ci --cache .npm --prefer-offline
# Build : npm ci déjà fait dans before_script
.nodejs_build:
extends: .nodejs_base
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
# Test : npm ci déjà fait dans before_script
.nodejs_test:
extends: .nodejs_base
script:
- npm test
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'

Avantages : Simple, robuste, fonctionne sur tous les runners.

mon-projet/.gitlab-ci.yml
include:
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'v1.0.0'
stages:
- install
- build
- test
install:
stage: install
extends: .nodejs_install
build:
stage: build
extends: .nodejs_build
needs: ["install"]
test:
stage: test
extends: .nodejs_test
needs: ["install"]

Sans ref, vous utilisez la branche par défaut du projet de templates. Si quelqu’un y pousse un changement non testé, tous vos pipelines peuvent casser.

# ⚠️ Dangereux : utilise toujours la dernière version
include:
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
# Pas de ref = branche par défaut = peut changer à tout moment
include:
# ✅ Version stable pour la prod (recommandé)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'v1.0.0' # Tag = version figée
# ✅ Commit spécifique (maximum de contrôle)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'a1b2c3d4e5f6' # SHA du commit
# ⚠️ Branche (peut changer)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'main'
EnvironnementQuel ref utiliserPourquoi
ProductionTag (v1.0.0)Stable, testé, ne change jamais
StagingBranche mainTeste les dernières évolutions
DéveloppementBranche feature/*Teste une nouvelle fonctionnalité

GitLab supporte include:rules pour conditionner les fichiers inclus :

include:
# Toujours inclus
- local: '/ci/base.yml'
# Seulement si variable définie
- local: '/ci/security.yml'
rules:
- if: '$ENABLE_SECURITY == "true"'
# Seulement sur main
- local: '/ci/deploy-prod.yml'
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
✅ Bon usage⚠️ Mauvais usage
Activer la sécurité via $ENABLE_SECURITYMultiplier les conditions jusqu’à l’illisibilité
Inclure le déploiement prod uniquement sur mainConditionner chaque template individuellement
Désactiver des jobs en mode “dry-run”Créer des branches logiques complexes

Les jobs qui étendent un template peuvent surcharger n’importe quelle propriété :

include:
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
build:
extends: .nodejs_build
variables:
NODE_VERSION: "20" # Surcharge la version
script:
- npm run build:prod # Surcharge le script
after_script:
- echo "Build terminé" # Ajoute un after_script

Plateforme de templates GitLab CI/CD maintenus par des experts :

  • Templates prêts à l’emploi pour de nombreuses technologies
  • Bien documentés et régulièrement mis à jour
  • Supporte les workflows modernes (Gitflow, trunk-based)

Site : to-be-continuous.gitlab.io

Catalogue de templates avec audit de conformité :

  • Catalogue visuel de templates
  • Détection de secrets et variables non protégées
  • Audit de conformité automatique

Site : r2devops.io

Utilisez toujours ref pour éviter les surprises :

include:
# ✅ Version pinnée (recommandé)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'v1.0.0' # Tag
# ✅ Commit spécifique (maximum de contrôle)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'a1b2c3d4e5f6' # SHA commit
# ⚠️ Branche (peut changer)
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'main'

include:integrity permet de vérifier le hash SHA256 du fichier inclus :

include:
- remote: 'https://example.com/templates/ci.yml'
integrity: 'sha256:abc123def456...' # Hash du fichier

Les CI/CD Components (include: component) présentent le même risque que les includes classiques si vous ne les pinnez pas :

# ❌ Dangereux : utilise toujours la dernière version
include:
- component: 'gitlab.com/components/sast@main'
# ✅ Sûr : version figée
include:
- component: 'gitlab.com/components/sast@1.2.0'
# ✅ Maximum de contrôle : SHA du commit
include:
- component: 'gitlab.com/components/sast@a1b2c3d4e5f6'

Quand vous utilisez include, l’outil indispensable c’est le Pipeline Editor de GitLab.

  1. Ouvrir le Pipeline Editor

    Dans votre projet : Build → Pipeline editor

  2. Visualiser la configuration complète

    Cliquez sur l’onglet “View merged YAML” (ou “Full configuration”).

    Vous voyez la configuration après résolution de tous les includes — c’est ce que GitLab exécute réellement.

  3. Identifier l’origine d’un job

    Dans la vue merged, cherchez le job qui pose problème. Vous pouvez voir :

    • Toutes les variables héritées
    • Les extends résolus
    • Les rules finales
  4. Valider avant de commit

    Le bouton “Validate” vérifie la syntaxe YAML et les références (jobs, stages).

Sans préfixe, vous risquez des conflits entre templates :

# ❌ Risque de conflit
.build: # Et si un autre template a aussi .build ?
script: ...
# ✅ Préfixe explicite
.nodejs_build:
.python_build:
.docker_build:

Chaque template devrait avoir un README avec :

  • Ce que fait le template (objectif)
  • Comment l’utiliser (exemple minimal)
  • Variables configurables (liste avec défauts)
  • Versions supportées (changelog des breaking changes)

Créez un projet ci-templates-tests qui :

  • Inclut chaque template
  • Lance un pipeline de validation
  • Vérifie que les jobs s’exécutent sans erreur

Un fichier = une technologie :

templates/
├── nodejs.yml # Tout ce qui concerne Node.js
├── python.yml # Tout ce qui concerne Python
├── docker.yml # Build/push d'images Docker
└── security.yml # Scans de sécurité (SAST, DAST)

Définissez toujours une valeur par défaut dans le template :

# Dans le template
variables:
NODE_VERSION: "18" # Valeur par défaut
.nodejs_build:
image: "node:${NODE_VERSION}"
# Dans le projet (surcharge optionnelle)
variables:
NODE_VERSION: "20" # Surcharge la valeur par défaut
# ❌ Dangereux
include:
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
# Pas de ref = utilise main = peut casser à tout moment
# ✅ Sûr
include:
- project: 'devops/ci-templates'
file: '/templates/nodejs.yml'
ref: 'v1.2.0' # Version figée

Quand plusieurs équipes partagent des templates, les conventions évitent les conflits et facilitent la lecture :

ÉlémentConventionExemples
Jobs cachés.{techno}_{action}.nodejs_build, .python_test, .docker_push
Variables de version{TECHNO}_VERSIONNODE_VERSION, PYTHON_VERSION, GO_VERSION
StagesNoms prévisiblesbuild, test, security, deploy
Fichiers{techno}.ymlnodejs.yml, python.yml, security.yml
# Exemple de template bien nommé
variables:
NODE_VERSION: "18" # Convention : TECHNO_VERSION
.nodejs_base: # Convention : .techno_action
image: "node:${NODE_VERSION}"
.nodejs_build:
extends: .nodejs_base
stage: build # Stage prévisible

Symptôme : Le pipeline refuse de se créer.

include config from '/templates/nodejs.yml' not found

Causes possibles :

  • Chemin incorrect (vérifiez les / au début)
  • Fichier renommé ou supprimé dans le projet source
  • ref qui pointe vers une branche/tag inexistant

Solution : Vérifiez le chemin exact dans le projet source.

Symptôme : GitLab ne trouve pas le projet de templates.

Causes possibles :

  • Chemin de projet incorrect (group/project vs group/subgroup/project)
  • Pas de permissions d’accès au projet
  • Projet privé sans accès pour le runner

Solution :

  • Vérifiez que vous pouvez accéder au projet dans l’interface GitLab
  • Demandez l’accès “Guest” minimum au projet de templates

Symptôme : extends: .nodejs_build échoue.

Cause : Le template n’exporte pas ce job (nom différent, ou job supprimé).

Solution : Ouvrez le fichier template et vérifiez le nom exact des jobs cachés.

Symptôme : Comportement bizarre, variables écrasées.

Cause : Deux templates définissent un job avec le même nom.

Solution : Utilisez des préfixes uniques (.nodejs_, .python_).

Symptôme : Votre valeur personnalisée est ignorée.

# Template
.job:
variables:
VERSION: "1.0"
# Votre projet
job:
extends: .job
VERSION: "2.0" # ❌ Syntaxe incorrecte !

Solution : Les variables se définissent dans variables:.

job:
extends: .job
variables:
VERSION: "2.0" # ✅ Correct
  1. include: local pour les fichiers du même repo
  2. include: project pour les templates centralisés
  3. include: component pour les briques versionnées du CI/CD Catalog
  4. ref pour versionner — pinez par tag ou commit (y compris les components !)
  5. extends pour hériter et surcharger
  6. Préfixer les jobs cachés (.nodejs_, .python_)
  7. Éviter include: remote non maîtrisé (risque supply chain)
  8. Choisir UN pattern pour Node.js : cache .npm/ OU artifacts node_modules/
  9. Pipeline Editor → View merged YAML pour débugger les includes
  10. Max 150 includes et 2 niveaux d’imbrication pour rester maintenable

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.