中東で何が起きたか

2026 年 3 月 1 日、イランによるドローン・ミサイル攻撃で UAE の AWS 施設 2 箇所が直撃を受け、バーレーンの施設も近隣への着弾で損傷しました。構造的な損壊に加え、消火設備の作動による水損もあったとされています。経緯は joho-todai.com の記事(2026-09-16)がまとめています。

半年後の 9 月 15 日、AWS は Health Dashboard で、バーレーンリージョン(me-south-1)全域と UAE リージョン(me-central-1)の 1 つのアベイラビリティゾーンについて、そこにのみ保存されていたリソースとデータへのアクセスを回復できないと表明しました。The Register が引用した文言はこうです。

The damage to our infrastructure spanned multiple Availability Zones and exceeded what our regional and multi-AZ services are designed to withstand.

損傷が複数のアベイラビリティゾーンにまたがり、リージョナルサービスとマルチ AZ サービスが耐えるよう設計された範囲を超えた、という説明です。同じ更新で AWS は、大半の顧客はバックアップからの復元や、アクセスできるデータの複製によって、他のリージョンで業務を再開したとも述べています。

失われたのは「そのリージョンにしか無かったデータ」です。他の場所に写しがあった顧客は再開でき、無かった顧客は失いました。

リージョンとアベイラビリティゾーン

AWS の公式説明を引きます。

Each AWS Region consists of a minimum of three, isolated, and physically separate AZs within a geographic area.

AZs are physically separated by a meaningful distance, many kilometers, from any other AZ, although all are within 100 km (60 miles) of each other.

リージョンは地理的な区域(東京、大阪、バーレーンなど)で、その中に最低 3 つのアベイラビリティゾーン(AZ)があります。AZ は独立した電源・冷却・物理セキュリティを持つデータセンター群で、互いに数 km 以上離れています。ただし全て 100 km 圏内です。

「マルチ AZ」は、この 100 km 圏内で複数の AZ に分散させる冗長化です。1 つのデータセンターの停電や火災には効きます。今回のように、同じ区域の複数の施設が同時に破壊される事象には効きません。AWS 自身が「マルチ AZ サービスの設計範囲を超えた」と言っているのはそういう意味です。

区域ごと失う事象に備えるなら、別のリージョンに写しを置くしかありません。これは今回の事象の前から AWS がディザスタリカバリの基本として案内していたことで、新しい知見ではありません。新しかったのは、それが実際に起きたことです。

当社の保管面を棚卸しした

RIKKA M&A の一次保管は、AWS の東京リージョンと Cloudflare R2 にあります。東京に中東ほどの地政学リスクはありませんが、首都直下地震や複数 AZ にまたがる災害は想定の範囲内です。

出発点は「サイトのデータは dev 環境にも同じものがあるから復旧できるが、S3 にしか無いデータは復元不能ではないか」という運営者の問いでした。保管面を全数で列挙し、実測した結果が次のとおりです。

データ実測した状態
DB既に Cloudflare R2 へ日次と毎デプロイで退避。最新世代を取得して全テーブルが揃うことを確認。東京を失っても残る
書類 3 バケット(取引書類・本人確認書類・納品ファイル)東京リージョンの外に 1 部も無い。 レプリケーション未設定、AWS Backup 0 件、アカウント内の全バケットが東京
公開メディア(R2)Cloudflare の外に完全な複製が無い。R2 にはバージョニングも無い
復旧用の暗号鍵(Secrets Manager)東京にのみ。別リージョンのレプリカ無し
R2 上の DB バックアップ本番ホストの R2 トークンで削除できる(テストオブジェクトで put → rm が通ることを実測)。バケットロック無し

そして前提の「dev に同じデータがある」は事実ではありませんでした。同じ SQL を両環境で実行すると、ノード数も会員数も交渉数も一致しません。dev は本番の複製ではなく、seed とテストで乖離していく環境でした。復旧の起点は R2 の日次ダンプであって、dev ではないと確定させるところから始まりました。

書類 3 バケットは S3 のバージョニングが有効でしたが、バージョニングは誤削除への備えであって、リージョン喪失には無力です。今回の事象そのものです。

どう直したか、なぜその構成にしたか

原則を 5 つ決めてから実装しました。

原則理由
再生成できないデータは、一次保管と異なるプロバイダに 1 部以上今回の事象は「同一プロバイダの同一リージョンに全部あった」ことが致命傷。DB は既に満たし、書類とメディアが満たしていなかった
AWS 一次のデータは東京の外に 1 部。サービスが提供する管理型の複製を使い、スクリプトを書かないスクリプト型のバックアップは「存在するが動いていない」の再発点になる。当社にはその実例が複数ある
本番ホストの資格情報では消せない写しを 1 部本番侵害=バックアップ全滅、を断つ
削除の約束(プライバシーポリシー)はバックアップにも及ぶ。保持は有限で、自動的に整合させるバックアップを「消えない個人情報の倉庫」にしない
「存在」ではなく**「復元」で検証**し、失敗は沈黙させないバックアップが取れていることと、戻せることは別

実装は翌日 1 日で行いました。

  • 書類 3 バケットを大阪リージョンへ S3 Cross-Region Replication。 delete marker の伝播を有効にし、一次で削除すると大阪でも現行版が消えます(削除の約束を複製先でも守る)。版指定の削除は複製されないので、悪意ある完全削除には耐えます。既存分は Batch Replication で初回同期し、全件を突合しました。複製失敗はイベント通知でメールに届き、置いてから失敗通知まで 24 秒で到達することを誘発試験で確かめました
  • 復旧用の暗号鍵を Secrets Manager の大阪レプリカへ。 管理型で自動同期されます。本番ホストからはレプリカにも到達できないことを否定テストで確認しました
  • 書類 3 バケットを Cloudflare R2 へ日付付きスナップショット(日次・35 日で失効)。AWS アカウントごと失う事象への備えです。一次の件数とバイト数が R2 側と全数一致しなければ失敗として通知します
  • R2 にバケットロック。 DB ダンプと書類スナップショットの prefix に 35 日のロックを掛けました。バケット設定は管理者権限でしか変えられず、本番のオブジェクト読み書きトークンでは解除も削除もできません。実物の最新世代の削除が拒否されることを本番のトークンで実測しました
  • R2 の公開メディアを大阪の S3 へ日次ミラー。 R2 に無いバージョニングを S3 側で持ち、書き込みに使う IAM には版の削除権限を与えていません。本番の鍵で put は通り、版削除は拒否されることを確認しました
  • 実効状態の検査をデプロイと週次 cron に配線。 複製規則・宛先・通知・鍵レプリカが外されていないか、直近 24 時間の複製失敗が続いていないかを読み取り専用の鍵で確かめます。期待値をわざとずらして検査が落ちることも確認しました
  • DB ダンプを公開鍵暗号(age)で暗号化。 本番には公開鍵だけを置き、秘密鍵は Secrets Manager(東京と大阪レプリカ)・開発機・紙の 3 か所に分けました。本番が侵害されても、既に R2 にある世代を読み解く鍵は本番にありません。公開鍵が無ければ平文で置かずに止まります
  • 監査ログ(CloudTrail)2 本を R2 へ差分ミラー。 小さなオブジェクトが二十数万件あるため日付付きスナップショットではなく差分方式にしました

書類 3 バケットについては、S3 CRR、AWS Backup、別プロバイダへのスナップショット、バージョニングのみ、の 4 案を比較しました。CRR は管理型で失敗検知も備わり、東京喪失と本番侵害に効きますが、AWS アカウントの喪失には効きません。そこを別プロバイダへのスナップショットで塞ぎます。どちらか一方では塞げない脅威が残るので、両方です。

なぜ複数リージョンで稼働させなかったか

今回の事象で失われたのは「そのリージョンにしか無かったデータ」で、AWS も「大半の顧客はバックアップから他リージョンで再開した」と述べています。守るべき第一は、データが別の場所に残っていることです。常時 2 つのリージョンでアプリを動かしていることではありません。

当社の計算資源は Lightsail 1 台で、docker compose で動き、DB もそのホスト上にあります。そして Lightsail は大阪リージョンに無い(AWS 公式の提供リージョン一覧。エンドポイント不存在も実測)。2 リージョン稼働にするなら EC2 と RDS を前提とした別の構成になり、それは RDS への移行計画の中で扱う話です。

選んだのは「データは大阪と別プロバイダに複製し、計算資源はリージョン非依存の手順書から再構築する」形です。入力は GitHub のコード、開発機に退避した本番固有ファイル、大阪レプリカの復旧鍵、R2 の DB ダンプ、大阪の書類レプリカの 5 つだけで、本番には一切依存しません。目標復旧時点(RPO)は、書類が分単位、DB とメディアが 24 時間以内です。目標復旧時間(RTO)は、この手順書を実際に通して測りました(次節)。

費用は判断基準にしていませんが、事実として月額 7.6 ドル程度です。大半は複製の失敗を検知するための CloudWatch メトリクスと Secrets Manager のレプリカで、保存容量そのものは数セントです。

何が改善したか

脅威とデータの組み合わせで、before → after を示します。

データ東京リージョン全損Cloudflare 喪失AWS アカウント喪失本番ホスト侵害
DB✔(R2)✔✔(R2)△ → ✔ バケットロック
書類 3 バケット✘ → ✔ 大阪 CRR✔✘ → ✔ R2 スナップショット✔(大阪へ本番の鍵は到達不能)
公開メディア✔✘ → ✔ 大阪 S3✔✘ → ✔ 版削除不可の鍵
復旧用の暗号鍵✘ → ✔ 大阪レプリカ✔✘(開発機の写しで緩和)✔

「復元」の検証は、データ層で 1 回、計算資源を含めた全再構築で 1 回、通しました。

データ層では、R2 の最新ダンプをスクラッチ DB に戻して全テーブルが揃うこと、大阪レプリカから取り出した鍵で暗号化された口座情報を復号できること(誤った鍵では拒否されること)、大阪の書類レプリカから取得したファイルが一次と一致することを確認しました。

全再構築は同じ日の午後に、大阪リージョンの EC2 で行いました。入力は上記の 5 つだけで、DB ダンプの復号鍵も開発機のものは使わず大阪レプリカから取り出しています(開発機を同時に失った想定)。DNS は切り替えず、ホスト内から本番のホスト名でオリジンの応答を確かめました。主要ページが全て 200 を返し、管理者のログインリンクが受理されて 2 要素認証の画面まで進み、暗号化された口座情報が復号でき、大阪の書類レプリカから署名付き URL で取得でき、エラーログが 0 件でした。

RTO の実測は 36 分 20 秒(インスタンス作成から検証完了まで。DNS 切替は含みません)。ただし、この時間には手順書の穴を直しながら進めた約 20 分が含まれています。デプロイは 4 回目で完走し、初回構築ではまだ無いコンテナへメンテナンスモードを設定しようとして止まる、アプリの IAM がレプリカ先のバケットに到達できない、コンテナのログ送信先が東京固定で起動しない、Docker ネットワークのアドレスが作成順で変わりオリジンの許可リストに合わない、など手順書に無かった穴が 7 つ見つかりました。全て手順書に反映してあり、次回は 20 分程度の見込みです。費用は 1 回 0.05 ドル程度でした。

副産物の事故も書いておきます。リハーサルで見つけた Docker ネットワークのアドレス固定を本番へ反映したところ、値は同じでも宣言が変わったためにネットワークが削除・再作成され、コンテナ間の名前解決が壊れて約 6 分停止しました。復旧はコンテナを全て作り直すだけでしたが、ネットワーク定義を変えるデプロイは通常の自動デプロイに任せず、メンテナンス窓で手動で行う、という規約を足しました。

次回のリハーサルは 1 年後です。

まとめ

  • マルチ AZ は 100 km 圏内の冗長化です。区域ごと失う事象には効きません。AWS 自身が「設計範囲を超えた」と表明しました
  • S3 のバージョニングは誤削除への備えであって、リージョン喪失には無力です
  • 「dev に同じデータがある」は復旧手段になりません。実測して初めて分かりました
  • 再生成できないデータは、別リージョンと別プロバイダに 1 部ずつ。本番ホストの資格情報で消せない写しを 1 部
  • 複製は管理型のサービスに任せ、失敗は通知させ、規則が外されていないかを定期検査してください
  • 「取れている」と「戻せる」は別です。戻す手順を実際に通してください。当社は全再構築を通して初めて手順書の穴が 7 つ見つかり、RTO 36 分が測れました