L'isolation des AZ a tenu. Votre architecture, non.
Une panne de refroidissement a tué des racks d'une zone us-east-1 et un quorum est mort avec eux. Ce que couvre le blast radius, plus un détecteur read-only.

Le soir du 7 mai, le refroidissement est tombé en panne dans une salle de données d'une zone de disponibilité d'us-east-1, des racks ont perdu leur alimentation, et le blast radius d'AWS a fait ce que la documentation promet : les dégâts sont restés à l'intérieur de use1-az4. Toutes les autres zones ont continué à servir. Les entreprises tombées cette nuit-là sont tombées à l'intérieur de leur propre architecture, et nous le savons avec une précision inhabituelle parce que Coinbase a publié un postmortem lundi qui le dit avec ses propres mots. Le trading a été, selon leur formule, "unavailable or degraded for roughly eight hours, with full recovery of all systems taking another twelve", pendant un événement où la frontière de zone de la plateforme a fonctionné.
Ceci est la Partie 1 de Nothing Fails Alone, une série sur l'écart entre la disponibilité que vous achetez à un fournisseur cloud et la disponibilité que vous construisez réellement par-dessus. Chaque partie prend un incident réel, en extrait la revendication architecturale qu'il met à l'épreuve, et livre un petit lab que vous pouvez exécuter contre votre propre compte. Les labs vivent dans un dépôt compagnon, nothing-fails-alone sur GitHub, et chacun d'eux est read-only.
Ce qui s'est réellement passé dans use1-az4
Le premier rapport d'incident sur l'AWS Health Dashboard était horodaté à 17:25 PDT le 7 mai, et comme l'événement résolu a depuis disparu du dashboard, la formulation ci-dessous est telle que citée par The Register à l'époque : des problèmes dans la zone de disponibilité use1-az4 d'us-east-1. Une mise à jour ultérieure a énoncé le mécanisme sans détour : "EC2 instances and EBS volumes hosted on impacted hardware are affected by the loss of power during the thermal event." À 18:47 PDT, AWS a déclaré travailler à ramener les températures à des niveaux normaux et a averti que d'autres services dépendant des EC2 instances et EBS volumes affectés dans cette zone pouvaient eux aussi être dégradés.
Le postmortem de Coinbase complète la cause physique : plusieurs unités de refroidissement (chillers) ont lâché en même temps dans une seule salle de données, et la perte de refroidissement a déclenché un arrêt de sécurité thermique des racks affectés. Voilà ce que "loss of power during the thermal event" signifie en pratique. Les racks n'ont pas été détruits ; ils ont été délibérément mis hors tension, parce que faire tourner du compute sans refroidissement le détruit. Les EC2 instances et EBS volumes de ces racks sont tombés ensemble, dans un seul bâtiment, dans une seule zone.
La récupération a été progressive, et honnête sur le fait de l'être. À 22:11 PDT cette nuit-là, AWS a signalé une capacité de refroidissement supplémentaire en ligne et quelques racks rétablis, avec d'autres à rétablir "in a controlled and safe manner". La capacité de refroidissement était revenue aux niveaux d'avant l'incident à 13:50 PDT le 8 mai, soit environ vingt heures après le premier rapport, la récupération des instances suivant avec retard le rétablissement du refroidissement. Si votre modèle mental d'un événement AZ est une coupure de quinze minutes, recalibrez : un événement thermique se mesure en heures parce que la physique se mesure en heures, et les racks reviennent rack par rack, pas tous d'un coup.
Ce qui n'est pas arrivé
Les autres zones de disponibilité d'us-east-1 sont restées saines. C'est la partie de cet incident qui devrait retenir plus d'attention qu'elle n'en reçoit, parce que c'est la partie qu'AWS a réellement promise. Les zones de disponibilité sont des installations physiquement séparées, avec alimentation et refroidissement indépendants, et le 7 mai cette indépendance a été mise à l'épreuve par une vraie défaillance d'installation et a tenu. Le domaine de défaillance était une salle de données ; le blast radius est resté à l'intérieur d'une seule zone.
Il y avait exactement une réserve honnête, et elle vaut d'être citée parce qu'elle compte plus loin dans cette série. AWS a détourné le trafic de la zone sinistrée, a conseillé aux clients de déplacer leurs charges vers les autres zones d'us-east-1, puis a admis : "Customers may experience longer than usual provisioning times." Bien sûr. Quand une zone meurt, chaque architecture multi-AZ correctement construite dans cette région se met à remplacer de la capacité dans les zones survivantes en même temps. La frontière de zone a tenu, mais les zones survivantes sont un pool partagé, et un basculement de masse est une ruée (thundering herd) contre ce pool. Gardez cette réserve en tête ; la Partie 3 de cette série porte sur ce que votre plan de reprise partage avec celui de tout le monde.
Les propres mots de Coinbase
Les postmortems des sociétés cotées sont d'habitude poncés jusqu'à ne plus rien dire. Celui-ci ne l'est pas, et c'est pourquoi il vaut d'être lu en entier. Deux phrases portent toute l'histoire architecturale. D'abord : "Our matching engine was pinned to a single building." Ensuite, l'explication du comment : le matching engine de Coinbase Exchange "runs as a Raft-based replicated cluster inside an AWS Cluster Placement Group". Et puis la phrase qui transforme un événement de zone en une panne de huit heures : "There was no automated cross-zone failover."
Un cluster placement group est single-AZ par construction. Ce n'est pas une limitation qu'AWS cache ; c'est le produit. L'intérêt de la stratégie cluster est d'entasser les instances sur du matériel physiquement proche, sur le même segment réseau à haut débit, pour que la latence de nœud à nœud soit aussi basse que possible pour EC2. Vous ne pouvez pas avoir cela et la séparation de zones en même temps, parce que la séparation de zones, c'est de la distance, et la distance, c'est de la latence. Pour un matching engine, où les microsecondes de latence de nœud à nœud sont le produit, un cluster placement group est le bon choix, et Coinbase le dit : "We make this choice deliberately."
Le problème, c'est ce qui vivait à l'intérieur. Raft existe pour survivre à la perte d'une minorité de nœuds. Mettez cinq nœuds Raft dans un cluster placement group et vous avez construit un protocole de consensus dont les membres partagent un bâtiment, donc partagent un domaine de défaillance, donc le protocole ne peut plus faire la seule chose pour laquelle il existe. Quand AWS a terminé des EC2 instances à l'intérieur du placement group de Coinbase à 21:29 ET, trois des cinq nœuds du matching engine sont tombés ensemble et le quorum a disparu. Un quorum qui partage une salle de données n'est pas un quorum ; c'est une seule défaillance avec cinq noms.
Sans basculement inter-zones automatisé derrière lui, la récupération est devenue un processus humain. Elle a exigé un changement de code en urgence, livré pendant l'incident, pour retirer une hypothèse de démarrage selon laquelle les cinq nœuds du cluster étaient résolvables. Le matching engine est revenu en mode cancel-only à 02:25 ET le 8 mai, le trading complet a repris à 03:49 ET, le site retail et l'application mobile étaient entièrement rétablis à 09:53 ET, et l'arriéré des topics d'event-streaming s'est résorbé à 14:00 ET. Environ huit heures d'indisponibilité, douze de plus jusqu'à la récupération complète, pendant un événement qu'AWS a contenu dans une seule zone.
Le multi-AZ, c'est quelque chose qu'on achète et quelque chose qu'on construit
La forme générale de cet incident n'est pas une histoire propre à Coinbase. C'est l'écart entre acheter une infrastructure multi-AZ et construire un système multi-AZ, et cet écart a un petit nombre de formes récurrentes. Chacune est une configuration qui paraît redondante sur le schéma d'architecture et ne l'est pas :
- Le groupe Auto Scaling à sous-réseau unique. L'ASG remplacera volontiers les instances défaillantes à l'infini, dans la même zone, parce que la liste de sous-réseaux que vous lui avez donnée se résout en une seule AZ. Quand cette zone se dégrade, la capacité désirée ne peut pas être atteinte tant qu'un humain n'édite pas le groupe. Une auto-réparation qui répare vers la défaillance n'est pas de l'auto-réparation.
- RDS sans Multi-AZ. Pas de standby synchrone signifie que la perte de zone n'est pas un basculement, c'est une restauration : depuis un snapshot, mesurée en heures, avec une perte de données jusqu'au dernier point de sauvegarde. Le plan de DR juste à côté suppose en général un basculement en moins d'une minute, parce que quelqu'un a lu la documentation Multi-AZ et que personne n'a vérifié la case dans la console.
- Le quorum dans un cluster placement group. Le motif Coinbase : trois, cinq ou sept nœuds de Raft, etcd ou ZooKeeper entassés dans un groupe qui est single-AZ par définition. La couche de consensus se déclare saine et tolérante aux pannes jusqu'à ce que le bâtiment ne soit plus d'accord.
- La dépendance NAT inter-AZ. Un sous-réseau privé dans la zone B dont la route par défaut pointe vers une NAT gateway dans la zone A. La défaillance de la zone A supprime le trafic sortant d'instances dont la propre zone est parfaitement saine. Celle-ci est invisible sur tous les schémas parce que la flèche pointe vers « NAT », pas vers une zone.
Aucune de ces configurations n'est exotique. Toutes passent un test de charge, un game day qui ne tue que des instances, et la plupart des revues d'architecture, parce que chacune n'échoue que quand une zone entière tombe, et les zones entières tombent assez rarement pour que l'hypothèse reste non testée pendant des années.
Le lab : un détecteur de concentration single-AZ
Les revendications doivent être testables, alors cette partie est livrée avec un lab : 01-single-az-detector, un unique fichier Python qui scanne le compte et la région courants à la recherche des motifs ci-dessus et de trois autres. Il est read-only au sens strict : chaque appel d'API qu'il fait est un Describe*. Il exécute sept contrôles : groupes Auto Scaling single-AZ, cluster placement groups, clusters de taille quorum à l'intérieur de placement groups, instances RDS single-AZ, clusters RDS dont tous les membres sont dans une seule zone, groupes de réplication ElastiCache sans Multi-AZ, et sous-réseaux privés dont la route par défaut traverse les zones pour atteindre une NAT gateway.
$ python3 detect.py
SEVERITY | RESOURCE | AZ | WHY
--------------------------------------------------------------------------...
CRITICAL | placement-group/matching-prod | us-east-1a (use1-az4) | 3 instances in cluster placement group 'matching-prod': a quorum-sized cluster in a group that is single-AZ by construction. ...
HIGH | asg/api-workers | us-east-1c (use1-az2) | Auto Scaling group spans exactly one AZ. Every replacement instance lands in the same zone ...
HIGH | rds-cluster/orders | us-east-1a (use1-az4) | All members of DB cluster 'orders' sit in one AZ. Aurora failover needs a reader in a different zone ...
MEDIUM | subnet-0a1b2c3d -> nat-0e4f5a6b | us-east-1b (use1-az6) -> us-east-1a (use1-az4) | Private subnet in us-east-1b (use1-az6) routes 0.0.0.0/0 through a NAT gateway in us-east-1a (use1-az4) ...
4 finding(s).Le contrôle qui mérite la sévérité CRITICAL est QUORUM_IN_ONE_AZ : un cluster placement group contenant exactement 3, 5 ou 7 instances en cours d'exécution. Ces nombres ne sont pas arbitraires ; ils sont la forme d'un quorum Raft, etcd ou ZooKeeper, et une charge en forme de quorum concentrée dans une seule zone est exactement la configuration qui a fait tomber Coinbase. Un placement group avec un autre nombre d'instances est quand même signalé, mais en HIGH : c'est une optimisation de latence dont quelqu'un devrait confirmer qu'elle a été choisie délibérément.
Deux comportements sont délibérés. D'abord, le code de sortie : le scan sort avec 0 chaque fois qu'il se termine, qu'il y ait des constats ou non, parce que c'est un rapport, pas une barrière. Si IAM refuse l'une des API, ce contrôle est ignoré avec un avertissement d'une ligne sur stderr, les contrôles restants s'exécutent quand même, et le code de sortie reste 0 ; vous n'obtenez le code de sortie 2 que quand le scan ne peut pas s'exécuter du tout : pas d'identifiants, pas de région, pas de boto3. Vérifiez stderr avant de faire confiance à un tableau propre. Ensuite, chaque constat rapporte la zone à la fois par son nom et par son ID, par exemple us-east-1a (use1-az4). Le nom est un alias qu'AWS randomise par compte ; l'ID est la zone physique. Le Health Dashboard disait use1-az4, et sans l'ID vous ne pouvez pas dire si c'était votre us-east-1a. Cette distinction ressemble à un détail aujourd'hui. La Partie 2 porte sur l'incident où elle cesse d'être un détail.
Modes de défaillance et ce qu'il faut surveiller
Le compromis sous tout cela est légitime, alors nommez-le au lieu de faire comme s'il n'existait pas. Le placement single-AZ achète de la latence, le transfert de données inter-AZ coûte de l'argent, et la réplication synchrone entre zones coûte de la latence en écriture. Coinbase n'est pas tombé par hasard dans un placement group ; ils l'ont conçu et ont accepté un risque. La défaillance n'était pas le choix, c'était que la conséquence du choix, l'absence de chemin automatisé hors de la zone, a été découverte à 21:29 pendant l'incident plutôt que décidée dans une revue de conception avant lui.
Ce qu'il faut surveiller dans votre propre compte, au-delà de l'exécution du détecteur : l'arithmétique du quorum, pas seulement son emplacement, parce que deux nœuds etcd sur trois dans une seule zone, c'est le même défaut avec une ligne de tableau plus avenante. Les ASG qui listent plusieurs sous-réseaux se résolvant tous vers la même zone, ce qui est la raison pour laquelle le détecteur résout les sous-réseaux VPCZoneIdentifier au lieu de faire confiance à la liste d'AZ. Les caches sans réplicas : une perte de zone refroidit ElastiCache, et la tempête de cache-miss qui en résulte atterrit sur votre base de données au pire moment possible. Et le provisionnement de capacité pendant un vrai événement de zone, la seule chose que le détecteur ne peut pas voir, parce que c'est une propriété de l'architecture de tous les autres, pas de la vôtre. AWS vous l'a dit lui-même, en plein incident : longer than usual provisioning times. La frontière de zone est réelle, et elle a tenu. Ce que vous construisez par-dessus est à vous.
À lire ensuite
- Partie 2 de cette série : Two Zones, Eighteen Hours, One Cause, où la distinction entre nom d'AZ et ID d'AZ cesse d'être un détail.
- Multi-Tenant LLM Apps: Isolating Customers on a Shared Model sur ercan.ai, la même leçon un cran plus haut : la plateforme vous donne une frontière, et l'isolation reste votre travail.
- Le dépôt compagnon : nothing-fails-alone, tous les labs de cette série, read-only par conception.
Pour du conseil en AWS, architecture cloud, revues de résilience et travail de plateforme, commencez par ercanermis.com.
Références
Plus d'Ercan
Deux autres sites, même auteur, terrain différent.
IA, LLMs, agents, ML appliquée.
Notes de terrain sur les charges IA. Analyse des coûts Bedrock, patterns d'agents, compromis de stockage vectoriel, modes de défaillance en production.
Visiter ercan.ai →Le hub. À propos, conseil, contact.
Hub personnel pour les deux pistes d'écriture. Qui je suis, comment fonctionne le conseil, comment me joindre.
Visiter ercanermis.com →