あらゆる復旧計画は、1つ目より静かな2つ目の前提を抱えている。1つ目は、インフラの一部がイベントを生き延びるという前提だ。このシリーズの第1回と第2回はそれを試した。2つ目は、イベントが来たとき、まだ修正をデプロイできるという前提だ。APIが応答し、コンソールが読み込まれ、パイプラインがロールを引き受けられ、Auto Scalingグループが置き換えを起動できる、という前提だ。2023年6月13日、Lambdaのコンピュート容量を管理するサブシステムの潜在的な欠陥が、us-east-1で関数呼び出しを劣化させ、その後の4時間のうち一部の間、そのリージョンのAWS Management Consoleはエラーページを配信し、STSは上昇したエラー率を返した。その日、ほとんどの顧客のインフラは何も壊れなかった。壊れたのは、彼らがそれを直すために使ったであろう層だった。コントロールプレーンがブラストラジアスの内側にあるとき、修復の経路は障害ドメインの内側にある。

これは Nothing Fails Alone の第3回だ。第1回は5月のus-east-1インシデントを取り上げ、顧客のアーキテクチャがその内側で失敗する一方でゾーン境界が持ちこたえるのを示した。第2回は3月のme-central-1のイベントを取り上げ、境界が何に対して設計されているか、施設の障害、そして何に対してではないか、1つの原因が2つのゾーンに届くこと、を示した。両方の回は、AWSが両方のインシデントの最中に公開したほぼ同じ但し書きの近くで終わった。"longer than usual provisioning times"、だ。第1回は、この回があなたの復旧計画が他の全員の復旧計画と何を共有しているかについての話になると約束した。その答えがこれだ。共有しているのはコントロールプレーンだ。あなたのフェイルオーバーは、そのリージョンの他のあらゆるフェイルオーバーと同じリージョナルAPIを呼ぶ。提供者によって運用され、あなたがそれを必要とさせるのと同じイベントによって劣化する。その依存関係は、あなたがレプリカに向けるのと同じ精査に値する。

2023年6月: 修正は、失敗したまさにそのものを必要とした

そのメカニズムは、AWSが2023年6月13日についてポストイベントサマリーを公開して以来、公の記録に残っている。正確に読む価値がある。コントロールプレーンが失敗する一方でその下のインフラが動き続けた、最もきれいに記録された事例だからだ。午前10時1分(PDT)、us-east-1のLambda Frontendフリートは通常の日次トラフィックに対してスケールし始めた。午前11時49分、それはAWSの言葉で言えば "a capacity threshold that had previously never been reached within a single cell" を越え、それが "triggered a latent software defect" した。実行環境は割り当てられたが決して使われず、"responsible for managing the underlying compute capacity" するサブシステムは機能する置き換えをプロビジョニングできず、そのリージョンのLambda呼び出しは失敗し始めた。

そして依存グラフがその仕事をした。サマリーはAmazon STS、AWS Management Console、Amazon EKS、Amazon Connect、Amazon EventBridgeを、"as a result of the degraded Lambda function invocations" 劣化したものとして列挙している。STSは午前11時49分から午後2時10分(PDT)まで、"with three distinct periods of impact" 上昇したエラー率を返した。us-east-1のコンソールは午前11時48分から午後2時2分まで、"AWS Management Console is currently unavailable" ページか "504 Time-out" のいずれかを配信した。フェデレーションサインインも劣化した。"Existing IAM sessions were not impacted, but new sign-in federation via SAML was degraded." 完全復旧は午後3時37分(PDT)、影響が始まってから3時間48分後に来た。

それを通常のランブックに重ねてみよう。ステップ1、コンソールにサインインする、劣化。ステップ2、パイプラインに新しいクレデンシャルのためにロールを引き受けさせる、STS、劣化、それも3回別々に。ステップ3、修復用のLambdaを呼び出す、それこそが障害だ。あなたのインスタンスはどれも失敗しなかった。あなたのデータベースはフェイルオーバーしなかった。イベントはあなたのインフラにまったく触れず、それでもあなたの計画が前提としたツールを奪った。教訓は歴史的なものではなく構造的なものだ。運用する層と失敗する層は同じ層であり、そしてまたそうなるだろう。

2025年10月: メルトダウンを、コントロールプレーンから見直す

2025年10月にus-east-1がダウンしたとき、このサイトは同日それをWhen the Cloud Sneezes, the World Catches a Coldで扱った。その記事はブラストラジアスの幅について、インターネットの半分が1つのリージョンに依存していることの不条理についてであり、何を変えるべきかで締めくくった。この回はそれが約束したフォローアップであり、AWSの公式ポストイベントサマリーの恩恵を受けて書かれている。そしてそのサマリーは、当日が許したものよりも冷静な読みに報いる。アプリではなく、ツールに何が起きたかを見よ。

引き金はDNSだった。dynamodb.us-east-1.amazonaws.comに対する "a latent race condition in the DynamoDB DNS management system that resulted in an incorrect empty DNS record"、自動化が "failed to repair" したレコードだ。DynamoDBのエンドポイントは数時間で復旧した。コントロールプレーンの被害はずっと長く続いた。EC2は、サマリーによれば "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"、その14時間のあいだ、そのリージョンのあらゆるマルチAZアーキテクチャの標準的な復旧手段である置き換え容量の起動それ自体が障害を受けていた。STSは午後11時51分から午前9時59分まで "API errors and latency" を返した。IAMユーザーでのコンソールサインインは午前1時25分まで "increased authentication failures" で失敗し、そのリージョンのIdentity Centerユーザーはまったくサインインできず、ルートクレデンシャルとフェデレーションサインインは他のリージョンでさえエラーを投げた。サインインの経路自体がus-east-1にあったからだ。

2つの記事を並べて置けば、分業は明確だ。10月の記事は、1つのリージョンに依存する代償は何かを問うた。この回はその内側にある、より狭く、より厄介な問いを問う。リージョンが悪い日を迎えたとき、なぜ良く構築されたマルチAZアーキテクチャが何時間もダウンし続けたのか。彼らの復旧がコントロールプレーンの操作だったからだ。スケールアウトが修正であり、スケールアウトこそが14時間のインスタンス起動障害が奪ったものだった。全員の計画が同じ劣化したAPIに同時に収束した。それこそが「あなたの計画は他の全員とコントロールプレーンを共有している」が実務上意味することだ。

2026年2月: Azure、同じ形、違うロゴ

これがAWS特有の癖なら、それはAWSの問題だろう。そうではない。2026年2月2日、MicrosoftはインシデントFNJ8-VQZを記録し、そのポストインシデントレビューはこう始まる。"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." Microsoft管理のストレージアカウントで匿名アクセスを無効化することを意図したセキュリティ修復ポリシーが、"a data synchronization problem in the targeting logic" を通じて、"intentionally configured to allow anonymous read access for platform functionality" されたアカウント、つまりVM拡張パッケージを配信するアカウントに適用された。仮想マシンは "failures when deploying or scaling" に見舞われ、AKSは "failures in node provisioning" に見舞われ、GitHub Actionsのジョブは "queued and timed out while waiting to acquire a hosted runner" した。

何が起きなかったかに注目してほしい。稼働中のVMは動き続けた。データプレーンは問題なかった。死んだのは、複数のリージョンで一度に、作成、スケール、変更する能力だった。コントロールプレーンが、データプレーンとは違うやり方で共有されているからだ。それが一般化する価値のある性質だ。コントロールプレーンは、そのデータプレーンが注意深く分離しているゾーン、時にはリージョンにまたがる1つの論理システムだ。それは、まさに全員が復旧しているときに最大負荷を受ける部品であり、マルチリージョンの図が示さないやり方で失敗する。図はあなたのリソースを描くのであって、それを変異させる機構を描かないからだ。2つの提供者、4か月の隔たり、同じ形だ。

静的安定性を、正しく定義する

その防御には名前がある。静的安定性だ。静的に安定なシステムは、依存関係が失敗しても、何も変える必要なく要件を満たし続ける。依存関係に求めたであろうものが、すでに所定の位置にあるからだ。この定義は「静的」という語を勝ち取っている。変異を必要としない復旧は、変異を実行する層によって阻止されえない。具体的には、それは事前計算された決定の小さな一族を意味する。

  • 事前プロビジョニングされた余裕。 各ゾーンが十分な容量を走らせ、生き残ったゾーンが起動なしに全負荷を担う。ゾーンの喪失は、Auto Scalingイベント、コントロールプレーンの操作ではなく、ロードバランサーの決定、データプレーンの操作になる。
  • フェイルオーバー時作成ではなく、事前作成。 スタンバイのDNSレコード、ターゲットグループのアタッチメント、スタンバイインスタンスは、インシデントの前に存在する。フェイルオーバーはヘルスチェックと重みを切り替える。Terraformを走らせはしない。
  • 事前に焼き込まれたイメージ。 パッケージミラー、設定サービス、シークレットエンドポイントに到達せずに配信状態まで起動するAMIは、起動の周りのすべてが劣化していても起動を有用に保つ。
  • 失敗した層を避けるブレークグラス経路。 10月のサマリーはサインインについて率直だ。IAMユーザー、Identity Center、フェデレーションがすべて一緒に劣化した。緊急アクセス経路が本物であるのは、それがあなたが救おうとしているリージョンとIDのプレーンを通らない場合だけであり、そして訓練されている場合だけだ。テストされていないブレークグラスのクレデンシャルは願望にすぎない。

共通の糸は、作業をインシデントの最中からインシデントの前へ、コントロールプレーンのスケジュールからあなたのスケジュールへと移すことだ。提供者のコントロールプレーンを信頼できるものにすることはできない。最初の1時間、それを必要としないように手配することはできる。

ラボ: 差を測れ、主張するな

この回のラボ、03-static-stabilityは、シリーズのルールを承知の上で破る。読み取り専用ではない。TerraformがVPC、インターネット向けのALB、6つのt3.microインスタンスを構築し、破棄するまでお金がかかるので、サンドボックスアカウントに属し、そして同じ日にゴミ箱へ属する。その代価で買えるのは、この記事が描く正確なギャップを、私の主張ではなく、あなたのアカウント上での測定として得ることだ。AWS自身のフォールトインジェクションのドキュメントはその前提を率直に述べている。AZの電源中断シナリオについて、"EC2 API calls made by the Auto Scaling control plane to recover lost capacity in the AZ will fail"、と。ラボはその文への両方の答えを1つのロードバランサーの背後に構築する。パスAは標準的な設計だ。ゾーンごとに1インスタンスを持つAuto Scalingグループとスケーリングポリシーで、ゾーンを失うとASGは復旧のためにec2:RunInstancesを呼ばなければならない。パスBは静的に安定な設計だ。同じワークロードを倍の容量、ゾーンごとに2インスタンスで事前プロビジョニングし、どちらのゾーン単独でもすでに全負荷を担う。

測定スクリプトには注記が必要だ。その最初の草稿が、示唆に富むやり方で間違っていたからだ。ASGから失敗したゾーンのサブネットを単に削除するのはゾーンの喪失ではない。それはリバランスを引き起こし、リバランスは何かを終了させる前に置き換えを起動するので、健全な容量は決して下がらず、測るべきものが何もない。本当のゾーンの喪失はインスタンスを殺す。そこでmeasure.pyはサブネットを削除し、その後そのゾーンのインサービスインスタンスをTerminateInstanceInAutoScalingGroupで、ShouldDecrementDesiredCapacity=False付きで終了させ、各グループを、他所で復旧しなければならない実際の容量だけ落とした状態にする。パスAについては、障害からロードバランサーでの完全な健全カウントまでの間隔を計測する。それは純粋なコントロールプレーンの間隔だ。起動呼び出し、ブート、ヘルスチェックだ。パスBについては、落ち着き待ちの窓を通じて健全カウントを見守り、最小値を記録する。それは4から2へ下がる。2はまさに障害後の要件なので、合格条件は自明に満たされるのではなく実際の低下に対してテストされる。これはスクリプトが表示するテーブルの形であって、私が得た結果ではない。私はこの記事のためにライブアカウントに対してこれを走らせていないし、読者が得る数字は読者のものだ。

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

パスAがあなたに表示するどんな数字も、ベストケースとして読め。それは静かな日の、健全で協力的なコントロールプレーンに対して計測された。10月のコントロールプレーンはそのどちらでもなかった。ラボ04は、パスAの数字をその夜そうなったであろうものに変える、容量不足のエラーを注入することで、そのギャップを埋めるために存在する。

正直な代償と、それが見合わなくなる場所

パスBは同じトラフィックを配信するために倍の定常状態容量を走らせる。それは脚注ではない。それが取引だ。静的安定性は、年に時間単位で測られるイベントに対して、毎時、遊休コンピュートで保険を買うことだ。2ゾーンなら保険料は100パーセント、3ゾーンでそれぞれが失われた1つを吸収できるサイズなら50に下がり、より多くのゾーンや過剰プロビジョニングを織り込んだサイジングなら、それ以下になる。それを払うべきは、ダウンタイムが収益や安全で測られる配信経路、絶対値で倍化が安価な小さなフリート、そしてそれ以外なら復旧がインシデントの最中にコントロールプレーンが機能することに依存してしまうあらゆるものに対してだ。

計算が成り立たなくなる場所では払うのをやめよ。バッチと非同期の作業は、ゾーンの喪失を通じてキューイングすべきであって、それに対して事前プロビジョニングすべきではない。開発とステージングには不要だ。非常に大きなフリートは余裕に本物のお金を払う。そこでの正直な手は、階層を分けることだ。クリティカルな部分には静的安定性を、残りにはコントロールプレーンの復旧を、目を開けたまま受け入れる。そしてこの技法が何をカバーしないかを知れ。それは第1回のCoinbaseを救わなかっただろう。彼らの障害は彼ら自身のデータプレーンにある、建物を共有するクォーラムだったからだ。それは第2回のリージョン喪失には答えない。運命づけられたリージョンの中の余裕は運命づけられた余裕だからだ。それは最初の数時間を守る。予備容量が足りなくなる前にコントロールプレーンが戻ってくるという賭けの上で、だ。その賭けは2023年6月と2025年10月に持ちこたえた。あなたの版のそれが持ちこたえるかは、あなたがテストするものであり、そこがこのシリーズの次の行き先だ。

次に読む

  • このシリーズの第2回、Two Zones, Eighteen Hours, One Cause。me-central-1のイベントと、ゾーン分離が見られない原因だ。
  • このシリーズの第4回、Testing the Assumption。ラボ04がゲームデーを走らせ、この回が描写することしかできなかったコントロールプレーンの障害を注入する。
  • ercan.aiAgents on Call, Part 2. The Foundation: Terraform Before Tokens。別のドメインでの同じ規律だ。あらゆるアカウント境界とIAMロールを最初のインシデントの前にプロビジョニングする。インシデントの最中に構築するには遅すぎるからだ。
  • 付属リポジトリ、nothing-fails-alone。このシリーズのすべてのラボ。これは読み取り専用ではない唯一のもので、そう明記されている。

AWS、クラウドアーキテクチャ、レジリエンスレビュー、プラットフォーム業務のコンサルティングは、ercanermis.comからどうぞ。

参考資料