Chaque plan de reprise porte une seconde hypothèse, plus discrète que la première. La première est qu'une partie de l'infrastructure survit à l'événement ; les Parties 1 et 2 de cette série ont testé celle-là. La seconde est que, quand l'événement arrive, vous pouvez encore déployer le correctif : l'API répond, la console se charge, votre pipeline peut assumer un rôle, le groupe Auto Scaling peut lancer un remplacement. Le 13 juin 2023, un défaut latent dans le sous-système qui gère la capacité de compute de Lambda a dégradé les invocations de fonctions dans us-east-1, et pendant une partie des quatre heures suivantes l'AWS Management Console de cette région servait des pages d'erreur tandis que STS renvoyait des taux d'erreur élevés. Rien dans l'infrastructure de la plupart des clients n'a cassé ce jour-là. Ce qui a cassé, c'est la couche qu'ils auraient utilisée pour réparer. Quand le plan de contrôle est à l'intérieur du blast radius, le chemin de remédiation est à l'intérieur du domaine de défaillance.

Ceci est la Partie 3 de Nothing Fails Alone. La Partie 1 a pris l'incident us-east-1 de mai et montré la frontière de zone en train de tenir tandis qu'une architecture client échouait à l'intérieur. La Partie 2 a pris l'événement me-central-1 de mars et montré contre quoi la frontière est conçue, les défaillances d'installation, et contre quoi elle ne l'est pas, une seule cause atteignant deux zones. Les deux parties finissaient près de la même réserve, publiée par AWS au milieu des deux incidents : "longer than usual provisioning times". La Partie 1 promettait que cette partie porterait sur ce que votre plan de reprise partage avec le plan de reprise de tout le monde. Voici la réponse : il partage le plan de contrôle. Votre basculement appelle les mêmes API régionales que tous les autres basculements de la région, opérées par le fournisseur, dégradées par les mêmes événements qui vous les rendent nécessaires, et cette dépendance mérite le même examen que celui que vous accordez à vos réplicas.

Juin 2023 : le correctif avait besoin de la chose qui a échoué

Le mécanisme est au registre public depuis qu'AWS a publié son post-event summary du 13 juin 2023. Il vaut d'être lu avec précision, parce que c'est le cas documenté le plus net d'un plan de contrôle qui échoue tandis que l'infrastructure en dessous continue de tourner. À 10:01 PDT, la flotte Lambda Frontend d'us-east-1 a commencé à monter en charge pour un trafic quotidien ordinaire. À 11:49, elle a franchi, selon les mots d'AWS, "a capacity threshold that had previously never been reached within a single cell", ce qui "triggered a latent software defect". Des environnements d'exécution étaient alloués mais jamais utilisés, le sous-système "responsible for managing the underlying compute capacity" ne pouvait pas provisionner de remplacements fonctionnels, et les invocations Lambda dans la région ont commencé à échouer.

Puis le graphe de dépendances a fait son œuvre. Le résumé liste Amazon STS, l'AWS Management Console, Amazon EKS, Amazon Connect et Amazon EventBridge comme dégradés "as a result of the degraded Lambda function invocations". STS a renvoyé des taux d'erreur élevés de 11:49 à 14:10 PDT "with three distinct periods of impact". La console d'us-east-1 servait, de 11:48 à 14:02, soit une page "AWS Management Console is currently unavailable", soit un "504 Time-out". La connexion fédérée s'est dégradée elle aussi : "Existing IAM sessions were not impacted, but new sign-in federation via SAML was degraded." La récupération complète est arrivée à 15:37 PDT, trois heures et quarante-huit minutes après le début de l'impact.

Reportez cela sur un runbook ordinaire. Étape un, se connecter à la console : dégradée. Étape deux, laisser le pipeline assumer un rôle pour des identifiants frais : STS, dégradé, à trois reprises distinctes. Étape trois, invoquer la Lambda de remédiation : c'est la panne. Aucune de vos instances n'a échoué. Votre base de données n'a pas basculé. L'événement n'a jamais touché votre infrastructure du tout, et il a quand même emporté les outils que votre plan supposait. La leçon est structurelle, pas historique : la couche d'opération et la couche défaillante étaient la même couche, et elles le seront de nouveau.

Octobre 2025 : l'effondrement, revu depuis le plan de contrôle

Quand us-east-1 est tombée en octobre 2025, ce site l'a couvert le jour même dans When the Cloud Sneezes, the World Catches a Cold. Ce billet portait sur la largeur du blast radius, l'absurdité de voir la moitié d'internet dépendre d'une seule région, et il se terminait sur ce qu'il fallait changer. Cette partie est la suite qu'il promettait, écrite avec le bénéfice du post-event summary officiel d'AWS, et le résumé récompense une lecture plus froide que celle que le jour permettait : regardez ce qui est arrivé aux outils, pas aux applications.

Le déclencheur était le DNS : "a latent race condition in the DynamoDB DNS management system that resulted in an incorrect empty DNS record" pour dynamodb.us-east-1.amazonaws.com, un enregistrement que l'automatisation "failed to repair". L'endpoint de DynamoDB a été rétabli en quelques heures. Les dégâts sur le plan de contrôle ont duré bien plus longtemps. EC2, selon le résumé : "Between 11:48 PM PDT on October 19 and 1:50 PM PDT on October 20, customers experienced increased EC2 API error rates, latencies, and instance launch failures", quatorze heures durant lesquelles le geste de reprise standard de chaque architecture multi-AZ de la région, lancer de la capacité de remplacement, était lui-même dégradé. STS a renvoyé des "API errors and latency" de 23:51 à 09:59. La connexion à la console avec un utilisateur IAM échouait avec des "increased authentication failures" jusqu'à 01:25, les utilisateurs d'Identity Center dans la région ne pouvaient pas se connecter du tout, et la connexion par identifiants root et la connexion fédérée renvoyaient des erreurs même dans d'autres régions, parce que le chemin de connexion lui-même vivait dans us-east-1.

Mettez les deux billets côte à côte et la division du travail est claire. Le billet d'octobre demandait ce que coûte le fait de dépendre d'une seule région. Celui-ci pose la question plus étroite et plus vicieuse à l'intérieur : quand la région a eu sa mauvaise journée, pourquoi des architectures multi-AZ bien construites sont-elles restées à terre pendant des heures ? Parce que leur reprise était une opération de plan de contrôle. Le passage à l'échelle était le correctif, et le passage à l'échelle est ce que quatorze heures de lancements d'instances dégradés ont emporté. Le plan de chacun convergeait sur la même API dégradée au même moment, ce qui est exactement ce que signifie en pratique « votre plan partage le plan de contrôle avec celui de tout le monde ».

Février 2026 : Azure, même forme, autre logo

Si c'était une bizarrerie d'AWS, ce serait un problème d'AWS. Ce n'en est pas un. Le 2 février 2026, Microsoft a enregistré l'incident FNJ8-VQZ, et son post-incident review s'ouvre ainsi : "Between 18:03 UTC on 02 February 2026 and approximately 00:30 UTC on 03 February 2026, a platform issue caused some customers to experience degraded performance and control plane failures, for multiple Azure services across multiple regions." Une politique de remédiation de sécurité censée désactiver l'accès anonyme sur des comptes de stockage gérés par Microsoft a été, à cause d'"a data synchronization problem in the targeting logic", appliquée à des comptes "intentionally configured to allow anonymous read access for platform functionality" : les comptes qui servent les paquets d'extension de VM. Les machines virtuelles ont subi des "failures when deploying or scaling", AKS a subi des "failures in node provisioning", et les jobs GitHub Actions "queued and timed out while waiting to acquire a hosted runner".

Remarquez ce qui n'est pas arrivé : les VM en cours d'exécution ont continué de tourner. Le plan de données allait bien. Ce qui est mort, c'est la capacité de créer, de mettre à l'échelle ou de changer, sur plusieurs régions à la fois, parce que le plan de contrôle est partagé d'une manière dont le plan de données ne l'est pas. Voilà la propriété qui mérite d'être généralisée. Un plan de contrôle est un seul système logique qui couvre les zones, parfois les régions, que son plan de données garde soigneusement séparées ; c'est la pièce sous charge maximale précisément quand tout le monde est en train de se rétablir ; et il échoue de manières que les schémas multi-région ne montrent pas, parce que le schéma dessine vos ressources, pas la machinerie qui les mute. Deux fournisseurs, à quatre mois d'écart, même forme.

La stabilité statique, définie correctement

La défense a un nom : la stabilité statique. Un système statiquement stable continue de satisfaire ses exigences quand une dépendance échoue, sans avoir à rien changer, parce que tout ce qu'il aurait demandé à la dépendance est déjà en place. La définition mérite le mot "statique" : une reprise qui ne demande aucune mutation ne peut pas être bloquée par la couche qui effectue les mutations. Concrètement, cela signifie une petite famille de décisions précalculées :

  • Marge de capacité pré-provisionnée. Chaque zone fait tourner assez de capacité pour que les zones survivantes portent la pleine charge sans aucun lancement. La perte de zone devient une décision de load balancer, une opération de plan de données, au lieu d'un événement Auto Scaling, une opération de plan de contrôle.
  • Pré-créé, pas créé-au-basculement. Les enregistrements DNS du standby, les rattachements de target group et les instances de secours existent avant l'incident. Le basculement bascule des health checks et des poids ; il ne lance pas Terraform.
  • Images pré-cuites. Une AMI qui démarre jusqu'à servir sans atteindre de miroirs de paquets, de services de configuration ou d'endpoints de secrets garde un lancement utile même quand tout ce qui entoure le lancement est dégradé.
  • Des chemins break-glass qui évitent la couche défaillante. Le résumé d'octobre est sans détour sur la connexion : utilisateurs IAM, Identity Center et fédération se sont tous dégradés ensemble. Un chemin d'accès d'urgence n'est réel que s'il ne traverse pas la région et le plan d'identité que vous essayez de sauver, et n'est réel que s'il est exercé ; un identifiant break-glass non testé est un vœu.

Le fil commun est de déplacer le travail de pendant-l'incident vers avant-l'incident, du calendrier du plan de contrôle vers le vôtre. Vous ne pouvez pas rendre fiable le plan de contrôle du fournisseur. Vous pouvez vous arranger pour ne pas en avoir besoin pendant la première heure.

Le lab : mesurez la différence, ne l'affirmez pas

Le lab de cette partie, 03-static-stability, enfreint sciemment une règle de la série : il n'est pas read-only. Terraform construit un VPC, un ALB exposé sur internet et six instances t3.micro, et cela coûte de l'argent jusqu'à ce que vous le détruisiez, donc il a sa place dans un compte sandbox et à la poubelle le jour même. Ce que vous achetez pour ce prix, c'est une mesure de l'écart exact que ce billet décrit, sur votre compte, au lieu de mon affirmation à son sujet. La documentation de fault-injection d'AWS elle-même énonce la prémisse sans détour : pour le scénario d'interruption d'alimentation d'AZ, "EC2 API calls made by the Auto Scaling control plane to recover lost capacity in the AZ will fail". Le lab construit les deux réponses à cette phrase derrière un même load balancer. Le chemin A est la conception standard : un groupe Auto Scaling avec une instance par zone et une politique de scaling, donc perdre une zone signifie que l'ASG doit appeler ec2:RunInstances pour se rétablir. Le chemin B est la conception statiquement stable : la même charge pré-provisionnée au double de la capacité, deux instances par zone, donc chaque zone seule porte déjà la pleine charge.

Le script de mesure mérite une note, parce que son premier jet était faux d'une manière instructive. Retirer simplement le sous-réseau de la zone défaillante d'un ASG n'est pas une perte de zone : cela déclenche un rééquilibrage, et le rééquilibrage lance des remplacements avant de rien terminer, donc la capacité saine ne baisse jamais et il n'y a rien à mesurer. Une vraie perte de zone tue les instances. Donc measure.py retire le sous-réseau puis termine les instances en service de cette zone via TerminateInstanceInAutoScalingGroup avec ShouldDecrementDesiredCapacity=False, laissant chaque groupe en déficit de capacité réelle qu'il doit rétablir ailleurs. Pour le chemin A, il chronomètre ensuite l'intervalle entre la panne et le retour au compte complet d'instances saines au niveau du load balancer, un intervalle qui est du pur plan de contrôle : appel de lancement, boot, health checks. Pour le chemin B, il surveille le compte d'instances saines à travers une fenêtre de stabilisation et enregistre le minimum, qui tombe de quatre à deux ; deux est exactement l'exigence post-défaillance, donc la condition de réussite est testée contre une vraie baisse plutôt que satisfaite trivialement. Voici la forme du tableau que le script imprime, pas un résultat que j'ai obtenu ; je n'ai pas exécuté ceci contre un compte réel pour ce billet, et les nombres qu'un lecteur obtient sont les siens :

PATH                    | TIME TO RECOVER               | API CALLS REQUIRED                | SURVIVES CONTROL PLANE LOSS
path-a (control plane)  | measured on your run          | yes: ec2:RunInstances via the ASG | no
path-b (static)         | 0s, capacity already in place | none                              | yes

Quel que soit le nombre que le chemin A imprime pour vous, lisez-le comme un meilleur cas : il a été mesuré contre un plan de contrôle sain et coopératif un jour calme. Le plan de contrôle d'octobre n'était ni l'un ni l'autre. Le lab 04 existe pour combler cet écart, en injectant les erreurs de capacité insuffisante qui transforment le nombre du chemin A en ce qu'il aurait été cette nuit-là.

Le coût honnête, et là où cela cesse d'en valoir la peine

Le chemin B fait tourner le double de la capacité en régime permanent pour servir le même trafic. Ce n'est pas une note de bas de page, c'est le marché : la stabilité statique, c'est acheter une assurance avec du compute inactif, à chaque heure, contre un événement mesuré en heures par an. Avec deux zones, la prime est de 100 pour cent ; avec trois zones dimensionnées chacune pour absorber la perte d'une, elle tombe à 50 ; avec plus de zones ou un dimensionnement conscient du surprovisionnement, moins. Payez-la pour le chemin de service dont l'indisponibilité se mesure en revenus ou en sécurité, pour les petites flottes où doubler est bon marché en valeur absolue, et pour tout ce dont la reprise dépendrait sinon du bon fonctionnement du plan de contrôle en plein incident.

Arrêtez de la payer là où les maths cessent de fonctionner. Le travail par lots et asynchrone devrait patienter en file d'attente à travers une perte de zone, pas se pré-provisionner contre elle. Le dev et le staging n'en ont pas besoin. Les très grandes flottes paient de l'argent réel pour de la marge, et là le geste honnête est de scinder le palier : stabilité statique pour la tranche critique, reprise par plan de contrôle acceptée, en connaissance de cause, pour le reste. Et sachez ce que la technique ne couvre pas. Elle n'aurait pas sauvé Coinbase dans la Partie 1, parce que leur défaillance était dans leur propre plan de données, un quorum partageant un bâtiment. Elle ne répond pas à la perte de région de la Partie 2, puisque de la marge à l'intérieur d'une région condamnée est de la marge condamnée. Elle protège les premières heures, sur le pari que le plan de contrôle revient avant que votre capacité de réserve ne cesse de suffire. Ce pari a tenu en juin 2023 et en octobre 2025. Que votre version de ce pari tienne, c'est une chose que vous testez, et c'est là que cette série se poursuit.

À lire ensuite

Pour du conseil en AWS, architecture cloud, revues de résilience et travail de plateforme, commencez par ercanermis.com.

Références