Aller au contenu
English
English
Infrastructure as Code medium

CI/CD GitLab CI pour rôle Ansible : pipeline parallel:matrix

75 min de lecture

Logo Ansible

Pipeline GitLab CI équivalent au workflow GitHub Actions, pour les équipes hébergées sur GitLab self-hosted ou gitlab.com. Stages : lint → test (parallel:matrix multi-distros × multi-versions). Release sur tag Git.

  • Structure d'un .gitlab-ci.yml pour rôle Ansible.
  • parallel:matrix GitLab pour multi-distros × multi-versions.
  • needs: entre stages pour fail-fast.
  • rules: pour limiter les déclencheurs (MR, branche main, tags).
  • Job de release automatique sur tag Git.

Ce fichier se pose à la racine du dépôt et se lit en trois blocs : les stages, qui donnent l'ordre général, les jobs, un par tâche réelle, et le bloc default:, qui porte ce que tous partagent. Repérez d'abord les trois jobs, ansible-lint, molecule-test et release : le premier filtre vite, le deuxième se démultiplie en 4 combinaisons, le troisième ne part que sur un tag.

---
stages:
- lint
- test
variables:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_NO_CACHE_DIR: "1"
PY_COLORS: "1"
ANSIBLE_FORCE_COLOR: "1"
default:
image: python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
tags:
- docker
# ─── Lint ───
ansible-lint:
stage: lint
before_script:
- pip install ansible-lint==25.* yamllint
script:
- yamllint roles/
- ansible-lint --profile=production roles/
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
# ─── Test multi-distros via matrice ───
molecule-test:
stage: test
needs: ["ansible-lint"]
parallel:
matrix:
- DISTRO: rockylinux9
ANSIBLE_VERSION: "2.17"
- DISTRO: rockylinux9
ANSIBLE_VERSION: "2.18"
- DISTRO: alma10
ANSIBLE_VERSION: "2.18"
- DISTRO: ubuntu2404
ANSIBLE_VERSION: "2.18"
before_script:
- apt-get update && apt-get install -y --no-install-recommends podman
- pip install
"ansible-core==${ANSIBLE_VERSION}.*"
"molecule>=26.0"
"molecule-plugins[podman]>=25.0"
- ansible-galaxy collection install -r requirements.yml
script:
- molecule test
variables:
MOLECULE_DISTRO: $DISTRO
# ─── Job de release sur tag Git ───
release:
stage: test
needs: ["molecule-test"]
script:
- echo "Release du rôle webserver vers Galaxy ici"
# ansible-galaxy role import via API token chiffré dans GitLab CI Variables
rules:
- if: $CI_COMMIT_TAG

Les six sous-sections ci-dessous prennent les mécanismes GitLab un par un, dans l'ordre d'exécution où ils interviennent. Deux d'entre eux n'ont pas d'équivalent exact côté GitHub Actions, la matrice explicite et les rules:, et ce sont précisément ceux qui déroutent en arrivant de l'autre forge.

L'ordre déclaré ici est celui du pipeline entier : tous les jobs d'un stage démarrent ensemble, et le stage suivant attend que le précédent soit terminé. C'est un ordre grossier, que le needs: des sections suivantes viendra affiner job par job.

stages:
- lint
- test

Lint avant test = fail-fast.

default:
image: python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
tags:
- docker

Image Python officielle, runners taggés docker (à adapter selon vos GitLab runners).

molecule-test:
parallel:
matrix:
- DISTRO: rockylinux9
ANSIBLE_VERSION: "2.17"
- DISTRO: rockylinux9
ANSIBLE_VERSION: "2.18"
- DISTRO: alma10
ANSIBLE_VERSION: "2.18"

Différence avec GitHub Actions : la matrice GitLab est explicite (chaque combinaison listée). Plus verbeux, mais plus contrôlable, vous pouvez exclure des combinaisons facilement (pas besoin d'exclude:).

molecule-test:
needs: ["ansible-lint"]

molecule-test ne démarre que si ansible-lint a réussi. Sans needs, GitLab respecte juste l'ordre de stages: mais lance tous les jobs du stage simultanément, needs: permet le DAG (Directed Acyclic Graph) plus précis.

ansible-lint:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"

Le job ne tourne que sur :

  • les merge requests (équivalent pull requests GitHub).
  • les commits sur main (post-merge).

Pas sur les autres branches → économie CI minutes.

release:
rules:
- if: $CI_COMMIT_TAG

Le job ne tourne que quand un tag Git est créé (git tag -a v1.0.0). Workflow recommandé : tag depuis main → release automatique sur Galaxy.

Ces quatre variables se répartissent en deux familles qu'il vaut mieux ne pas confondre. Les trois premières sont prédéfinies par GitLab et renseignées à chaque exécution : elles servent à écrire des rules:. La dernière ligne regroupe les variables que vous déclarez dans parallel:matrix, et dont le nom est libre.

VariableDescription
$CI_COMMIT_TAGTag Git si déclencheur tag, vide sinon
$CI_COMMIT_BRANCHBranche du commit
$CI_PIPELINE_SOURCESource du pipeline (push, merge_request_event, schedule...)
$DISTRO, $ANSIBLE_VERSIONVariables de matrice (custom, définies dans parallel:matrix)

Le job release a besoin du token API Galaxy pour publier. Jamais en clair, utiliser les CI/CD Variables GitLab :

  1. Repo → Settings → CI/CD → Variables.

  2. Ajouter GALAXY_TOKEN avec Masked + Protected.

  3. Dans le job release :

    release:
    script:
    - ansible-galaxy role import --api-key=$GALAXY_TOKEN ...

Masked = token absent des logs CI. Protected = utilisable seulement sur branches/tags protégés (main, v*).

AspectGitHub ActionsGitLab CI
Matricestrategy.matrix: (auto-combinaisons)parallel:matrix: (explicite)
DAG entre jobsneeds:needs:
Cacheactions/cache@v4Native (cache:)
SecretsRepo settings → SecretsSettings → CI/CD → Variables
Scheduleon.schedule.cronPipeline schedules (UI)
Self-hosted runnersRunnersRunners (tags:)

Conclusion : les deux fonctionnent, GitLab CI est plus explicite, GitHub Actions plus concis. Choisir selon votre hébergement de code.

Le pipeline montré ici tient en trois décisions : découper en stages lint puis test, décliner les combinaisons avec parallel:matrix, et réserver la publication au seul déclencheur $CI_COMMIT_TAG. Ce lab vous fait écrire ce .gitlab-ci.yml de bout en bout, et la correction vérifie que les needs: créent bien le graphe attendu et que le job de release ne peut pas partir sur une simple poussée de branche.

Ces cinq symptômes se répartissent en deux familles. Les deux premiers sont des erreurs de fichier, une règle mal écrite ou une valeur numérique non quotée, et se corrigent en une ligne. Les trois derniers viennent de l'infrastructure, un secret mal déclaré, un runner introuvable ou une image trop maigre, et se règlent hors du .gitlab-ci.yml.

SymptômeCauseFix
Job ne se déclenche pasrules: mal écritTester avec ci-lint GitLab
parallel:matrix planteQuote string vs intANSIBLE_VERSION: "2.17" (avec quotes)
Token Galaxy en clair dans logsPas configuré MaskedCI/CD Variables → Edit → cocher Masked
Runner non dispotags: [docker] mais pas de runner avec ce tagVérifier les runners disponibles + adapter tags
apt-get lentimage: python:3.12-slim recharge à chaque jobCustom image avec deps pré-installées

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • GitLab CI = équivalent GitHub Actions pour les équipes auto-hébergées.
  • parallel:matrix: explicite > strategy.matrix.exclude: GitHub.
  • needs: entre stages = DAG précis.
  • rules: if pour limiter les déclencheurs (MR, main, tags).
  • CI/CD Variables Masked + Protected pour les tokens.
  • Versionner et publier : ce que déclenche réellement le job de release sur tag, côté Galaxy comme côté Automation Hub.
  • HashiCorp Vault / OpenBao : l'alternative aux variables CI/CD masquées dès que les secrets se multiplient.
  • Installer rôles Galaxy : épingler les dépendances pour qu'un pipeline rejoué six mois plus tard donne le même résultat.

Ce site vous est utile ?

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

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn