1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS障害に学ぶ】CloudFront VPC Origins 障害 ―「よくある構成」への影響と、watch・備えの型

1
Posted at

対象: 2026/07/16 に発生した Amazon CloudFront の障害(JST 20:18 に完全復旧、AWS の [RESOLVED] 発表は JST 21:22)

👋 はじめに

2026/07/16の夕方、大規模な AWS 障害が発生しました!!

影響を受けたのは Amazon CloudFront の VPC Origins 接続を使っている構成
CloudFront + 内部 ALB という、わりと採用例の多い「よくある構成」なんです。

この記事では、その「よくある構成」を題材に、次の流れで整理します。

  • こういう構成だと今回のケースに該当します
  • タイムラインはこうでした(障害の追い方)
  • 特別な対応をしなくても復旧したが、本来どう watch すべきか(監視の型)
  • もし該当構成に手を入れるなら、どうあるべきか(回避策と CDK 実装例)

なお、障害情報は AWS の公式ステータス(CloudFront RSS)と公開報道を情報源にしています。

🏗️ こういう構成だと、今回のケースに該当します

今回影響を受けるのは、次のようなごく一般的な「CloudFront + 内部ALB」構成です。

利用者 → Route53(Alias) → CloudFront ┬─ 動的リクエスト → VPC Origin(内部ALB) → コンテナ/アプリ
                                      └─ 静的アセット   → S3 オリジン
  • CloudFront → 内部ALB を VPC Origins で接続する(ALB を公開せず、公開SSL証明書も不要にできる構成)。
  • 動的リクエスト(API/画面)が VPC Origin 経由だと、今回壊れた「エッジ→VPC ルーティング」を直撃する。
  • 一方 S3 オリジン側(SPA アセット・静的ファイル)は VPC を経由しないので、この障害の影響外。

結果として「静的配信は生きているが、動的な API/画面だけ 5xx になる」という部分障害の形になり得ます。VPC Origins をアプリ経路に採用しているシステムは、程度の差はあれ同じ弱点を抱えていると言えます。

なぜ VPC Origins を選ぶのか

そもそも、なぜ内部 ALB を VPC Origins で繋ぐのか。採用理由は主に3つです。

  • ALB を公開しなくて済む:パブリック IP もインターネットゲートウェイ経由の受けも不要になり、攻撃対象領域(Attack Surface)を減らせる。
  • ALB 側に公開 SSL 証明書を載せる必要がない:CloudFront↔ALB 間は VPC 内の閉じた経路なので、証明書管理を CloudFront 側に一本化できる。
  • CloudFront をバイパスした直接アクセスを防げる:WAF や署名付き URL といったエッジの防御を、必ず経由させられる。

コードにすると、こういうイメージです(識別子は例示用)。

import { Duration } from 'aws-cdk-lib';
import { Distribution, OriginProtocolPolicy, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
import { VpcOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';

// CloudFront → 内部ALB を VPC Origin で接続
// 狙い: ALB を公開せず、ALB 側の SSL 証明書も不要にする
const webAlbVpcOrigin = VpcOrigin.withApplicationLoadBalancer(webAlb, {
  protocolPolicy: OriginProtocolPolicy.HTTP_ONLY, // 経路が VPC 内で閉じるため HTTP
  readTimeout: Duration.seconds(60),
});

new Distribution(this, 'WebDistribution', {
  defaultBehavior: {
    origin: webAlbVpcOrigin, // 動的リクエスト(API/画面)は VPC Origin 経由
    viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
    // cachePolicy / originRequestPolicy などは要件に応じて
  },
  // 静的アセットや署名付きダウンロードは S3 オリジン(VPC を経由しない)を別ビヘイビアで割り当てる
});

この「公開しないための VPC Origins」という選択は、裏を返すと「CloudFront↔VPC 経路に一点集中する」ことでもあります。得られるのはセキュリティ、引き換えに失いがちなのが経路の冗長性。今回の障害は、そのトレードオフが表面化したケースと言えます。

📌 学び
VPC Origins は「公開しない安全性」と引き換えに、CloudFront↔VPC 経路への依存を一点に集める。採用時に「壊れたときの代替経路」までセットで考えておきたい。

📅 タイムラインはこうでした

AWS Service Health Dashboard の CloudFront RSS(https://status.aws.amazon.com/rss/cloudfront.rss)を追いました。時刻は AWS 表記が PDT (UTC-7)JST = PDT + 16時間 で併記します。

PDT JST 内容
07/16 00:45 07/16 16:45 障害発生(後の発表で判明した開始時刻)
07/16 01:44 07/16 17:44 「VPC Origins 利用者で 5xx エラー増加」調査開始の一報
07/16 02:21 07/16 18:21 続報。原因未特定、緩和作業中。回避策としてオリジンタイプ変更を案内
07/16 03:18 07/16 19:18 Service impactService degradation に変化。根本原因を特定(エッジ→VPCルーティングのパケット処理サブシステム)
07/16 04:16 07/16 20:16 原因をさらに絞り込み(ルーティングテーブルの容量)。緩和策を特定・テスト中、テスト後に段階展開予定
07/16 04:27 07/16 20:27 **初期の復旧の兆候(initial signs of recovery)**を確認
07/16 04:57 07/16 20:57 緩和策の効果で復旧が大きく進行。完全復旧は45分以内の見込みと発表
07/16 05:22 07/16 21:22 [RESOLVED] 完全復旧を発表。オリジンタイプを変更した利用者は元に戻してOK

AWS の RCA によると、障害の影響時間は 12:45〜4:18 AM PDT(JST 16:45〜20:18、約3時間33分)。復旧経緯は「2:57 AM PDT に原因特定 → 3:52 AM PDT に複数の緩和策を実施 → 4:18 AM PDT(JST 20:18)に完全復旧」でした。

ここで注目したいのが復旧のタイミングです。AWS が正式に [RESOLVED] を出したのは JST 21:22。しかし RCA が示す実際の完全復旧は JST 20:18 で、公式アナウンスは実際の復旧より 1 時間ほど遅れています。裏を返せば、ステータスページの「Resolved」を待っていると、実際の復旧を1時間見逃すということです(この教訓は後述の監視の型につながります)。

そしてもう一つ、RSS を追っていてハマったのが lastBuildDate の読み方でした。フィードは再生成のたびに時刻が進むのですが、新しい <item> が増えていなければ状況は何も動いていない。時刻だけ見て「更新された」と勘違いしないのが地味に大事でした。

🌍 影響範囲(ネットからの情報収集)

複数メディアの報道を総合すると、単一アプリに閉じた話ではなく広域の障害でした(内容はライセンス配慮のため要約・言い換えしています)。

  • 障害開始は 12:45 AM PDT(JST 16:45)で、現地の午前中いっぱい継続。Mirror の報道
  • Downdetector で AWS 関連の障害報告が 350 件超に達したとの報道。Express の報道
  • 影響は VPC Origins 利用者に限定される一方、複数リージョンの Web サイト/アプリでログイン失敗や 504 タイムアウトが観測された。KuCoin の報道
  • Frankfurt (FRA) インフラとの関連を指摘する報道もあり。Sunday Guardian / Gigazine

要するに「利用者側のミスではなく AWS 側のマネージドサービス障害」であり、利用者側でコードを直しても直らないタイプ。復旧は基本 AWS 待ちです。だからこそ「影響範囲の即時特定」と「代替経路の有無」が明暗を分けます。

👀 何もしなくても復旧する。それでも、どう watch すべきか

今回のような AWS 側障害は、利用者が手を動かして直せるものではありません。実際、特別な対応をしなくても、AWS の段階復旧とともにサービスは戻ります。それでも「正しく watch する」ことには大きな価値があります。慌ててオリジンタイプを引き剥がすような過剰反応を避け、復旧を客観的に判断できるからです。

まずは手動確認、からの自動化

最初は RSS を手で確認していましたが、睨み続けるのは非効率です。そこで 新しい <item>(guid)が出た瞬間だけログに記録する PowerShell スクリプトで監視を自動化しました。

# 2分ごと(ttl 5分に対して十分)にポーリングし、新item検出時のみ記録
$url = 'https://status.aws.amazon.com/rss/cloudfront.rss'
$stateFile = Join-Path $env:TEMP 'cloudfront-rss-lastguid.txt'
$lastGuid = if (Test-Path $stateFile) { (Get-Content $stateFile -Raw).Trim() } else { '' }

while ($true) {
  [xml]$rss = (Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 30).Content
  $item = $rss.rss.channel.item | Select-Object -First 1
  # title/description は CDATA。.InnerText で取り出さないと XmlElement になる罠
  $guid = if ($item.guid.InnerText) { $item.guid.InnerText } else { [string]$item.guid }

  if ($guid -ne $lastGuid) {
    $lastGuid = $guid
    Set-Content -Path $stateFile -Value $guid -Encoding UTF8
    Write-Output ("*** NEW *** {0} / {1}" -f $item.title.InnerText, $item.pubDate)
  }
  Start-Sleep -Seconds 120
}

小さなハマりどころが2つありました。

  • title / descriptionCDATA なので、[string] で受けると System.Xml.XmlElement になってしまう。.InnerText で取り出す。
  • 前回の guid を state ファイルに保存し、増分だけ通知する。これをしないと再生成のたびに毎回ヒットしてノイズだらけになる。

これで「新しい発表が出た時だけ」ログに落ちるようになり、張り付きから解放されました。ただし、これはあくまで暫定策です。

本来やるべき監視の型

RSS ポーリングは手早いですが、恒久策は別にあります。

Health API / EventBridge で「自分のアカウントの」イベントを取る

実は RSS の説明文にも書いてあるのですが、アカウント固有のイベントは EventBridge の aws.health ソース、または Health API で取得するのが本筋です。

  • グローバルな RSS と違い、自分のリソースが影響を受けているかを判定できる。
  • EventBridge ルールで Slack / Teams / PagerDuty へ即時通知できる(人間が RSS を睨む必要がない)。

自前メトリクスで「実害」と「復旧」を裏取りする

  • CloudFront:5xxErrorRate
  • ALB:HTTPCode_ELB_5XX_Count / TargetResponseTime
  • CloudFront 5xx と ALB 5xx が乖離していれば、「アプリは正常だが CloudFront↔VPC 間で落ちている」と切り分けできる(=今回の障害の兆候)。

前掲のとおり、今回は AWS の [RESOLVED] 発表(JST 21:22)より、実際の完全復旧(JST 20:18)が 1 時間先行していました。自前メトリクスでエラー率の推移を見ていれば、公式アナウンスを待たずに復旧を判断できたはずです。ただし段階デプロイの最中は再発(フラッピング)もあり得るため、単発のアクセス成功ではなくエラー率が継続的にゼロ近傍へ戻ったかで判断するのが安全です。

📌 学び
ステータスページは「世界の状況」、Health API は「自分の状況」、自前メトリクスは「実害と復旧の裏取り」。三点セットで見ると判断が速い。そして ステータスページは現実より遅れる。復旧判定は公式アナウンスではなく、自前メトリクスのエラー率推移で行う。

🧯 もし該当構成に手を入れるなら、どうあるべきか

「特に何もしなくても復旧した」とはいえ、次に同じことが起きたときのために備えは考えておきたいところです。

論点の整理:「Route53 を前段に」ではない

よくある発想として「Route53 を前段に置けば?」がありますが、Route53 は DNS なのでそもそも既に最前段にいます。本当の論点は「VPC Origins 単一依存をやめ、代替経路(フェイルオーバー先)を持つか」です。

案A:CloudFront Origin Group によるフェイルオーバー(本命)

CloudFront の Origin Group は、プライマリが指定ステータスコードを返したときにセカンダリへ再試行する仕組みです。

  • Origin Group は プライマリ + セカンダリの 2 オリジン構成AWS 公式ドキュメント
  • フェイルオーバー対象コードは 500 / 502 / 503 / 504 / 403 / 404(2026年5月時点)から選択。BlazingCDN の解説
  • 今回の障害は 5xx を返すため、primary = VPC Origin / secondary = 非VPC経路 を組んでいれば自動フェイルオーバーが成立し得た

注意点も明確です。

  • セカンダリを VPC Origin にしても無意味(同じ障害に巻き込まれる)。別系統(S3 の縮退ページ等)にする必要がある。
  • CloudFront はステータスコードのみで判定する。200 で中身が壊れているケースはフェイルオーバーしない。

CDK 実装例(aws-cdk-lib v2)

VPC Origin をプライマリ、S3 の縮退ページをセカンダリにする Origin Group の例です(リソース名は例示用)。

import { Distribution, OriginProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
import {
  VpcOrigin,
  S3BucketOrigin,
  OriginGroup,
} from 'aws-cdk-lib/aws-cloudfront-origins';

// プライマリ: 内部ALB への VPC Origin(従来どおり)
const primaryOrigin = VpcOrigin.withApplicationLoadBalancer(alb, {
  protocolPolicy: OriginProtocolPolicy.HTTP_ONLY,
});

// セカンダリ: 縮退ページ(メンテナンス告知など)を置いた S3
const fallbackOrigin = S3BucketOrigin.withOriginAccessControl(fallbackBucket);

// Origin Group: 5xx を検知したらセカンダリへフェイルオーバー
const webOriginGroup = new OriginGroup({
  primaryOrigin,
  fallbackOrigin,
  fallbackStatusCodes: [500, 502, 503, 504],
});

new Distribution(this, 'WebDistribution', {
  defaultBehavior: {
    origin: webOriginGroup,
    // viewerProtocolPolicy, cachePolicy などは既存設定を流用
  },
});

これだけで「動的経路が 5xx を返したら、静的な縮退ページに切り替わる」動きが実現できます。全機能は維持できませんが、「全断」を「縮退表示」に変えるだけでも体感は大きく違います。

案B:Route53 + CloudFront ハイブリッドフェイルオーバー

AWS は Route53 ヘルスチェックと Origin Group を組み合わせる「ハイブリッドオリジンフェイルオーバー」も公開しています。AWS 公式ブログ

  • 利点:DNS 層でも切り替えられ、経路制御の自由度が高い。
  • 難点:フェイルオーバーはタイムアウト経過後に発火するためレイテンシが乗る。今回のような「CloudFront 内部機能だけ壊れる」障害は、ヘルスチェックでの綺麗な検知が難しい。

案C:縮退運用(Graceful Degradation)を割り切る

全機能の維持を諦め、S3 の静的ページ(メンテ告知/読み取り専用画面)へフェイルオーバーさせて「全断」を防ぐ。コスト対効果は一番高いことが多いです。案A の CDK 例がそのまま使えます。

📌 学び
「どこまでの障害を自前で吸収するか」を先に決める。CloudFront 地域障害まで完全冗長化するのは費用対効果が合わないことが多く、まずは Origin Group で S3 縮退ページへ逃がすのが現実解。


参考リンク

注記: 本記事中の報道・外部記事の内容は、ライセンス配慮のため要約・言い換えを行っています。

本ブログに掲載している内容は、私個人の見解であり、所属する組織の立場や戦略、意見を代表するものではありません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?