Aller au contenu
CI/CD & Automatisation medium

Lab 18 — Fiabilité et robustesse

9 min de lecture

logo gitlab

Un pipeline peut être propre, modulaire et malgré tout fragile. Il suffit d’une défaillance runner temporaire, d’un timeout non maîtrisé ou de deux déploiements concurrents pour casser la chaîne. Ce lab vous fait traiter cette couche de résilience.

  • Diagnostiquer une erreur de stage volontairement injectée
  • Ajouter retry avec un ciblage des causes transitoires
  • Poser des timeout explicites sur les jobs critiques
  • Utiliser resource_group pour sérialiser les déploiements

Cette étape correspond au passage d’un pipeline “fonctionnel” à un pipeline “opérationnel”. Dans la vraie vie, les échecs transitoires sont inévitables : runners indisponibles, congestion réseau, jobs longs qui s’accumulent, déploiements concurrents.

Ce lab est utile quand :

  • les pipelines échouent de manière intermittente ;
  • plusieurs déploiements se chevauchent ;
  • l’équipe veut réduire les faux négatifs CI.
  1. Basculez sur la branche de départ

    Fenêtre de terminal
    cd pipeline-craft
    git checkout starter/lab-18
  2. Lancez un lint branch-aware

    Fenêtre de terminal
    glab ci lint --dry-run --ref starter/lab-18
  3. Observez l’erreur attendue

    Le starter est volontairement invalide avec un stage orchestrate absent.

Vous devez d’abord rétablir un pipeline valide, puis renforcer sa robustesse sur les jobs sensibles.

  1. Ouvrez .gitlab-ci.yml

  2. Ajoutez le stage manquant orchestrate dans stages:

  3. Revalidez

    Fenêtre de terminal
    glab ci lint .gitlab-ci.yml
👉 Vérifier votre solution (Étape 1)

Le starter du lab 18 référence déjà des jobs d’orchestration, mais oublie le stage correspondant.

stages:
- lint
- test
- orchestrate
- build
- deploy
  1. Ajoutez un retry ciblé

    Indice : ciblez les causes transitoires infra, pas les erreurs applicatives.

  2. Ajoutez un timeout explicite

    Indice : le timeout doit rester réaliste pour un build Docker normal.

  3. Gardez interruptible: true sur les jobs non critiques de long run

👉 Vérifier votre solution (Étape 2)

1️⃣ Renforcement de docker-build dans ci/build.yml

Section intitulée « 1️⃣ Renforcement de docker-build dans ci/build.yml »
docker-build:
stage: build
needs:
- pytest-matrix
- run-child-pipeline
image: docker:27
services:
- docker:27-dind
variables:
<<: *docker_vars
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
timeout: 20m
interruptible: true
  1. Ajoutez resource_group pour éviter les déploiements concurrents

    Indice : utilisez un verrou distinct par environnement.

  2. Ajoutez timeout et retry raisonnables sur staging et production

  3. Conservez interruptible: false pour éviter une interruption de déploiement en cours

👉 Vérifier votre solution (Étape 3)
deploy-staging:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to staging..."
- ./scripts/deploy-demo.sh staging
resource_group: staging
retry:
max: 1
when:
- runner_system_failure
timeout: 10m
interruptible: false
rules:
- if: $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
deploy-production:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to production..."
- ./scripts/deploy-demo.sh production
resource_group: production
retry:
max: 1
when:
- runner_system_failure
timeout: 15m
interruptible: false
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
  1. Validation CI

    Fenêtre de terminal
    glab ci lint .gitlab-ci.yml
  2. Commit et push

    Fenêtre de terminal
    git add .gitlab-ci.yml ci/build.yml ci/deploy.yml
    git commit -m "ci: improve reliability with retry timeout and resource locks"
    git push origin starter/lab-18
  3. Vérifiez un run complet

👉 Vérifier votre solution (Étape 4)
  • le lint ne remonte plus l’erreur de stage manquant ;
  • docker-build supporte mieux les pannes transitoires runner/réseau ;
  • les déploiements sont sérialisés (resource_group) et non interruptibles ;
  • les timeouts explicites empêchent les jobs bloqués trop longtemps.
📄 Voir le fichier .gitlab-ci.yml complet
stages:
- lint
- test
- orchestrate
- build
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH
- if: $CI_COMMIT_TAG
default:
interruptible: true
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
include:
- local: ci/lint.yml
- local: ci/test.yml
- local: ci/orchestration.yml
- local: ci/build.yml
- local: ci/deploy.yml
📄 Voir le fichier ci/build.yml complet
.docker-vars: &docker_vars
DOCKER_TLS_CERTDIR: "/certs"
docker-build:
stage: build
needs:
- pytest-matrix
- run-child-pipeline
image: docker:27
services:
- docker:27-dind
variables:
<<: *docker_vars
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
timeout: 20m
interruptible: true
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker build -t $CI_REGISTRY_IMAGE:latest .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
📄 Voir le fichier ci/deploy.yml complet
deploy-staging:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to staging..."
- ./scripts/deploy-demo.sh staging
resource_group: staging
retry:
max: 1
when:
- runner_system_failure
timeout: 10m
interruptible: false
rules:
- if: $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
deploy-production:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to production..."
- ./scripts/deploy-demo.sh production
resource_group: production
retry:
max: 1
when:
- runner_system_failure
timeout: 15m
interruptible: false
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
  • Le lint ne renvoie plus l’erreur de stage
  • retry est ciblé sur des causes transitoires pertinentes
  • Les jobs critiques ont un timeout explicite
  • Les déploiements sont sérialisés via resource_group

Un retry trop large masque les vraies erreurs applicatives. Ciblez seulement les cas transitoires liés à l’infrastructure CI.

Ne mettez pas interruptible: true sur un job de production critique, sinon un nouveau pipeline peut interrompre un déploiement en cours.

  • Fiabiliser un pipeline, ce n’est pas seulement le faire passer une fois
  • retry, timeout et resource_group traitent des risques différents
  • Le starter cassé est un exercice de diagnostic, pas un accident
  • La résilience CI doit rester explicite et mesurable

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.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn