Espace étudiants

Polytech Tours · Cours

CI/CD : de l'intégration
au déploiement continu

Comprendre les pipelines, le cycle de vie d'une release, les stratégies de déploiement et la culture DevOps.

Durée : 4 heures Ingénieurs 4ᵉ & 5ᵉ année 7 modules + annexe Git
Télécharger le cours magistral

Cours interactif, cliquez sur un module pour le déplier.

Objectifs pédagogiques

1
Introduction & objectifs
15 min · Pourquoi la CI/CD existe

1.1 Le problème que la CI/CD résout

Imaginez une équipe de développement il y a une vingtaine d'années. Dix développeurs travaillent chacun de leur côté pendant trois mois sur leur propre copie du code. Arrive le jour fatidique de l'intégration : on rassemble tout le travail de tout le monde. C'est ce qu'on appelait, sans rire, l'integration hell, l'enfer de l'intégration. Des milliers de lignes en conflit, des comportements incompatibles, des fonctionnalités qui marchaient isolément et qui s'effondrent une fois réunies. La mise en production se faisait un vendredi soir, à plusieurs, en croisant les doigts.

Ce modèle a un coût énorme :

  • Le coût du délai : entre le moment où une fonctionnalité est codée et celui où elle apporte de la valeur à l'utilisateur, il peut s'écouler des mois.
  • Le coût du risque : plus on accumule de changements avant de livrer, plus la livraison est grosse, plus elle est risquée. Un gros déploiement qui échoue est très difficile à diagnostiquer, quelle modification, parmi les centaines embarquées, a causé la panne ?
  • Le coût humain : la peur de déployer. Quand déployer fait peur, on déploie moins souvent, donc les lots grossissent, donc le risque augmente, donc la peur augmente. Un cercle vicieux.

La CI/CD est la réponse d'ingénierie à ce cercle vicieux. L'idée fondatrice tient en une phrase : si quelque chose fait mal, faites-le plus souvent. L'intégration fait mal ? Intégrez en continu, plusieurs fois par jour, par tout petits incréments. Le déploiement fait peur ? Déployez si souvent, et de façon si automatisée, que cela devienne un non-événement.

1.2 Les trois sigles à ne pas confondre

On parle de « CI/CD » comme d'un bloc, mais il y a en réalité trois concepts distincts, et leur distinction est au cœur de ce cours.

SigleNomDéfinition courte
CIContinuous Integration
(Intégration continue)
Chaque modification de code est fusionnée fréquemment dans une branche commune, puis automatiquement compilée et testée.
CDelContinuous Delivery
(Livraison continue)
Tout code qui passe la CI est automatiquement amené dans un état déployable. La mise en production reste déclenchée par un humain (un clic).
CDepContinuous Deployment
(Déploiement continu)
Tout code qui passe l'ensemble des tests est déployé en production automatiquement, sans intervention humaine.

La différence entre Delivery et Deployment est subtile mais structurante : c'est la présence ou l'absence d'un bouton humain avant la production. En Continuous Delivery, l'artefact est prêt, validé, à un clic de la prod, mais c'est une personne qui décide du moment. En Continuous Deployment, il n'y a plus de clic : le pipeline va jusqu'au bout tout seul.

À retenir : toute organisation faisant du Continuous Deployment fait nécessairement du Continuous Delivery, qui fait nécessairement de la CI. L'inverse n'est pas vrai, c'est un emboîtement : CI ⊂ Delivery ⊂ Deployment.

1.3 Objectifs pédagogiques

À la fin de ce cours, vous saurez : expliquer l'utilité d'une pipeline et distinguer CI / Delivery / Deployment ; décrire le cycle de vie d'une release ; comparer les stratégies de déploiement modernes ; comprendre les architectures actif/passif et actif/actif ; et mesurer une démarche CI/CD avec les métriques DORA.

2
Le cycle de vie d'une release
35 min · Environnements, recettes & gouvernance ITIL

2.1 Qu'est-ce qu'une release ?

Une release (ou « mise en production », ou « livraison ») est un ensemble cohérent de modifications du logiciel, identifié par une version, qui franchit une série d'étapes de validation avant d'être mis à disposition des utilisateurs finaux. Le mot-clé est cohérent : une release n'est pas « le code à un instant T », c'est un lot qu'on a décidé de faire avancer ensemble, tester ensemble, et déployer ensemble.

2.2 Les environnements

Le code ne passe jamais directement de la machine du développeur à la production. Il traverse une succession d'environnements, chacun étant une copie de l'application de plus en plus proche des conditions réelles.

EnvironnementRôleQui l'utilise
DEVLà où le code est écrit et testé pendant son écriture.Les développeurs
Intégration / CIEnvironnement éphémère où la pipeline assemble et teste automatiquement chaque modification.La pipeline
Recette interne
(staging)
Environnement stable où l'équipe valide les fonctionnalités avant de les montrer au client.QA, équipe projet
Recette externe
(UAT)
Environnement où le client / les utilisateurs métier valident que le produit répond au besoin.Client, utilisateurs clés
Pré-productionRéplique aussi fidèle que possible de la production. Tests techniques finaux.Ops, équipe technique
PRODL'environnement réel, utilisé par les vrais utilisateurs.Tout le monde

Un principe essentiel : la configuration doit être externalisée du code. Le même artefact doit pouvoir tourner sur n'importe quel environnement, la seule chose qui change étant la configuration injectée (URL de base de données, clés d'API, niveaux de log…). C'est le principe « build once, deploy anywhere » : on construit l'artefact une seule fois, et c'est exactement cet artefact-là, déjà testé, qu'on promeut d'environnement en environnement. Recompiler à chaque étape reviendrait à tester un objet et à en déployer un autre.

2.3 Le cheminement d'une release

Voici le parcours type d'une modification, du clavier du développeur jusqu'à l'utilisateur :

  Développement
       │   le développeur écrit le code et ses tests
       ▼
  Tests dev
       │   tests unitaires et d'intégration (poste / CI)
       ▼
  Recette interne
       │   validation fonctionnelle par la QA
       ▼
  Recette externe (UAT)
       │   validation par le client / les utilisateurs métier
       ▼
  Déploiement en production
       │   mise à disposition des utilisateurs finaux
       ▼
  Run / exploitation
           supervision, support, mesure

Chaque flèche est une porte de qualité (quality gate) : on ne franchit l'étape suivante que si la précédente est validée. La pipeline CI/CD (module 3) est l'outil qui automatise et fait respecter ces portes.

Recette interne vs recette externe

C'est une distinction qu'on confond souvent. Les deux sont des phases de validation, mais ne répondent pas à la même question :

  • La recette interne répond à : « Avons-nous bien construit le produit ? » Le logiciel est-il conforme aux spécifications, sans régression, stable ? C'est l'équipe (la QA) qui juge.
  • La recette externe (UAT) répond à : « Avons-nous construit le bon produit ? » Le logiciel répond-il réellement au besoin métier ? C'est le client / l'utilisateur final qui juge.

On peut parfaitement avoir un logiciel qui passe la recette interne (zéro bug, conforme au cahier des charges) mais qui échoue la recette externe, parce que le cahier des charges lui-même ne correspondait pas au vrai besoin.

2.4 Le versionnement : semantic versioning

Pour identifier une release, on lui donne un numéro de version. La convention la plus répandue est le Semantic Versioning (SemVer), au format MAJEUR.MINEUR.CORRECTIF, par exemple 2.4.1.

  • MAJEUR : changement incompatible avec les versions précédentes (breaking change).
  • MINEUR : ajout d'une fonctionnalité rétrocompatible.
  • CORRECTIF : correction de bug rétrocompatible.

En lisant 2.4.1 → 3.0.0, un intégrateur sait immédiatement qu'il y a un risque d'incompatibilité ; en lisant 2.4.1 → 2.4.2, il sait que c'est un correctif sans danger. Le numéro de version communique une intention.

2.5 La couche de gouvernance : ITIL

Jusqu'ici nous avons décrit le parcours technique d'une release. Mais dans une organisation, surtout une grande, une banque, un opérateur, ce parcours est encadré par une couche de gouvernance. Le référentiel le plus connu est ITIL (Information Technology Infrastructure Library), un ensemble de bonnes pratiques pour la gestion des services informatiques. Il est bien plus large que la CI/CD ; deux pratiques nous intéressent ici directement.

La gestion des changements

Tout changement apporté à un système en production est potentiellement risqué. La gestion des changements ITIL vise à ce que chaque changement soit évalué, autorisé et tracé. ITIL distingue trois types de changements :

  • Changement standard : faible risque, pré-autorisé, répétitif et bien connu. Pas d'autorisation au cas par cas.
  • Changement normal : doit être évalué et autorisé, souvent par un CAB (Change Advisory Board).
  • Changement urgent : à appliquer en urgence (ex. correctif d'une faille critique), avec une procédure d'autorisation accélérée.
Le lien fondamental avec la CI/CD : une pipeline mature et fiable permet de transformer des déploiements « changement normal » en « changement standard ». Si chaque release suit automatiquement le même chemin testé, audité, traçable et réversible, le déploiement devient répétitif et à faible risque, donc pré-autorisable. C'est ainsi qu'une organisation passe de « deux mises en production par an validées par un comité » à « plusieurs déploiements par jour », sans abandonner la gouvernance : la pipeline elle-même devient le contrôle.

La gestion des mises en production

Cette pratique ITIL planifie, coordonne et supervise la construction, le test et le déploiement des releases : que met-on dans la release, quand la déploie-t-on, comment communique-t-on, quel est le plan de retour arrière. À retenir : la pipeline CI/CD est la mise en œuvre technique ; ITIL est le cadre organisationnel. Une pipeline sans gouvernance, c'est de la vitesse sans direction ; une gouvernance sans pipeline, c'est de la lourdeur sans bénéfice.

3
La pipeline CI/CD
55 min · Anatomie, branches & outils

3.1 Qu'est-ce qu'une pipeline ?

Une pipeline (ou « chaîne ») CI/CD est une suite automatisée d'étapes que tout changement de code doit traverser, du commit jusqu'au déploiement. C'est la matérialisation, sous forme de code et d'automatisation, des portes de qualité vues au module 2. Le vocabulaire est globalement partagé entre les outils :

  • Trigger (déclencheur) : l'événement qui démarre la pipeline (un push, une merge request, une planification, un déclenchement manuel…).
  • Stage (étape) : un regroupement logique de travail (build, test, deploy…), exécuté en général séquentiellement.
  • Job (tâche) : une unité de travail dans un stage. Plusieurs jobs d'un même stage peuvent s'exécuter en parallèle.
  • Step / script : une commande élémentaire exécutée dans un job.
  • Runner / agent : la machine (souvent un conteneur) qui exécute concrètement les jobs.
  • Artefact : le produit d'un stage, conservé et transmis aux stages suivants (binaire, image conteneur, rapport de tests…).

3.2 Anatomie d'une pipeline : les quatre grandes étapes

 
 ┌──────────┐   ┌──────────────┐    ┌──────────────┐   ┌─────────────┐
 │  BUILD  │──▶│    TESTS    │──▶ │    TESTS   │──▶│ DÉPLOIEMENT│
 │         │   │ FONCTIONNELS│    │  TECHNIQUES │   │            │
 └──────────┘   └──────────────┘    └──────────────┘   └─────────────┘
  compile &       unitaires,        charge,            vers les
  produit         intégration,      sécurité,          environnements
  l'artefact      E2E, SonarQube    infrastructure     puis la prod

Étape 1 : Build

Déclenchée à chaque modification, cette étape récupère le code, résout les dépendances, compile si nécessaire, et produit un artefact, typiquement aujourd'hui une image conteneur (Docker). C'est l'objet immuable qui sera testé puis déployé : l'étape qui matérialise le principe « build once ». Si le build échoue, la pipeline s'arrête immédiatement.

Étape 2 : Tests fonctionnels

On vérifie ici que le logiciel fait ce qu'il doit faire. Cette étape contient plusieurs niveaux, représentés par la pyramide des tests :

            ╱╲          Tests E2E (end-to-end)
           ╱  ╲         lents, coûteux, peu nombreux
          ╱────╲
         ╱      ╲       Tests d'intégration
        ╱        ╲      moyens
       ╱───────────╲
      ╱            ╲    Tests unitaires
     ╱______________╲   rapides, peu coûteux, très nombreux
  • Tests unitaires : valident une fonction, une classe, isolément. Très rapides, on en a des milliers, ils tournent à chaque commit.
  • Tests d'intégration : valident que plusieurs composants fonctionnent ensemble (ex. code applicatif + base de données).
  • Tests end-to-end (E2E) : simulent un vrai parcours utilisateur de bout en bout, dans un navigateur (Cypress, Playwright, Selenium). Réalistes mais lents et fragiles, on en a peu.

La logique de la pyramide : beaucoup de tests rapides à la base, peu de tests lents au sommet. Une pipeline qui inverserait la pyramide (« cornet de glace ») serait lente et instable. On ajoute aussi l'analyse statique : linters et outils comme SonarQube, qui mesurent la qualité, la couverture et détectent les code smells sans exécuter le code.

Étape 3 : Tests techniques

On vérifie ici non plus ce que fait le logiciel, mais comment il se comporte en conditions réelles :

  • Tests de charge / performance : le système tient-il la montée en charge ? On simule des milliers d'utilisateurs (JMeter, k6, Gatling) et on mesure temps de réponse, débit, point de rupture.
  • Tests de sécurité : le SAST analyse le code source à la recherche de failles ; le DAST attaque l'application en fonctionnement ; l'analyse des dépendances (SCA) repère les bibliothèques tierces vulnérables.
  • Tests d'infrastructure : si l'infra est décrite sous forme de code (Infrastructure as Code, Terraform, Ansible), on la teste elle aussi.

Étape 4 : Déploiement

L'étape qui amène l'artefact validé dans un environnement, et finalement en production. La manière de déployer fait l'objet du module 4. C'est ici que se joue la frontière : en Continuous Delivery, le pipeline s'arrête au seuil de la production et attend une validation manuelle ; en Continuous Deployment, il franchit ce seuil automatiquement.

3.3 Le prérequis qu'on oublie : la stratégie de branches

On peut avoir la plus belle pipeline du monde : si l'équipe travaille mal avec Git, il n'y aura pas de vraie intégration continue. La stratégie de branches est le prérequis humain de la CI. Trois grands modèles coexistent.

  • GitFlow, modèle historique (2010), très structuré : branches main, develop, feature/*, release/*, hotfix/*. Puissant mais lourd : les branches de fonctionnalité vivent longtemps, ce qui recrée l'integration hell. Adapté aux logiciels versionnés livrés explicitement.
  • GitHub Flow, beaucoup plus simple : une seule branche durable, main, toujours déployable. Pour chaque travail, une branche courte, une pull request relue et testée par la CI, puis fusionnée. Adapté aux applications web.
  • Trunk-Based Development, le modèle considéré aujourd'hui comme le plus aligné avec la CI/CD. Tous les développeurs intègrent leur travail dans une branche unique (le trunk) au moins une fois par jour. Les branches, quand elles existent, vivent quelques heures.

Comment intégrer du code pas encore fini sans casser le trunk ? Deux techniques : les feature flags (on intègre le code, mais éteint, voir module 4) et le branch by abstraction (on fait évoluer le code derrière une couche d'abstraction stable).

Plus les branches sont courtes, plus l'intégration est réellement continue. Le trunk-based development n'est pas un détail d'outillage : c'est ce qui rend le mot « continue » de « CI » honnête.

3.4 Le panorama des outils

  • GitHub Actions : intégré à GitHub, configuration en YAML dans .github/workflows/. Très populaire, large écosystème d'actions réutilisables.
  • GitLab CI/CD : intégré à GitLab, configuration dans .gitlab-ci.yml. Solution très complète, du dépôt au déploiement.
  • Jenkins : l'outil historique, open-source, auto-hébergé, extrêmement extensible via plugins. Plus ancien, demande davantage de maintenance, mais encore très présent.

Le principe est partout le même : la pipeline est décrite dans un fichier versionné avec le code (pipeline as code). Elle est donc relue, historisée, et évolue avec le projet.

3.5 Exemple commenté : GitHub Actions

.github/workflows/ci.yml
name: CI/CD

# Déclencheur : à chaque push sur main et sur chaque pull request
on:
  push:
    branches: [ main ]
  pull_request:

jobs:
  build-and-test:
    runs-on: ubuntu-latest          # le runner : machine Ubuntu fournie par GitHub
    steps:
      - uses: actions/checkout@v4   # récupère le code du dépôt

      - name: Installer les dépendances
        run: npm ci                 # installation propre et reproductible

      - name: Build
        run: npm run build          # étape 1 - construction de l'artefact

      - name: Tests unitaires
        run: npm test               # étape 2 - tests fonctionnels

  deploy:
    needs: build-and-test           # ne s'exécute QUE si le job précédent réussit
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production         # GitHub peut exiger une validation manuelle ici
    steps:
      - uses: actions/checkout@v4
      - name: Déploiement
        run: ./deploy.sh            # étape 4 - déploiement

Points clés : le needs matérialise la porte de qualité (pas de déploiement si les tests échouent) ; le environment: production permet d'exiger une approbation humaine, c'est précisément le « bouton » du Continuous Delivery.

3.6 Exemple commenté : GitLab CI/CD

.gitlab-ci.yml
# Les étapes (stages), exécutées dans l'ordre
stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/                # l'artefact est transmis aux stages suivants

test-job:
  stage: test
  script:
    - npm test               # ne démarre que si le stage build a réussi

deploy-job:
  stage: deploy
  script:
    - ./deploy.sh
  environment: production
  rules:
    - if: $CI_COMMIT_BRANCH == "main"   # uniquement sur main
      when: manual                      # CONTINUOUS DELIVERY : clic requis
Le concept de « bouton » apparaît ici avec when: manual, placé à l'intérieur de la règle : la pipeline prépare tout, mais attend un clic humain pour la production. Remplacer when: manual par when: on_success ferait basculer le projet en Continuous Deployment. Une seule ligne sépare les deux régimes, c'est une décision d'organisation, pas de technologie.
4
Les stratégies de déploiement
40 min · Rolling, blue/green, canary, feature flags

4.1 Le problème : déployer sans casser

Une fois l'artefact validé, il faut le mettre en production. La question n'est pas anodine : à l'instant du déploiement, des utilisateurs sont en train d'utiliser l'ancienne version. Comment passer de l'ancienne à la nouvelle sans interruption de service, et en maîtrisant le risque qu'un défaut soit passé à travers tous les tests ?

C'est ce que résolvent les stratégies de déploiement. Le critère de comparaison principal : si la nouvelle version est défectueuse, combien d'utilisateurs sont impactés, et pendant combien de temps ?

4.2 Recreate (déploiement « brutal »)

La stratégie de base : on arrête l'ancienne version, puis on démarre la nouvelle.

   v1  v1  v1          (arrêt)           v2  v2  v2
  ┌──┐┌──┐┌──┐   ▶    ┌─────────┐   ▶   ┌──┐┌──┐┌──┐
  └──┘└──┘└──┘        │ INDISPO │       └──┘└──┘└──┘
                      └─────────┘

Avantage : simple, aucun risque de cohabitation entre versions. Inconvénient majeur : il y a une interruption de service pendant la bascule. À réserver aux environnements hors-production ou aux applications qui tolèrent une fenêtre de maintenance. C'est la référence de base à partir de laquelle on comprend les autres.

4.3 Rolling deployment (déploiement progressif)

On remplace les instances de l'ancienne version par la nouvelle une par une, progressivement. À tout moment, une partie des instances sert la v1, une autre la v2, et le service n'est jamais totalement interrompu.

Étape 1 :  v2  v1  v1  v1
Étape 2 :  v2  v2  v1  v1
Étape 3 :  v2  v2  v2  v1
Étape 4 :  v2  v2  v2  v2

Avantages : pas d'interruption ; pas besoin de doubler l'infrastructure. Inconvénients : pendant le déploiement, les deux versions coexistent, elles doivent être compatibles (notamment avec la base de données) ; le retour arrière est plus lent. C'est la stratégie par défaut de Kubernetes, donc l'une des plus répandues aujourd'hui.

4.4 Blue/Green deployment

On maintient deux environnements de production complets et identiques, Blue et Green. À un instant donné, un seul reçoit le trafic réel.

            ┌─────────────┐
   Trafic ─▶│   BLUE  v1  │  ◀── actif
            └─────────────┘
            ┌─────────────┐
            │  GREEN  v2  │  ◀── on déploie et teste ici, à blanc
            └─────────────┘

   puis on bascule le routeur :

            ┌─────────────┐
            │   BLUE  v1  │  ◀── passif (garde-fou pour le rollback)
            └─────────────┘
            ┌─────────────┐
   Trafic ─▶│  GREEN  v2  │  ◀── actif
            └─────────────┘

On déploie la v2 sur l'environnement inactif (Green), on l'y teste tranquillement, puis on bascule tout le trafic d'un coup en reconfigurant le routeur.

Avantages : bascule instantanée ; retour arrière instantané (il suffit de re-router vers Blue, resté intact). Inconvénients : il faut doubler l'infrastructure ; la bascule expose 100 % des utilisateurs d'un coup à la v2.

Lien avec le module 5 : le blue/green est l'expression « déploiement » d'une architecture actif/passif. Blue est actif, Green est passif, et déployer revient à faire une bascule.

4.5 Canary deployment

Le nom vient des canaris qu'on descendait dans les mines : si l'oiseau tombait, c'est que l'air était toxique, il servait de détecteur précoce. Ici, on expose la v2 à une petite fraction des utilisateurs (1 %, 5 %, 10 %…), on observe les métriques, et si tout va bien on augmente progressivement jusqu'à 100 %. Au moindre signal négatif, on rebascule les utilisateurs « canari » vers la v1.

   95 % des utilisateurs ──▶  v1  v1  v1  v1
    5 % des utilisateurs ──▶  v2          ◀── le « canari » observé

   métriques OK ? on monte à 25 %, puis 50 %, puis 100 %
   métriques KO ? on revient à 0 % - seuls 5 % ont été impactés

Avantages : c'est la stratégie qui minimise le rayon d'impact d'un défaut, au pire, quelques pour-cent d'utilisateurs touchés, brièvement. Inconvénients : la plus complexe à mettre en œuvre ; nécessite un routage fin du trafic et surtout une observabilité solide.

4.6 Feature flags (interrupteurs de fonctionnalité)

La technique la plus moderne, et celle qui change le plus la façon de penser. Un feature flag est un interrupteur, piloté par configuration, qui permet d'activer ou désactiver une fonctionnalité sans redéployer.

exemple conceptuel
if (featureFlags.isEnabled("nouveau-tunnel-paiement")) {
    afficherNouveauTunnel();
} else {
    afficherAncienTunnel();
}

L'idée-clé : les feature flags découplent le déploiement du release. Déployer, c'est mettre le code en production (acte technique). Releaser, c'est rendre une fonctionnalité visible aux utilisateurs (acte métier). On peut donc déployer du code éteint en production pendant des semaines (ce qui rend possible le trunk-based development), puis l'allumer quand on le décide, pour tous, ou pour un segment précis (test interne, beta, déploiement géographique progressif). En cas de problème, on éteint l'interrupteur : rollback instantané, sans aucun redéploiement (kill switch).

Inconvénients : génère de la dette technique si on ne supprime pas les vieux flags ; multiplie les chemins de code à tester ; demande un outillage de gestion des flags.

4.7 Tableau comparatif

StratégieInterruption ?Coût infraRayon d'impactRollbackComplexité
RecreateOuiFaible100 %LentTrès faible
RollingNonFaibleCroissantLentFaible
Blue/GreenNonÉlevé (×2)100 % (bref)InstantanéMoyenne
CanaryNonMoyenQuelques %RapideÉlevée
Feature flagsNonFaiblePilotableInstantanéMoyenne

Il n'y a pas de « meilleure » stratégie dans l'absolu. Le choix dépend du budget d'infrastructure, de la criticité du service, de la maturité de l'observabilité et du type d'application. Et ces stratégies se combinent : on peut faire un déploiement canary de code tout en pilotant l'exposition des fonctionnalités par feature flags.

4.8 Une note sur le rollback

Quelle que soit la stratégie, une règle d'or : un déploiement n'est jamais terminé tant qu'on ne sait pas revenir en arrière. Le plan de retour arrière fait partie de la release, au même titre que le code. Attention au point le plus piégeux : les migrations de base de données. Le code peut revenir en arrière instantanément ; une migration de schéma, beaucoup moins. D'où la pratique des migrations rétrocompatibles (la v1 et la v2 du code doivent toutes deux fonctionner avec le schéma courant), qui rend les déploiements zéro-downtime réellement sûrs.

5
Architecture & résilience : actif/passif & actif/actif
30 min · Haute disponibilité & reprise d'activité

5.1 Disponibilité et reprise d'activité

Déployer souvent et proprement, c'est bien. Mais que se passe-t-il si c'est l'infrastructure elle-même qui tombe, une panne de serveur, de datacenter, de région cloud ? C'est l'objet de la résilience, et elle conditionne directement la manière dont on livre.

  • Haute disponibilité (HA) : la capacité du système à rester opérationnel malgré la panne d'un composant. On l'obtient par la redondance : ne jamais avoir un seul exemplaire de quoi que ce soit.
  • Reprise d'activité (DR, Disaster Recovery) : la capacité à redémarrer le service après un sinistre majeur (perte d'un datacenter entier).

On mesure le DR avec deux indicateurs que tout ingénieur doit connaître :

  • RTO (Recovery Time Objective) : en combien de temps doit-on avoir rétabli le service ? (durée d'indisponibilité acceptable)
  • RPO (Recovery Point Objective) : quelle quantité de données peut-on se permettre de perdre, exprimée en temps ? (un RPO de 5 min = on accepte de perdre au maximum les 5 dernières minutes de données)
Note culture : dans le secteur bancaire et financier, ces sujets sont devenus une obligation réglementaire avec le règlement européen DORA, Digital Operational Resilience Act. À ne pas confondre avec les métriques DORA du module 6, qui n'ont aucun rapport : pure homonymie.

5.2 Architecture actif/passif

On dispose de (au moins) deux sites, deux datacenters, deux régions cloud. À un instant donné, le site actif traite l'intégralité du trafic ; le site passif est une réplique en attente, qui ne traite aucun trafic mais reçoit en permanence une réplication des données depuis le site actif.

                     ┌──────────────────┐
   Utilisateurs ───▶ │   SITE ACTIF     │
                     │   traite 100 %   │
                     └────────┬─────────┘
                              │ réplication des données
                              ▼
                     ┌──────────────────┐
                     │   SITE PASSIF    │   (en attente)
                     │   traite 0 %     │
                     └──────────────────┘

En cas de panne du site actif, on opère une bascule (failover) : le site passif devient actif et prend le trafic. Cette bascule peut être manuelle ou automatique, et se fait généralement en reconfigurant le DNS ou le load balancer.

Avantages : conception relativement simple ; pas de problème de cohérence puisqu'un seul site écrit les données à la fois. Inconvénients : le site passif est une ressource payée mais inexploitée en temps normal ; la bascule prend un certain temps (le RTO n'est pas nul) ; il faut tester régulièrement la bascule, sous peine de découvrir le jour J que le site passif ne fonctionne pas.

5.3 Architecture actif/actif

Ici, tous les sites traitent du trafic simultanément, en parallèle. Un répartiteur de charge (load balancer) distribue les utilisateurs entre eux.

                     ┌──────────────────┐
              ┌────▶ │  SITE A - actif  │  traite ~50 %
   Load       │      └──────────────────┘
   balancer ──┤             ↕ synchronisation bidirectionnelle
              │      ┌──────────────────┐
              └────▶ │  SITE B - actif  │  traite ~50 %
                     └──────────────────┘

Si un site tombe, l'autre absorbe tout le trafic : il n'y a quasiment pas d'interruption, le RTO tend vers zéro.

Avantages : aucune ressource gaspillée ; bascule quasi instantanée ; permet de répartir géographiquement les utilisateurs (chacun servi par le site le plus proche) ; absorbe mieux les pics de charge. Inconvénients : nettement plus complexe. Le défi central est la cohérence des données : si les deux sites acceptent des écritures en même temps, comment garantir qu'ils restent synchronisés sans conflit ? C'est un problème difficile (au cœur du théorème CAP), qui demande des bases de données et des architectures spécifiquement conçues pour cela.

5.4 Le lien avec la livraison

Pourquoi ce sujet dans un cours de CI/CD ? Parce que les stratégies de déploiement du module 4 sont, au fond, des applications de ces architectures :

  • Le blue/green est une architecture actif/passif : Blue actif, Green passif, et « déployer » = « basculer ». La même mécanique de bascule sert à la fois pour la résilience (panne) et pour la livraison (nouvelle version).
  • Un déploiement rolling ou canary suppose que l'application tourne déjà sur un parc redondant d'instances, donc une forme d'actif/actif à l'échelle des instances.
Une infrastructure conçue pour la résilience est aussi une infrastructure conçue pour le déploiement sans interruption. Survivre à une panne et livrer une nouvelle version se résolvent avec les mêmes briques : redondance, réplication, et capacité à rerouter le trafic.
6
Culture DevOps & mesure de la performance
25 min · Méthodes de dev, DevOps & métriques DORA

6.1 Rappel express : les méthodes de développement

La CI/CD ne tombe pas du ciel : elle prolonge une évolution des méthodes de développement.

  • Le modèle historique en cascade (waterfall) enchaîne des phases longues et figées (spécification → conception → développement → test → livraison). Rigide, et l'erreur de cadrage ne se découvre qu'à la fin.
  • Les méthodes agiles (manifeste Agile, 2001) y répondent par des cycles courts et itératifs, l'adaptation au changement et la livraison fréquente de valeur. Les deux cadres les plus utilisés : Scrum (le travail organisé en sprints de 1 à 4 semaines, avec des rôles, Product Owner, Scrum Master, équipe, et des rituels) et Kanban (un flux continu de tâches visualisées sur un tableau, avec une limite du travail en cours).

Le lien avec la CI/CD est direct : livrer en fin de chaque sprint n'a de sens que si livrer est devenu rapide et fiable. L'agilité crée la demande de livraisons fréquentes ; la CI/CD en fournit le moyen technique.

6.2 La culture DevOps

Pendant longtemps, deux équipes se sont fait face : les Dev (qui veulent livrer du changement vite) et les Ops (qui veulent garantir la stabilité). Leurs objectifs semblaient opposés, c'est le fameux « mur de la confusion » : le Dev « jette » son code par-dessus le mur, et l'Ops se débrouille en production.

DevOps est le mouvement culturel qui abat ce mur. Ce n'est pas un outil, ni un poste, ni une équipe : c'est un ensemble de principes.

  • Responsabilité partagée : « You build it, you run it. » L'équipe qui développe est aussi responsable du bon fonctionnement en production.
  • Automatisation : tout ce qui est répétitif et manuel (build, tests, déploiement, provisionnement d'infra) doit être automatisé, c'est précisément la pipeline.
  • Mesure : on pilote avec des données, pas avec des impressions (voir 6.3).
  • Amélioration continue : les incidents donnent lieu à des post-mortems sans blâme, on cherche la cause systémique, pas le coupable.

On entend aussi parler de SRE (Site Reliability Engineering), l'approche formalisée par Google. Elle introduit la notion d'error budget : on ne vise pas 100 % de disponibilité (impossible et ruineux) ; on définit un objectif réaliste (par exemple 99,9 %), et la différence, les 0,1 %, est un « budget » que l'équipe peut dépenser. Tant qu'il reste du budget, on déploie vite. S'il est épuisé, on gèle les nouveautés pour se concentrer sur la fiabilité. Le budget d'erreur réconcilie ainsi, chiffres à l'appui, la vitesse des Dev et la stabilité des Ops.

6.3 Mesurer : les métriques DORA

Comment savoir si une démarche CI/CD est bonne ? Le programme de recherche DORA (DevOps Research and Assessment, racheté par Google) a identifié quatre métriques clés qui prédisent la performance d'une équipe logicielle. Elles se répartissent en deux familles.

FamilleMétriqueQuestion posée
VitesseFréquence de déploiementÀ quelle fréquence l'organisation déploie-t-elle en production ?
Lead Time for ChangesCombien de temps s'écoule entre un commit et sa mise en production ?
StabilitéChange Failure RateQuel % des déploiements provoque une dégradation nécessitant une correction ?
Recovery Time (MTTR)En cas d'incident causé par un changement, en combien de temps rétablit-on le service ?
Le résultat le plus important, et le plus contre-intuitif, de ces recherches : vitesse et stabilité ne s'opposent pas, elles vont de pair. Les organisations « Elite » déploient le plus souvent et ont les taux d'échec les plus bas. La raison est cohérente avec tout ce cours : déployer souvent, c'est déployer de petits lots ; de petits lots sont moins risqués, plus faciles à tester et à corriger. La vitesse bien outillée produit la stabilité.

Ces métriques sont précieuses car elles donnent un objectif mesurable : améliorer une pipeline, ce n'est pas une question de goût, cela se constate sur ces quatre chiffres.

7
Synthèse, ressources & lien avec le TP
15 min · Récapitulatif

7.1 Les idées à retenir

  • « Si quelque chose fait mal, faites-le plus souvent. » Intégrer et déployer en continu, par petits incréments, pour transformer un événement risqué en non-événement.
  • CI ⊂ Continuous Delivery ⊂ Continuous Deployment. La frontière entre Delivery et Deployment est un simple bouton humain avant la production.
  • Une release traverse une chaîne d'environnements et de portes de qualité ; recette interne (« a-t-on bien construit ? ») et recette externe (« a-t-on construit le bon produit ? ») ne posent pas la même question.
  • La pipeline automatise ces portes : build → tests fonctionnels → tests techniques → déploiement. Son vrai prérequis est humain : une stratégie de branches à branches courtes (trunk-based development).
  • Les stratégies de déploiement se choisissent selon le rayon d'impact acceptable : recreate, rolling, blue/green, canary, feature flags. Les feature flags découplent déployer de releaser.
  • Les architectures actif/passif et actif/actif servent la résilience et la livraison sans interruption, ce sont les mêmes briques.
  • DevOps est une culture (responsabilité partagée, automatisation, mesure) ; les 4 métriques DORA prouvent que vitesse et stabilité progressent ensemble.

7.2 Pour aller plus loin

  • Continuous Delivery, Jez Humble & David Farley, l'ouvrage de référence.
  • Accelerate, Forsgren, Humble & Kim, le livre qui présente la recherche DORA.
  • The Phoenix Project, Gene Kim, un roman pédagogique sur la culture DevOps.
  • Le rapport annuel State of DevOps (DORA / Google Cloud).
  • La documentation officielle de GitHub Actions et de GitLab CI/CD, pour pratiquer.

7.3 Lien avec le TP

Le travail pratique associé à ce cours a un objectif simple et direct : construire vous-mêmes une pipeline de CI/CD sur un projet applicatif, et faire un peu de développement. L'enjeu n'est pas la taille de l'application, mais de vivre concrètement ce que ce cours a décrit : un déclencheur sur un push, un build qui produit un artefact, des tests qui font office de porte de qualité, et un déploiement automatisé. C'est en voyant sa propre pipeline passer au vert, ou au rouge, qu'on saisit vraiment l'essence de la CI/CD.

8
Annexe Git : guide pratique & cheat sheet
Complément · à consulter en autonomie
Cette annexe est un module complémentaire, à lire en autonomie ou à parcourir en début de TP. Elle ne consomme pas le budget des 4 heures, mais elle est le prérequis pratique de tout le reste : sans une aisance minimale avec Git, la stratégie de branches du module 3 et la notion même de trigger sur push restent abstraites. Si une seule chose vous bloque dans le TP, ce sera probablement Git, d'où cette fiche.

8.1 Le bon modèle mental

Git n'est pas un « dossier synchronisé dans le cloud ». C'est un système de gestion de versions distribué : chaque développeur possède sur sa machine une copie complète de l'historique du projet. Pour bien l'utiliser, il faut visualiser trois zones en local, plus le dépôt distant.

  Répertoire de       Zone de            Dépôt local        Dépôt distant
  travail             préparation        (historique)       (GitHub / GitLab)
  (working dir)       (staging / index)
       │                   │                  │                   │
       │── git add ───────▶│                  │                   │
       │                   │── git commit ───▶│                   │
       │                   │                  │── git push ──────▶│
       │◀──────────── git pull  /  git clone ──────────────────────│
  • Répertoire de travail : vos fichiers, tels que vous les modifiez.
  • Zone de préparation (staging / index) : un sas où vous sélectionnez ce qui ira dans le prochain commit. C'est ce qui permet de ne committer qu'une partie de vos modifications.
  • Dépôt local : l'historique de tous les commits, sur votre machine. On peut y travailler sans connexion.
  • Dépôt distant (remote, appelé origin par défaut) : la copie partagée, avec laquelle on synchronise.

Un commit est un instantané (snapshot) de l'état du projet à un instant donné, identifié par une empreinte unique (un hash). Une branche n'est rien d'autre qu'un pointeur mobile vers un commit. Comprendre ces quelques objets, c'est comprendre l'essentiel de Git.

8.2 Le workflow d'une journée de développement

une journée type
1.  git pull                              # récupérer les derniers changements
2.  git switch -c feature/ma-fonction      # créer une branche de travail
3.  ... coder ...
4.  git status                            # voir ce qui a changé
5.  git add fichier1 fichier2              # préparer les fichiers
6.  git commit -m "feat: ajoute X"         # enregistrer un commit
        ↑ répéter 3→6 par petits incréments
7.  git push -u origin feature/ma-fonction # publier la branche
8.  ... ouvrir une Pull / Merge Request ...
9.  ... relecture + CI verte → fusion dans main ...
Règle d'or : commitez petit et souvent, poussez régulièrement. Un commit doit représenter une idée cohérente, pas trois jours de travail mélangés. Plus vos commits sont petits, plus l'historique est lisible et plus un retour arrière est facile. C'est exactement le principe des « petits lots » du module 1.

8.3 Les branches en pratique

Une branche permet de travailler sur une fonctionnalité sans perturber le code stable (main).

branches
git branch                       # lister les branches existantes
git switch -c feature/login      # créer une branche ET basculer dessus
git switch main                  # revenir sur main
git merge feature/login          # fusionner dans la branche courante
git branch -d feature/login      # supprimer une branche devenue inutile
Note : git switch et git restore (Git 2.23+) remplacent l'ancien git checkout, qui faisait trop de choses à la fois. Vous croiserez encore beaucoup git checkout dans les tutoriels : sachez que git checkout -bgit switch -c.

Le choix de la stratégie de branches (GitFlow, GitHub Flow, trunk-based) est traité au module 3.3. Pour un TP, le plus simple et le plus sain est le GitHub Flow : main toujours stable, une branche courte par fonctionnalité, une Pull Request pour fusionner.

8.4 Collaborer : Pull Requests et conflits

La Pull Request (GitHub) ou Merge Request (GitLab) est la demande de fusionner votre branche dans main. Elle a trois rôles : déclencher la relecture par les pairs (code review), déclencher la pipeline CI automatiquement, et tracer la discussion. On ne fusionne que si la review est validée et la CI est verte, c'est une porte de qualité (module 2).

Un conflit de fusion survient quand deux branches ont modifié les mêmes lignes d'un fichier. Git ne peut pas décider à votre place et marque la zone ainsi :

marqueurs de conflit
<<<<<<< HEAD
le code de la branche courante
=======
le code de la branche que l'on fusionne
>>>>>>> feature/login

Pour le résoudre : ouvrez le fichier, choisissez la bonne version (en supprimant les marqueurs <<<, ===, >>>), puis git add fichier-resolu suivi de git commit. Un conflit n'est pas une erreur ni un drame : c'est juste Git qui vous demande de trancher. Les conflits sont d'autant plus rares et petits que l'on intègre souvent (revoilà la CI).

8.5 Les commandes de sauvetage (« au secours »)

Ce sont les commandes qui rassurent : presque tout est rattrapable avec Git.

rattrapage
git restore fichier            # annuler les modifs NON commitées d'un fichier
git restore --staged fichier   # retirer un fichier du staging
git stash                      # mettre de côté tout le travail en cours...
git stash pop                  # ...et le récupérer plus tard
git revert <hash>              # créer un commit qui ANNULE un commit (sûr)
git reset --soft HEAD~1        # annuler le dernier commit, GARDER les modifs
git reset --hard HEAD          # /!\ DANGER : tout réinitialiser, modifs PERDUES
git reflog                     # historique de TOUS les déplacements de HEAD
  • git revert vs git reset : revert ajoute un nouveau commit qui défait un ancien, sans réécrire l'histoire, donc sûr sur une branche partagée. reset réécrit l'histoire, à réserver à des commits locaux non encore poussés.
  • git reflog est le filet de sécurité ultime. Même après un reset --hard malheureux, Git garde la trace de l'ancien commit pendant des semaines : reflog permet de retrouver son empreinte et d'y revenir. Tant qu'un travail a été commité au moins une fois, il est presque toujours récupérable.

8.6 Bonnes pratiques & messages de commit

  • Committez tôt, committez souvent. Un commit = une idée.
  • Soignez le message de commit. Une convention répandue, Conventional Commits, préfixe le message par un type : feat: (fonctionnalité), fix: (correction), docs:, test:, refactor:, chore:. Ces préfixes se relient au Semantic Versioning du module 2 (feat: → version mineure, fix: → correctif).
  • Ne committez jamais de secrets (mots de passe, clés d'API, tokens) ni de fichiers générés (node_modules/, dist/, .env). Listez-les dans un fichier .gitignore à la racine du dépôt.
  • Faites git pull avant de commencer à travailler et avant de pousser, pour limiter les conflits.
  • Une branche = une fonctionnalité, et une branche courte (quelques heures à quelques jours, pas quelques semaines).

8.7 Cheat sheet Git

Démarrer & configurer

CommandeEffet
git config --global user.name "Nom"Définir son nom (une fois)
git config --global user.email "mail"Définir son email (une fois)
git clone <url>Cloner un dépôt distant existant
git initInitialiser un dépôt dans le dossier courant

Au quotidien

CommandeEffet
git statusVoir l'état des fichiers (le réflexe à avoir)
git add <fichier>Préparer un fichier pour le commit
git add .Préparer toutes les modifications
git commit -m "message"Enregistrer un commit
git commit -am "message"add + commit des fichiers déjà suivis
git pushEnvoyer ses commits au dépôt distant
git pullRécupérer et fusionner les commits distants
git fetchRécupérer les commits distants sans fusionner

Branches

CommandeEffet
git branchLister les branches
git switch <branche>Changer de branche
git switch -c <branche>Créer une branche et basculer dessus
git merge <branche>Fusionner une branche dans la branche courante
git branch -d <branche>Supprimer une branche
git push -u origin <branche>Publier une branche pour la première fois

Inspecter

CommandeEffet
git log --oneline --graphHistorique compact et visuel
git diffModifications non encore préparées
git diff --stagedModifications préparées (en staging)
git show <hash>Détail d'un commit précis
git blame <fichier>Voir qui a modifié chaque ligne

Réparer & sauver

CommandeEffet
git restore <fichier>Annuler les modifs non commitées d'un fichier
git restore --staged <fichier>Retirer un fichier du staging
git stash / git stash popMettre de côté / récupérer le travail en cours
git revert <hash>Annuler un commit via un nouveau commit (sûr)
git reset --soft HEAD~1Annuler le dernier commit, garder les modifs
git reset --hard HEAD/!\ Tout réinitialiser, modifs perdues
git reflogRetrouver un commit « perdu » (filet de sécurité)
git cherry-pick <hash>Appliquer un commit précis sur la branche courante