Aller au contenu
Infrastructure as Code medium

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

8 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 : linttest (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.
---
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
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
stages:
- lint
- test

Lint avant test = fail-fast.

default:
image: python:3.12-slim
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.

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.

Cette page a un lab d'accompagnement : labs/ci/gitlab/ dans stephrobert/ansible-training.

Le lab fournit .gitlab-ci.yml complet. 7 tests structure validés (stages, matrix, needs, rules, release).

Fenêtre de terminal
cd ~/Projets/ansible-training/labs/ci/gitlab/
cat .gitlab-ci.yml
pytest -v challenge/tests/ # 7 tests structure
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
  • 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.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. 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