SJ blog
architecture
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

CloudFrontキャッシュ動作設計 — キャッシュポリシー・オリジンリクエストポリシー・TTL

CloudFrontのキャッシュビヘイビア、キャッシュポリシー(CachingOptimized等)、オリジンリクエストポリシー、カスタムCacheKey設定、TTL制御、Invalidation、Origin Groupsを解説。

一言結論

CloudFrontのキャッシュヒット率を最大化するにはキャッシュキーにクッキーやヘッダーを含めないことが基本で、どうしても動的コンテンツが必要な場合はパスパターンでキャッシュビヘイビアを分離するのが定石だ。

CloudFrontのキャッシュ仕組み

CloudFrontはエッジロケーションにコンテンツをキャッシュし、オリジンサーバーへのリクエストを削減する。キャッシュの動作はCache BehaviorとCache Policyで細かく制御できる。

リクエストフロー:
  クライアント → エッジロケーション(キャッシュチェック)
    ↓ キャッシュHIT → クライアントに返す
    ↓ キャッシュMISS → オリジンにリクエスト → キャッシュ → クライアントに返す

キャッシュポリシー(Cache Policy)

キャッシュキーとTTLを定義する。

# キャッシュポリシーの作成
aws cloudfront create-cache-policy \
  --cache-policy-config '{
    "Name": "custom-cache-policy",
    "DefaultTTL": 86400,
    "MaxTTL": 31536000,
    "MinTTL": 0,
    "ParametersInCacheKeyAndForwardedToOrigin": {
      "EnableAcceptEncodingGzip": true,
      "EnableAcceptEncodingBrotli": true,
      "HeadersConfig": {
        "HeaderBehavior": "none"
      },
      "CookiesConfig": {
        "CookieBehavior": "none"
      },
      "QueryStringsConfig": {
        "QueryStringBehavior": "whitelist",
        "QueryStrings": {
          "Items": ["version", "lang"],
          "Quantity": 2
        }
      }
    }
  }'

AWSマネージドキャッシュポリシー

CachingOptimized:
  - 最大TTL: 31536000秒(1年)
  - Gzip/Brotli圧縮対応
  - Cookie/ヘッダー/クエリ文字列はキャッシュキーに含めない
  - 静的コンテンツに最適

CachingDisabled:
  - TTL: 0秒(キャッシュしない)
  - 動的コンテンツや認証済みAPIに使用

CachingOptimizedForUncompressedObjects:
  - 圧縮無効版のCachingOptimized
  - 既に圧縮済みのコンテンツ(JPEG等)向け

オリジンリクエストポリシー(Origin Request Policy)

キャッシュには含めないがオリジンに転送する情報を定義する。

# オリジンリクエストポリシー例(IPを転送、Cookieはキャッシュキーに含めないが転送する)
aws cloudfront create-origin-request-policy \
  --origin-request-policy-config '{
    "Name": "forward-user-ip",
    "HeadersConfig": {
      "HeaderBehavior": "whitelist",
      "Headers": {
        "Items": ["CloudFront-Viewer-Country", "CloudFront-Viewer-City"],
        "Quantity": 2
      }
    },
    "CookiesConfig": {
      "CookieBehavior": "all"
    },
    "QueryStringsConfig": {
      "QueryStringBehavior": "all"
    }
  }'

Cache BehaviorとPath Pattern

複数のCache BehaviorをPath Patternで使い分ける。

Default (*):
  → すべてのリクエスト
  → キャッシュポリシー: CachingOptimized
  → オリジン: S3バケット(静的コンテンツ)

/api/*:
  → APIリクエスト
  → キャッシュポリシー: CachingDisabled
  → オリジン: ALB(動的コンテンツ)
  → ビューワープロトコルポリシー: HTTPS Only

/images/*:
  → 画像専用
  → TTL: 7日間
  → オリジン: S3バケット
# ディストリビューションのCache Behavior更新
aws cloudfront update-distribution \
  --id DISTRIBUTION_ID \
  --distribution-config '{
    "CacheBehaviors": {
      "Quantity": 1,
      "Items": [{
        "PathPattern": "/api/*",
        "TargetOriginId": "alb-origin",
        "CachePolicyId": "CACHING-DISABLED-POLICY-ID",
        "ViewerProtocolPolicy": "https-only",
        "AllowedMethods": {
          "Quantity": 7,
          "Items": ["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"]
        }
      }]
    }
  }'

Cache Invalidation(キャッシュ無効化)

# 特定のパスのキャッシュを削除
aws cloudfront create-invalidation \
  --distribution-id DISTRIBUTION_ID \
  --paths '/images/logo.png' '/css/style.css'

# ワイルドカードで一括削除(コスト: 最初の1,000パス/月は無料、超過は$0.005/パス)
aws cloudfront create-invalidation \
  --distribution-id DISTRIBUTION_ID \
  --paths '/*'

頻繁なInvalidationはコストがかかる。URLにバージョン番号やハッシュを付けることでキャッシュバスティングを実装する方が効率的だ。

# ❌ コスト高: デプロイのたびに/* をInvalidate
# ✅ 推奨: ファイル名にハッシュを含める
  style.css → style.a1b2c3.css
  app.js    → app.x9y8z7.js

Origin Groups(フェイルオーバー)

プライマリオリジンが障害の場合にセカンダリに切り替える。

# Origin Groupの設定(プライマリ: 東京ALB、セカンダリ: 大阪ALB)
aws cloudfront create-distribution \
  --distribution-config '{
    "Origins": {
      "Items": [
        {"Id": "primary-origin", "DomainName": "primary.example.com"},
        {"Id": "secondary-origin", "DomainName": "secondary.example.com"}
      ]
    },
    "OriginGroups": {
      "Items": [{
        "Id": "failover-group",
        "FailoverCriteria": {
          "StatusCodes": {"Items": [500, 502, 503, 504], "Quantity": 4}
        },
        "Members": {
          "Items": [
            {"OriginId": "primary-origin"},
            {"OriginId": "secondary-origin"}
          ]
        }
      }]
    }
  }'

TTLの制御

TTLの優先順位:
1. Cache-Control: max-age(オリジンのレスポンスヘッダー)
2. Expires ヘッダー
3. CloudFrontのデフォルトTTL設定
4. Max TTL (上限)
5. Min TTL (下限)

例:
  オリジンがCache-Control: max-age=3600 を返す
  CloudFrontのDefaultTTL: 86400
  → 3600秒でキャッシュが失効(オリジンの設定が優先)
  
  オリジンがCache-Controlを返さない場合
  → CloudFrontのDefaultTTL(86400秒)が使われる

試験頻出ポイント

シナリオ回答
APIパスはキャッシュしたくないCache Behavior + CachingDisabledポリシー
静的コンテンツのキャッシュ最大化CachingOptimized + 長いTTL
デプロイ後にキャッシュを更新Invalidation または URLバージョニング
オリジン障害時の自動切り替えOrigin Groups
クエリ文字列をキャッシュキーに含めるCache PolicyのQueryStringsConfig設定

まとめ

CloudFrontのキャッシュ設計はパスパターン別のCache BehaviorとキャッシュポリシーのAWSマネージドポリシーを活用することで効率的に設定できる。静的コンテンツはCachingOptimized、動的APIはCachingDisabledで明確に分離することが基本設計だ。