Aller au contenu principal

Template de pipelines Gitlab CI/CD

· 5 minutes de lecture
Stéphane ROBERT

En tant que développeurs, nous connaissons tous l'acronyme DRY : don’t repeat yourself Et donc nous savons tous qu'il faut autant que possible factoriser notre code. Pour nos Gitlab-ci, nous avons à notre disposition les templates.

Mais pourquoi donc ?

Si vous êtes un devops travaillant sur plusieurs projets sur GitLab, vous aurez vite remarqué que si vous devez modifier un pattern dans tous vos projets ce la peut vite devenir fastidieux.

Prenons le cas d'une application utilisant un grand nombre de librairies toutes standardisées utilisant à peu près tous les mêmes stages : deploy, test, .., release. Si vous deviez reporter la moindre modification sur un template à toutes cela pourrait être improductif et sources d'erreurs. Alors voyons ensemble les templates Gitlab-ci

Créer et inclure template Gitlab-ci

Pour stocker les différents composants de votre template, créez tout simplement un projet gitlab indépendant. Créez-y vos fichiers yaml.

Par exemple nous voulons définir un template d'installation de packages nodejs (le premier commentaire est le nom du projet suivi du nom du fichier) :

# template-ci/install.yml

install:
script:
- npm install

Ensuite dans vos projets d'applications, il suffit d'inclure dans votre .gitlab-ci.yml un appel à ce script.

# mon-app1/.gitlab-ci.yml

include:
- project: 'template-ci'
file: 'install.yml'
ref: 'master'

Vous remarquez certainement la balise ref. Elle permet de pointer vers une branche du projet de template. Cela va vous permettre de pouvoir faire évoluer votre ci sans impacter toute votre production. En effet, dans un projet préci, vous pourrez utiliser une branche de votre template pour le faire évoluer par exemple. Vous pourriez également créer des branches pour des variantes de votre template de ci.

Paramétrer un template gitlab-ci

Pour le moment, install recherche uniquement les dépendances déclarées dans le fichier package.json. Mais voilà dans un de vos projets, nous voulons lui indiquer un autre fichier de déclarations. Pour répondre à cela gitlab propose les variables d'environnement.

Pour éviter des effets indésirables je vous recommande de déclarer toutes les tâches de templates en tant que taches masquées et d'utiliser extend si nécessaire. En utilisant cette méthode une tache masquée incluse non déclarée en extend ne sera pas exécuté. Donc si on lance notre précédant pipeline d'application il ne se passera rien !

Pour déclarer une tache masquée il suffit de lui mettre un . devant son nom. Ce qui donne :

# template-ci/install.yml

.install:
variables:
INSTALL_DIRECTORY: '.'
script:
- cd $INSTALL_DIRECTORY
- npm install

Dans notre le ci de l'application nous devons utiliser le mot clé extends :

# mon-app1/.gitlab-ci.yml

include:
- project: 'template-ci'
file: 'install.yml'
ref: 'master'

projet1:
extends: .install
variables:
INSTALL_DIRECTORY: 'projet1/'

projet2:
extends: .install
variables:
INSTALL_DIRECTORY: 'projet2/'

Définir des templates dans le même fichier

Il est possible de définir les templates de job dans le fichier .gitlab-ci.yml. On reprend le même principe

Exemple :

.pip_install:
stage: sanity check
image: fedora:31
before_script:
- curl https://bootstrap.pypa.io/get-pip.py -o /root/get-pip.py
- python3 /root/get-pip.py
- dnf install -y git-core

sanity check:
extends: .pip_install
script:
- pip3 install --user jinja2 PyYAML
- python3 ./src/generate_templates.py

- git diff --exit-code && exit 0 || true

- echo "some files were not generated through 'src/generate_templates.py' or
have not been committed. Please edit the files under 'src', run
'src/generate_templates.py' and then commit the result"
- exit 1

Utilisation des ancres

Une autre syntaxe possible fait appel à ce aux ancres yaml. Il s'agit d'un nom auquel est accolé un &ancre. Ensuite vous rappelez <<: *ancre.

Un exemple :

.job_template: &job_configuration
image: ruby:2.6
services:
- postgres
- redis

test1:
<<: *job_configuration
script:
- test1 project

test2:
<<: *job_configuration
script:
- test2 project

Cela peut être utile si on souhaite utiliser deux template de job dans un job :

.job_template: &job_configuration
script:
- test project
tags:
- dev

.postgres_services:
services: &postgres_configuration
- postgres
- ruby

.mysql_services:
services: &mysql_configuration
- mysql
- ruby

test:postgres:
<<: *job_configuration
services: *postgres_configuration
tags:
- postgres

test:mysql:
<<: *job_configuration
services: *mysql_configuration

On peut aussi l'utiliser pour étendre des variables, mais aussi les scripts :

variables: &global-variables
SAMPLE_VARIABLE: sample_variable_value
ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value

# a job that must set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy:
stage: cleanup
variables:
<<: *global-variables
GIT_STRATEGY: none
script: echo $SAMPLE_VARIABLE

Pour l'utiliser avec les include il faut alors utiliser des !références :

# setup.yml
.setup:
script:
- echo creating environment

et dans le ci lui même :

include:
- local: setup.yml

.teardown:
after_script:
- echo deleting environment

test:
script:
- !reference [.setup, script]
- echo running my own command
after_script:
- !reference [.teardown, after_script]

Depuis la version 14.3 de gitlab il est possible de conditionner les include par des règles.

include:
- local: builds.yml
rules:
- if: '$INCLUDE_BUILDS == "true"'

Plus loin avec les templates gitlab-ci

Il existe de nombreux autres patterns d'utilisation des templates de ci. Le plus simple, c'est de lire ceux de gros projets héberger dans gitlab.com comme celui gitlab/release-cli ou celui de freedesktop.org