La migration qui a redéfini l'ennui
Un samedi matin, à 8 h, un système de dix ans a quitté sa vieille instance EC2 Linux, qui hébergeait absolument tous les composants, pour une pile en conteneurs et une base de données gérée. Le PDG ne s'est même pas rendu compte que la migration avait eu lieu, jusqu'à ce qu'on l'en avise le lundi matin. La migration a causé un grand total d'environ 60 minutes de performance dégradée et aucune plainte d'utilisateur.
C'est normalement un trimestre de travail à cinq personnes. Ç'a été un seul contractuel externe, à temps partiel, sur huit semaines, dont la majeure partie passée à attendre et à faire de l'assurance qualité. Voici comment, et pourquoi vous devriez envisager la même approche.
Ce qu'il y avait sur le serveur
Commençons par ce qu'il y avait sur cette machine. L'application, la base de données, tous les fichiers téléversés et les sauvegardes automatisées, sur le même disque. Des dizaines de gigaoctets de sauvegardes reposaient sur le même volume que la base de données qu'elles sauvegardaient, donc perdre ce disque, c'était perdre les données et leurs copies locales d'un seul coup.
Le script de sauvegarde nocturne était tronqué au milieu d'une condition if. Il mourait à chaque exécution sur une erreur de syntaxe et n'avait pas produit un seul fichier depuis des années. Un deuxième script, complet celui-là, tournait le matin, alors le dossier de sauvegardes avait toujours l'air frais. C'est précisément ce qui l'a caché. La capacité de restauration que l'entreprise avait réellement ne venait pas de cet horaire-là.
La machine avait une alarme. Une seule. Elle vérifiait le remplissage du disque en filtrant la sortie de df sur un nom de périphérique que cette instance n'avait pas. Le filtre ne retournait rien, le script plantait avant même d'évaluer le seuil, et le disque est resté à 68 % pendant qu'une alerte réglée à 80 % était structurellement incapable de se déclencher.
La file d'attente lisait une variable d'environnement que plus rien ne définissait. Résultat : les courriels d'inscription et de réinitialisation de mot de passe partaient en ligne directe, à l'intérieur de la requête HTTP de l'utilisateur, pendant qu'un processus de file d'attente, juste à côté, ne traitait rien du tout. Une seule requête sur le plan du site tirait dix-sept mégaoctets de la base pour retourner une page de moins d'un mégaoctet, en 848 requêtes SQL.
Le déploiement, c'était : se connecter à la machine, tirer la branche, redémarrer le service. Aucune intégration continue, aucune infrastructure décrite nulle part, aucun chemin de retour.
Ce qui était lisible depuis l'internet public
Rien de tout ça n'était caché. N'importe qui ayant les accès aurait pu écrire cette liste en un après-midi, et une bonne partie était lisible depuis l'internet public avec un simple navigateur. Un vidage complet de la configuration du serveur, servi publiquement, qui affichait la version du moteur d'exécution, l'adresse interne et le chemin d'installation. Une adresse qui retournait des chiffres d'affaires en clair, sans authentification, explicitement bloquée dans le robots.txt, donc la sensibilité était connue et l'adresse était ouverte quand même. Des statistiques mesurées par un outil éteint trois ans plus tôt, donc trois ans à ignorer d'où venaient les visiteurs.
Ce que cette configuration coûtait à l'entreprise
Le coût d'affaires de tout ça n'est pas celui qu'on imagine. L'équipe livrait encore. Les fonctionnalités sortaient au rythme qu'on pouvait attendre. Ce que cette configuration coûtait, c'était la prévisibilité. Personne ne pouvait dire d'avance quel changement était sûr, parce qu'il n'y avait aucun moyen de vérifier avant que ce soit en ligne, ni aucun moyen de revenir en arrière si ça ne l'était pas. Le plus gros coût de travailler comme ça, c'est le risque, porté en permanence, à chaque livraison. Un risque de cette taille décide de ce que les gens osent tenter. Le plus petit changement est toujours le plus sûr, alors il gagne à chaque fois, et après dix ans, la base de code est faite de dix ans de plus petite option possible.
Construire le remplacement à côté de la production
Alors on ne l'a pas migré. On a construit le remplacement à côté, en laissant la vieille machine être la vraie production du premier au dernier jour. C'est cette décision-là qui garde le risque bas et qui permet à une seule personne à temps partiel de porter le projet. Rien de ce qu'on construisait ne pouvait casser l'entreprise avant la minute où on a choisi de basculer.
La nouvelle plateforme roule dans des conteneurs, sur une base de données gérée avec des sauvegardes automatiques qui s'exécutent vraiment et une protection contre la suppression. Les fichiers sont passés dans un stockage objet derrière un CDN. Les secrets sont sortis du dépôt. Le déploiement et le retour arrière sont devenus un bouton. L'infrastructure est entièrement en code, et elle roulait localement avant qu'un seul dollar d'hébergement soit dépensé.
Le gros des huit semaines est parti dans une réplique complète de la production, tenue à jour par une synchronisation de données à sens unique, jouée et rejouée pendant des semaines. On a cassé ce script de synchronisation exprès, de toutes les façons auxquelles on a pensé, et c'est comme ça qu'on a découvert qu'un vidage de base qui meurt à gauche d'un tube retourne le code de sortie de ce qui se trouve à droite. La version évidente de ce script aurait effacé la cible en annonçant un succès. C'est la partie qui ressemble à du temps mort sur une facture, et c'est la raison pour laquelle le basculement s'est résumé à quatre points de liste plutôt qu'à une fin de semaine.
La supervision a été refaite autour de la leçon de la vieille machine. Une vérification horaire qui s'assure que les choses tournent réellement, doublée d'un signal de vie externe qui se déclenche si le vérificateur lui-même se tait. Une alarme qui ne se déclenche qu'au franchissement d'un seuil ne peut pas vous dire qu'elle a cessé de fonctionner.
Le basculement
Ce qui nous ramène à la date du basculement, un samedi matin à 8 h. Avec un système répliqué pleinement fonctionnel, on avait devant nous une longue liste de vérifications pour le basculement. On a :
- Provisionné les nouveaux certificats TLS pour les nouveaux serveurs avant le basculement DNS
- Fait rouler le script de synchronisation une dernière fois, en parallèle, pour ingérer les données et le contenu ajoutés depuis la dernière passe
- Refait un test de fumée sur la nouvelle instance
- Pointé le DNS vers la nouvelle instance
Et c'est tout. Une seule main suffit pour compter les étapes.
Ce n'est aucune de ces quatre étapes qui a coûté les 60 minutes. Le site n'est jamais tombé. Il est devenu lent, pendant environ une heure, à cause de deux problèmes qui n'existent que sous le trafic réel et qu'aucune réplique ne peut vous montrer. La nouvelle base de données avait été provisionnée trop petite, et un service interne s'est dégradé une fois qu'il portait toute la charge. Un des deux a été réglé plus tard le jour même. L'autre le lundi, quand la charge de semaine est arrivée et l'a rendu évident. Les migrations sans incident imprévu, ça n'existe tout simplement pas. Le travail, c'est de garder ces incidents assez petits pour que personne n'ouvre un billet.
Ce qu'une migration de système hérité achète, et ce qu'elle n'achète pas
Huit semaines entre le premier audit et le basculement, dont environ un mois passé à réellement construire. Ça a coûté moins qu'un mois de consultant en cravate. Le trimestre à cinq personnes à temps plein n'aurait pas acheté un meilleur résultat, parce que ce qui rend l'opération sûre, c'est l'ordre des étapes, pas le nombre de gens. On ne fait pas cuire une dinde cinq fois plus vite en utilisant cinq fours.
Voici ce que ça achète, et ce que ça n'achète pas. Un changement peut maintenant être fait, annulé et observé. Les sauvegardes roulent sans que personne les surveille. Un déploiement, c'est un bouton, et l'équipe sait exactement ce qui est sorti, quand, et qui l'a envoyé, ce que personne ne pouvait savoir du temps où tout le monde partageait les mêmes accès SSH. Plus rien ne se modifie directement sur un serveur en ligne pour être poussé sur la branche principale après coup. C'est le plancher. Ça ne rend pas le produit meilleur en soi, ça rend le prochain tour de travail sûr à faire, et ce travail-là est distinct.
Si vous détenez un morceau d'une entreprise qui roule sur quelque chose du genre, la raison d'envisager la même approche, ce n'est pas les huit semaines. On ne peut pas vous donner votre chiffre sans avoir vu votre système, et quiconque vous en donne un avant de regarder invente. La raison, c'est que construire à côté échoue proprement. Si le remplacement est mauvais, vous l'apprenez un samedi matin avec la vieille machine encore debout à côté, pas à mi-chemin d'un basculement que vous ne pouvez pas inverser.
La question la moins chère vient en premier : est-ce que quelqu'un dans cette équipe peut faire un changement, l'annuler, et voir ce qui s'est passé ? Si la réponse est non, rien d'autre sur la feuille de route n'est réel. Le savoir, c'est un audit de code. Agir dessus, c'est un sauvetage de système hérité. Pour la version technique de notre façon de travailler dans ce genre de système, on a écrit sur la programmation agentique appliquée au code ancien.