The DevOps Handbook
Chapitre 2 / 14 · 16 min de lecture

La Première Voie : les principes du Flux

Accélérer le flux de gauche à droite, du développement vers le client : rendre le travail visible, limiter l'en-cours, réduire la taille des lots et éliminer le gaspillage.

Dans la chaîne de valeur technologique (technology value stream), le travail circule typiquement du développement vers l'exploitation — les deux maillons situés entre l'entreprise et ses clients. La Première Voie (The First Way) exige un flux rapide et fluide de ce travail, du développement (Development) vers l'exploitation (Operations), afin de livrer vite de la valeur au client. Là où Accelerate établissait par la recherche pourquoi la vitesse fiable compte, ce chapitre décrit comment l'obtenir : on optimise un objectif global plutôt que des optima locaux — taux d'achèvement de fonctionnalités côté dev, ratio détection/correction des tests, ou mesures de disponibilité côté ops.

On augmente le flux en rendant le travail visible, en réduisant la taille et l'intervalle des lots, et en intégrant la qualité dès la conception (building quality in) pour empêcher les défauts de se propager en aval. En accélérant le passage à travers la chaîne de valeur, on réduit le délai de livraison (lead time) nécessaire pour satisfaire les demandes des clients internes comme externes — gagnant au passage en qualité, en agilité, et en capacité à « expérimenter plus vite que la concurrence ». L'objectif : diminuer le temps requis pour déployer un changement en production, tout en augmentant la fiabilité et la qualité des services. Les indices de méthode, on les glane dans la façon dont les principes lean ont transformé la chaîne de valeur manufacturière.

Rendre le travail visible

Une différence majeure sépare la chaîne de valeur technologique de la chaîne manufacturière : notre travail est invisible. Contrairement aux processus physiques, on ne voit pas aisément où le flux est entravé, ni où le travail s'accumule devant un poste contraint. Transférer du travail entre postes, en usine, est lent et hautement visible — il faut déplacer physiquement des stocks.

Dans le logiciel, au contraire, le transfert se fait d'un clic : réassigner un ticket à une autre équipe. Parce que c'est si facile, le travail peut rebondir indéfiniment entre équipes faute d'informations complètes, ou être poussé en aval avec des problèmes qui restent totalement invisibles — jusqu'au jour où l'on est en retard sur ce qu'on avait promis, ou que l'application tombe en production.

Pour voir où le flux est bon et où il est en file d'attente ou bloqué, il faut rendre le travail aussi visible que possible. L'une des meilleures méthodes consiste à utiliser des tableaux visuels — tableaux kanban ou tableaux de planification de sprint — où l'on représente le travail sur des cartes physiques ou électroniques. Le travail naît à gauche (souvent tiré depuis un backlog), est tiré de poste en poste (les colonnes), et s'achève en atteignant la droite, dans une colonne « Terminé » ou « En production ».

Exigences  →  Dev (en cours | fait)  →  Test  →  Staging  →  En production
  ┌────┐        ┌────┐  ┌────┐          ┌────┐    ┌────┐        ┌────┐
  │ #4 │        │ #2 │  │ #1 │          │    │    │    │        │    │
  │ #5 │        │ #3 │  │    │          │    │    │    │        │    │
  └────┘        └────┘  └────┘          └────┘    └────┘        └────┘
  (backlog)     ◄──── le travail est TIRÉ de gauche à droite ────►
   délai de livraison = du dépôt de la carte à la colonne « En production »

Le travail devient non seulement visible, mais pilotable, de sorte qu'il s'écoule de gauche à droite aussi vite que possible. On peut même mesurer le délai de livraison : du moment où la carte est posée sur le tableau jusqu'à son entrée dans la colonne « Terminé ». Idéalement, le tableau couvre toute la chaîne de valeur : le travail n'est « terminé » que lorsqu'il atteint la droite. Une fonctionnalité dont le dev a achevé l'implémentation n'est pas terminée ; elle ne l'est que lorsque l'application tourne en production et délivre de la valeur au client.

Astuce

En mettant tout le travail de chaque poste en file d'attente visible, toutes les parties prenantes priorisent plus facilement dans le contexte des objectifs globaux. Chaque poste peut alors se concentrer sur une seule tâche (single-task) — la plus prioritaire — jusqu'à son achèvement, augmentant le débit (throughput).

Limiter l'en-cours (WIP)

En production manufacturière, le travail quotidien est dicté par un plan généré régulièrement — quotidiennement, hebdomadairement — qui établit quels travaux lancer selon les commandes, les échéances, les pièces disponibles. Dans le logiciel, le travail est bien plus dynamique, surtout dans les services partagés (shared services), où les équipes doivent satisfaire les demandes d'innombrables parties prenantes. Le quotidien y est dominé par la « priorité du jour », les demandes urgentes affluant par tous les canaux imaginables : systèmes de tickets, outage calls, courriels, téléphone, salons de discussion, et escalades managériales.

En usine, interrompre une production est coûteux et visible : il faut souvent casser le travail en cours et mettre au rebut tout ce qui est inachevé. Cet effort élevé décourage les interruptions fréquentes. Dans le logiciel, au contraire, interrompre un travailleur est trivial — les conséquences sont invisibles pour presque tout le monde — alors même que l'impact négatif sur la productivité peut être bien supérieur à celui de l'usine. Un ingénieur affecté à plusieurs projets doit basculer de tâche en tâche (task switching), payant à chaque fois le coût de la reconstitution du contexte, des règles cognitives et des objectifs.

Attention

Des études ont montré que le temps pour accomplir des tâches même simples — comme trier des formes géométriques — se dégrade significativement en situation de multitâche (multitasking). Or notre travail dans la chaîne de valeur technologique est cognitivement bien plus complexe que trier des formes : l'effet du multitâche sur le temps de cycle y est donc bien pire encore.

On limite le multitâche en codifiant et en faisant respecter des limites d'en-cours (WIP, work in progress) sur chaque colonne ou poste — un plafond sur le nombre de cartes pouvant s'y trouver. Par exemple, on peut fixer une limite de trois cartes en test. Quand trois cartes occupent déjà la voie « test », aucune nouvelle carte ne peut y entrer tant qu'une carte n'est pas achevée ou renvoyée vers la colonne de gauche, remise en file. Et rien ne peut être travaillé sans être d'abord matérialisé par une carte — ce qui renforce que tout travail doit être rendu visible.

Dominica DeGrandis, l'une des principales expertes des kanbans dans les chaînes de valeur DevOps, note que « contrôler la taille de la file [le WIP] est un levier de management extrêmement puissant, car c'est l'un des rares indicateurs avancés du délai de livraison — pour la plupart des éléments de travail, on ne sait pas combien de temps ils prendront tant qu'ils ne sont pas réellement achevés. »

Limiter le WIP rend aussi plus visibles les problèmes qui empêchent le travail d'aboutir. Quand on limite l'en-cours, il arrive qu'on n'ait rien à faire parce qu'on attend quelqu'un d'autre. Tentant alors de commencer du nouveau travail (« mieux vaut faire quelque chose que rien ») — mais la bien meilleure action consiste à trouver ce qui cause le retard et à aider à le résoudre. Le mauvais multitâche surgit précisément quand les gens sont affectés à plusieurs projets, multipliant les problèmes de priorisation.

Note

Taiichi Ohno comparait l'imposition de limites de WIP au fait de drainer l'eau de la rivière des stocks afin de révéler tous les problèmes qui obstruent le flux rapide. Comme le résume David J. Andersen, auteur de Kanban, en une formule devenue célèbre : « Stop starting. Start finishing. » — cessez de commencer, commencez à finir.

Réduire la taille des lots

L'autre composante clé d'un flux fluide et rapide est de travailler en petits lots (small batch sizes). Avant la révolution lean, on fabriquait par gros lots, surtout là où le réglage ou le changement d'outillage était long ou coûteux. Produire de grands panneaux de carrosserie exige d'installer des matrices lourdes sur des presses à emboutir — une opération qui pouvait prendre des jours. Quand le coût de changement est si élevé, on emboutit autant de panneaux que possible d'un coup, en gros lots, pour réduire le nombre de changements.

Mais les gros lots font exploser l'en-cours et injectent une forte variabilité dans le flux, qui se propage dans toute l'usine. Résultat : délais longs et qualité médiocre — si un défaut apparaît sur un panneau, c'est tout le lot qu'il faut mettre au rebut. La leçon centrale du lean : pour raccourcir les délais et accroître la qualité, il faut réduire continuellement la taille des lots. La limite théorique basse est le flux unitaire (single-piece flow), où chaque opération porte sur une seule unité à la fois.

L'écart entre gros et petits lots se voit de façon spectaculaire dans la fameuse simulation d'envoi de newsletters décrite dans Lean Thinking de James P. Womack et Daniel T. Jones. Supposons dix brochures à expédier, chacune requérant quatre étapes : plier la feuille, l'insérer dans l'enveloppe, fermer l'enveloppe, l'affranchir.

La stratégie « gros lot » (production de masse) exécute une opération sur les dix brochures avant de passer à la suivante : plier les dix feuilles, puis toutes les insérer, puis fermer les dix enveloppes, puis les affranchir. La stratégie « petit lot » (flux unitaire) enchaîne au contraire les quatre étapes d'une brochure avant de commencer la suivante : plier, insérer, fermer, affranchir — puis seulement recommencer.

Chaque étape = 10 secondes par enveloppe, pour 10 enveloppes.

GROS LOT (production de masse)
plier ×10 │ insérer ×10 │ fermer ×10 │ affranchir ×10
1ʳᵉ enveloppe terminée après ....................... 310 s
erreur de pliage ? détectée au plus tôt à 200 s,
puis il faut TOUT replier et réinsérer (les 10).

PETIT LOT (flux unitaire / single-piece flow)
plier→insérer→fermer→affranchir  (puis l'unité suivante)
1ʳᵉ enveloppe terminée après ......................... 40 s   (8× plus vite)
erreur de pliage ? on ne refait QUE la brochure concernée.

La première enveloppe sort en 310 secondes en gros lot, contre 40 secondes en flux unitaire — huit fois plus vite. Pire, si l'on découvre lors de la fermeture une erreur de pliage faite à la première étape, en gros lot on ne la détecte au plus tôt qu'à deux cents secondes, et il faut replier et réinsérer les dix brochures ; en petit lot, on n'en refait qu'une. Les petits lots produisent moins d'en-cours, des délais plus courts, une détection plus rapide des erreurs et moins de retouches.

Ces effets négatifs des gros lots valent tout autant dans le logiciel. Pensons à un calendrier de livraison annuel, où une année entière de code part d'un coup en production : comme en usine, cette « grosse livraison » crée des pics soudains de WIP et des perturbations massives en aval, d'où flux et qualité dégradés. Cela valide une expérience commune : plus le changement poussé en production est gros, plus les erreurs sont difficiles à diagnostiquer et longues à corriger.

Comme l'écrit Eric Ries sur Startup Lessons Learned, « la taille de lot est l'unité selon laquelle les produits du travail se déplacent entre les étapes d'un processus [DevOps]. Pour le logiciel, le lot le plus facile à voir, c'est le code : chaque fois qu'un ingénieur intègre du code, il regroupe une certaine quantité de travail. » De la branche traditionnelle, où le code de plusieurs développeurs travaillant des semaines est agrégé puis intégré, jusqu'aux lots minuscules du déploiement continu — il existe tout un éventail de techniques. L'équivalent du flux unitaire dans le logiciel est le déploiement continu (continuous deployment), où chaque changement intégré en gestion de version est construit, testé et déployé en production.

Réduire le nombre de transferts

Quand les délais de déploiement se comptent en mois, c'est souvent parce qu'il faut des centaines — voire des milliers — d'opérations pour faire passer le code de la gestion de version à la production. Transmettre du code à travers la chaîne mobilise de multiples départements sur des tâches variées : tests fonctionnels, tests d'intégration, création d'environnements, administration des serveurs, du stockage, du réseau, répartition de charge, sécurité de l'information.

Chaque fois que le travail passe d'une équipe à l'autre, il exige une foule de communications : demander, spécifier, signaler, coordonner, prioriser, planifier, arbitrer, tester, vérifier. Cela mobilise différents systèmes de tickets, des documents de spécification, des réunions, des courriels, des partages de fichiers, des serveurs FTP, des pages wiki. Chacune de ces étapes est une file d'attente potentielle où le travail patiente dès qu'on dépend de ressources partagées entre plusieurs chaînes de valeur (par exemple, une exploitation centralisée). Les délais sont si longs qu'il faut sans cesse escalader pour faire avancer les choses.

Même dans le meilleur des cas, un peu de savoir se perd inévitablement à chaque transfert (handoff). Avec assez de transferts, le travail peut perdre tout le contexte du problème à résoudre ou de l'objectif organisationnel poursuivi. Un administrateur de serveurs voit arriver un ticket demandant la création de comptes utilisateurs sans savoir pour quelle application, ni pourquoi, ni quelles sont les dépendances, ni s'il s'agit d'un travail récurrent.

Pour atténuer ces problèmes, on cherche à réduire le nombre de transferts : soit en automatisant des pans entiers du travail, soit en réorganisant les équipes pour qu'elles puissent livrer elles-mêmes la valeur au client, plutôt que d'être perpétuellement dépendantes des autres. On augmente ainsi le flux en réduisant le temps passé en file d'attente et le temps sans valeur ajoutée (non–value-added time).

Identifier et élever continuellement la contrainte

Pour réduire les délais et augmenter le débit, il faut identifier continuellement les contraintes du système et améliorer leur capacité de travail. Dans Beyond the Goal, le Dr Goldratt énonce le principe fondateur de sa Théorie des Contraintes : « Dans toute chaîne de valeur, il y a toujours une direction d'écoulement, et toujours une seule et unique contrainte ; toute amélioration apportée ailleurs qu'à cette contrainte est une illusion. » Améliorer un poste situé avant la contrainte ne fait qu'empiler le travail plus vite encore devant le goulot ; améliorer un poste situé après le laisse affamé, en attente que le travail franchisse le goulot.

Goldratt définit en réponse ses cinq étapes de focalisation (five focusing steps) :

1. Identifier la contrainte du système.
2. Décider comment EXPLOITER au mieux la contrainte.
3. SUBORDONNER tout le reste à cette décision.
4. ÉLEVER la contrainte (augmenter sa capacité).
5. Si la contrainte a été brisée, revenir à l'étape 1
   — sans laisser l'INERTIE créer une nouvelle contrainte.

Dans une transformation DevOps typique, à mesure qu'on passe de délais en mois ou trimestres à des délais en minutes, la contrainte suit une progression caractéristique — étant entendu que cette progression est une généralisation des transformations courantes, et non une loi universelle :

ContrainteSymptômeContre-mesure
Création d'environnementsOn attend des semaines ou des mois un environnement de prod ou de testEnvironnements à la demande, entièrement en libre-service, toujours disponibles
Déploiement du codeChaque déploiement prend des semaines (jusqu'à 1 300 étapes manuelles, sujettes à l'erreur, mobilisant trois cents ingénieurs)Automatiser les déploiements jusqu'au libre-service par n'importe quel développeur
Mise en place et exécution des testsDeux semaines pour préparer les environnements et données de test, quatre de plus pour exécuter les tests de régression à la mainAutomatiser et paralléliser les tests pour suivre le rythme du développement
Architecture trop coupléeTout changement impose de passer devant des dizaines de comités pour obtenir l'autorisationArchitecture faiblement couplée : changements sûrs et autonomes, productivité accrue

Une fois toutes ces contraintes brisées, la contrainte se déplacera vraisemblablement vers le développement ou les product owners — et c'est précisément qu'on veut qu'elle soit. Notre but étant que de petites équipes développent, testent et déploient de la valeur de façon autonome, vite et fiablement, les meilleurs profils — qu'ils soient en dev, QA, ops ou sécurité — affirment tous que leur objectif est de maximiser la productivité des développeurs. Quand la contrainte est là, on n'est plus limité que par le nombre de bonnes hypothèses métier formulées et par notre capacité à écrire le code pour les tester auprès de vrais clients.

Cette progression ne dispense pas d'identifier la contrainte réelle de chaque chaîne de valeur : les techniques pour y parvenir — notamment le value stream mapping et les mesures — sont abordées plus loin dans l'ouvrage.

Éliminer les peines et les gaspillages

Shigeo Shingo, l'un des pionniers du Système de production Toyota, tenait le gaspillage (waste) pour la plus grande menace à la viabilité d'une entreprise. La définition lean usuelle : « l'usage de toute matière ou ressource au-delà de ce que le client requiert et est prêt à payer ». Shingo identifia sept gaspillages manufacturiers : stocks, surproduction, traitements superflus, transport, attente, mouvement, défauts.

À retenir

Les interprétations modernes du lean notent que « éliminer le gaspillage » peut prendre un sens avilissant et déshumanisant. L'objectif est reformulé : réduire la peine et la pénibilité dans le travail quotidien par l'apprentissage continu, au service des objectifs de l'organisation. Dans tout l'ouvrage, le mot gaspillage renvoie à cette acception, plus proche des idéaux DevOps.

Dans Implementing Lean Software Development, Mary et Tom Poppendieck définissent gaspillage et peine comme tout ce qui cause un délai pour le client — toute activité contournable sans affecter le résultat. Voici leurs catégories, adaptées au logiciel.

Type de gaspillageCe qu'il recouvre
Travail partiellement fait (partially done work)Tout travail inachevé ou en file (specs non revues, attente d'une revue QA ou d'un ticket d'admin) ; il se périme et perd sa valeur avec le temps
Processus superflus (extra processes)Travail qui n'ajoute pas de valeur pour le client : documentation inutilisée en aval, revues ou approbations sans valeur ajoutée — surcoût d'effort et de délai
Fonctionnalités superflues (extra features)Fonctions non requises par l'organisation ou le client (le gold plating) ; elles alourdissent la complexité, les tests et la gestion
Changement de tâche (task switching)Gens affectés à plusieurs projets, contraints au changement de contexte et à la gestion des dépendances — effort et temps ajoutés
Attente (waiting)Tout délai contraignant des ressources à patienter ; allonge le temps de cycle et prive le client de valeur
Mouvement (motion)Effort pour déplacer information ou matière d'un poste à l'autre ; aggravé par la non-colocalisation et par les transferts ambigus
Défauts (defects)Information ou produit incorrect, manquant ou flou ; plus le délai entre création et détection est long, plus c'est dur à résoudre
Travail non standard ou manuel (nonstandard/manual work)Dépendance à des serveurs non reconstructibles, environnements ou configurations à la main ; idéalement automatisé, en libre-service, à la demande
Héroïsmes (heroics)Actes déraisonnables devenus quotidiens : interventions en prod à 2 h du matin, des centaines de tickets à chaque livraison

Piège courant

Les héroïsmes ne figurent pas dans les catégories de Poppendieck, mais le livre les ajoute tant ils sont fréquents — surtout dans les services partagés d'exploitation. Loin d'être une vertu, l'héroïsme chronique est le symptôme d'un système défaillant. Notre but est de rendre ces gaspillages et ces peines visibles — partout où l'héroïsme devient nécessaire — puis de systématiquement faire ce qu'il faut pour les soulager ou les supprimer, au service du flux rapide.

À retenir

  • La Première Voie optimise le flux global du développement vers l'exploitation et le client ; on l'accélère en rendant le travail visible, en limitant l'en-cours, en réduisant lots et transferts, et en élevant la contrainte.
  • Le travail logiciel étant invisible, on le matérialise sur des tableaux kanban couvrant toute la chaîne de valeur — une carte n'est « terminée » qu'en production, et le délai de livraison se mesure de bout en bout.
  • Limiter l'en-cours (WIP) combat le multitâche, qui dégrade gravement le temps de cycle ; comme le dit DeGrandis, la taille de file est l'un des rares indicateurs avancés du délai — d'où le mot d'ordre « stop starting, start finishing ».
  • Réduire la taille des lots transforme le flux : la simulation des newsletters montre la première enveloppe sortie huit fois plus vite en flux unitaire, avec moins d'en-cours, des erreurs détectées plus tôt et moins de retouches — l'équivalent logiciel étant le déploiement continu.
  • Chaque transfert (handoff) perd du savoir et allonge les délais ; on les réduit en automatisant et en réorganisant les équipes pour qu'elles livrent la valeur elles-mêmes.
  • La Théorie des Contraintes de Goldratt impose de n'améliorer que la contrainte : dans le flux IT, elle progresse de la création d'environnements au déploiement, aux tests, puis à l'architecture trop couplée — l'objectif étant qu'elle finisse côté développement, où l'on maximise la productivité des développeurs.
  • Les catégories de gaspillage de Poppendieck (travail partiellement fait, processus et fonctionnalités superflus, changement de tâche, attente, mouvement, défauts, travail manuel, héroïsmes) doivent être rendues visibles puis éliminées — l'héroïsme chronique étant le symptôme d'un système à réparer.