S3静的サイトの「ちゃんとした」構成 ― CloudFront・OAC・WAFで本番品質にする

2026-10-26 | Shinichi Noguchi | AWS

【技術相談】本件の内容に関して30分間の無料相談承ります →

S3静的サイトの「ちゃんとした」構成

この記事をシェア

Before: S3静的ウェブサイトホスティング単体の公開 / After: CloudFront+OAC+非公開S3バケットの構成対比

図: S3単体公開(Before)とCloudFront+OAC+非公開バケット(After)の対比。

「S3バケットを作って、静的ウェブサイトホスティングを有効にすれば、サイトが公開できる」という手順は、AWSの入門書にはほぼ必ず登場します。間違いではありません。手軽だし、動くし、月額も安く済みます。でも入門書の手順をそのまま持ち出して運用すると、3つの壁に当たります。

1つ目は、HTTPSが使えないこと。静的ウェブサイトホスティングが公開するエンドポイント(http://バケット名.s3-website-…)はHTTPです。カスタムドメインを付けても、このエンドポイントのままではTLSを付けられません。2つ目は、バケットが「直接」見えていること。公開のためにバケットを外部アクセス許可にしているので、URLの構造さえ分かれば、サイト経由でなくS3側からもオブジェクトにアクセスできます。入り口がサイトのほかに一つ余計にできるわけです。3つ目は、キャッシュを自分で設計しないこと。AWSが構える世界各地のエッジサーバーを経由しないので、見ている場所によって表示速度がバラバラです。

この記事では、入門構成を「本番構成」に引き上げる手順を順番に見ていきます。題材は当サイト自身です。当サイトもS3バケットの静的ファイルを、CloudFrontのHTTPS配信でshinichi.noguchi.jp.netとして公開しています。記事を公開すると、GitHub ActionsがS3へ同期し、CloudFrontのキャッシュを無効化して、本文のURLがHTTP 200になるまで待つ、という流れが毎回動いています。

※2026年10月26日時点の公開情報に基づきます。料金の金額は試算であり、S3とCloudFrontのリージョン別単価など、この場では現行値が出せない部分は料金ページへの誘導に置き換えています。収益にかかわる最終判断は、必ず公開料金で確認してください。

本番構成の全体像と、その理由

構成は、ユーザー → CloudFront(HTTPS・カスタムドメイン・エッジ配信)→ OAC認証 → 非公開S3バケット、という一本道です。ドメインはRoute 53などのDNSでCloudFrontに向け、証明書はACM(AWS Certificate Manager)で発行します。

この構成を選ぶ理由は3つに整理できます。

  • 配信がエッジ経由になるので、表示速度が安定する。HTTPSもCloudFrontの証明書で提供される
  • S3バケットは完全非公開にできる。CloudFrontからのアクセスだけを許す「OAC」(Origin Access Control)がバケットの鍵を握る
  • デプロイはS3バケットへのaws s3 syncで完結する。配信の品質はCloudFrontに任せられる

なお2026年に入ってから、Amazon S3はVercel Marketplaceでも扱われるようになりました(2026-10-14のAWS発表)。S3をサイトの受け皿にする流れは今も広がっています。一方で、S3はバケットを「静的ファイル置き場」からデータレイクやAI検索(S3 Tables、S3 Vectorsなど)の土台へも広げています。だからこそ、静的サイトという一番素朴な用途を、ちゃんとした構成で押さえておく価値はむしろ上がっています。

OAC設定の最大の落とし穴 ― 「静的ウェブサイトホスティング」を切る

最大の落とし穴が1つあります。S3バケットを「静的ウェブサイトホスティング」に設定したままにしてしまうと、CloudFrontからOACを付けられません(参照: CloudFront開発者ガイド)。S3のオリジンには2種類あり、OACが使えるのは後者だけです。

S3の2つのオリジンの違い
オリジン特徴本番での扱い
静的ウェブサイトホスティングのエンドポイント(バケット名.s3-website-…)HTTP固定。どのリージョンでも同じURL形式でサイトが見られる。配信はカスタムオリジン扱い使わない(OACの対象外)
RESTエンドポイント(バケット名.s3.リージョン.amazonaws.com)OAC対応。SSE-KMSなどの暗号化とも組み合わせ可能CloudFrontのオリジンにする

つまり、入門書で最初に有効化していた「静的ウェブサイトホスティング」の設定は、CloudFront本番構成では無効化しておくのが無難です。有効のままだと、HTTP固定のエンドポイントがそのまま残り、OACを経由しない別の通り道が生き続けるからです。

OACの組み立て方

  1. S3バケットをRESTエンドポイント前提に整える: Block Public Accessを有効のまま、オブジェクトオーナーシップはBucket owner enforced(新規バケットのデフォルト)にする
  2. CloudFrontディストリビューションのオリジンとしてRESTエンドポイントを指定し、Origin Access Controlを作成して紐づける
  3. OACがバケットへアクセスできるよう、バケットポリシーでcloudfront.amazonaws.comを許可する

バケットポリシーの基本形は次の通りです(開発者ガイドの読み取り専用の例をそのまま引用し、バケット名とアカウントIDはデモ用の値に置き換えています)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipalReadOnly",
      "Effect": "Allow",
      "Principal": { "Service": "cloudfront.amazonaws.com" },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/<CloudFront distribution ID>"
        }
      }
    }
  ]
}

※構文自体は公式ドキュメントの例を使っていますが、このバケットポリシーを筆者の環境で新規に作成・評価した実測ではありません。配信IDは実際のCloudFrontディストリビューションIDに置き換える必要があります。

ポイントはConditionです。この配信IDからのアクセスだけを許可するので、他のCloudFront配信がこのバケットをオリジンとして参照する事態を構造的に防げます。

ACM証明書のus-east-1の罠

CloudFrontに紐づけるACM証明書は、米国東部(バージニア北部)リージョン(us-east-1)で発行する必要があります。東京リージョン(ap-northeast-1)で発行した証明書はリージョン不一致で選べません。サイトの利用者が日本中心でも、証明書の発行場所だけはus-east-1です。DNSはRoute 53の場合、CloudFrontへのALIASレコードで割り当てます。

キャッシュ設計 ― HTMLは短く、アセットは長く

HTMLは数十秒〜数分で切れるように短く、CSS・JS・画像は日〜月単位でしっかり持たせる。この2つを分けるのが、静的配信におけるキャッシュ設計の基本です。

分割の考え方はシンプルで、「変わるもの」「変わらないもの」で扱いを分けるだけです。HTMLは記事の追加・修正で内容が変わるので短く。CSSやJavaScript、画像はファイル名にバージョンを付けて変わらないようにすれば、長くキャッシュしても壊れません。この「ファイル名を変える方式」を、いわゆるキャッシュバスティング(破壊)と呼びます。

一方で、ファイル名を変える運用が現実に難しいタイミングがあります。そのときはCloudFrontの無効化(Invalidation)を使い、キャッシュを明示的に破棄してから次回から最新を取りに行かせるようにします。標準配信では無効化に、月あたり一定の無料枠が用意されています(※枠の正確な値は執筆時点で再確認中。詳細は料金ページから)。デプロイパイプラインの最後にcreate-invalidationを差し込むと、手動操作が不要になります。

当サイトの実例

当サイトの静的公開パイプラインは、scripts/blog-publish.shから次の順で動いています。

  1. 変更をfeature/blog-<スラッグ>ブランチにコミットしてpush
  2. GitHub ActionsでPRを作成し、マージ
  3. ワークフロー「Deploy to S3」がaws s3 syncでS3へ同期し、CloudFrontのキャッシュ無効化(invalidation)を発行
  4. 公開URLがHTTP 200になるまで待って、記事の公開を確認

アクセスの先はすべて単一のS3バケットです。CloudFrontのキャッシュ無効化は、S3同期の直後にGitHub Actionsで自動的に発行しています。「マージしたのに記事が見えない」という静的サイトあるあるの原因は、だいたいこの無効化の漏れです。

セキュリティの上乗せ ― Response Headers PolicyとWAF

Response Headers Policy

CloudFrontの「Response Headers Policy」を使うと、CloudFrontがブラウザへ返すレスポンスヘッダー(セキュリティヘッダー)を、配信設定の追加だけで付けられます。初期値のままでは返らないContent-Security-PolicyやStrict-Transport-Securityを、コードを触らずに足せるので、まず選んでおくのが低リスクです。AWSが用意したマネージドポリシー(CloudFront Upgraded Security Headersなど)から始める方法が基本です。

WAFをつけるか

静的サイトに攻撃できる入り口は、問い合わせフォームなどの動的な要素に限られます。その攻撃面がコストに見合うと判断した時点で、WAFの導入を検討すればよいです。やや意外な動きとして、CloudFrontにはフラットレートプラン(月額固定・超過請求なし)が用意されています。$0のFreeプランから始まり、$15/月のProプラン以降は、WAF・DDoS対策・ボット管理・Route 53・CloudWatch Logs・サーバーレスエッジコンピュート・S3ストレージクレジットをまとめて含む料金です。

CloudFrontのフラットレートプラン(2026-10-26時点の公式料金ページの表記による)
プラン月額データ転送 / リクエストS3ストレージクレジットWAFルール数
Free$0100GB / 100万リクエスト5GB5
Pro$1550TB / 1,000万リクエスト50GB25
Business$20050TB / 1億2,500万リクエスト1TB50
Premium$1,00050TB(最大600TBに変更可)/ 5億リクエスト(最大60億に変更可)5TB75

どのプランも超過請求なしです。WAF・DDoS対策・ボット管理・Route 53・CloudWatch Logs・サーバーレスエッジコンピュートも、プランに応じて込みになっています。個人サイト・ブログが本格的にWAFまで持っていくなら、この固定料金に一本化する設計が、2026年時点の選択肢の1つになります。

個人サイト・ブログの段階では、CloudFront標準のDDoS耐性(AWS Shield Standard)を前提にしてまず十分です。静的配信だけのサイトでは、WAFが守れる範囲が狭いことも先に認識しておくと、判断がぶれません。問い合わせや定期収益が動き出してから、費用対効果を検討すればよいです。

料金試算

料金の金額は試算です。S3・CloudFrontともリージョンと用量で単価が変わるため、具体的な金額はS3の料金ページ・CloudFrontの料金ページで最新を確認してください。

小規模静的サイトの月額構造(試算)
項目構造小規模サイトでの目安
S3の保存Standardのリージョン別単価×保存GB数数十円〜数百円
CloudFront従量課金リージョン階段別のデータ転送・リクエスト単価月数十円〜数ドル(ページビュー数万〜数十万程度)
CloudFrontフラットレート月額固定・超過なしWAF・ボット・DNS込みで$15/月からの固定
無効化(Invalidation)パスごとの課金・無料枠あり定型的な公開なら無料枠内

「HTTPS・キャッシュ・セキュリティヘッダー」を一気に整えるなら、WAFまで込みのフラットレートを最初から併用する選択肢が増えたことは、2026年の本番構成だと嬉しい変化です。反対に、サイト規模がごく小さい段階なら従量課金のままで、超過しづらい範囲に留まるのが安価です。

まとめ: 入門構成との違い5つ

この記事で示した「入門から本番」の変化
  • HTTPS: CloudFront + ACM(証明書発行はus-east-1)でTLSを構成し、HTTPのバケット直アクセスはやめる
  • オリジン: RESTエンドポイントをCloudFrontオリジンにして、OACでバケットを完全非公開にする
  • キャッシュ: HTML短命 / アセット長命に分けて、無効化までデプロイパイプラインに組み込む
  • セキュリティ: Response Headers Policyから始め、WAFは費用対効果を見てから
  • 料金: 小規模なら月数十円〜数ドル帯が現実的。WAF込みのフラットレート($15/月〜)は「超過請求なし」の固定に整理できる

「あえて再入門」の観点で最後に一点。入門書の「静的ウェブサイトホスティングを有効化」は、2026年時点では本番運用の入口ではなく、1回だけの動作確認用と位置づけるのがよいです。本番はCloudFront + OAC + 非公開バケットを標準としましょう。

参考資料

💬 無料技術相談のご案内

「S3で公開しているサイトのHTTPSが不安」「CloudFrontに上げたいがOACの設定がややこしい」という方へ。30分間無料でご相談を承っております。

  • S3・CloudFront・OACの現行構成の診断
  • キャッシュ設計とデプロイパイプラインの整備
  • コスト感や導入スケジュールの目安

30年以上のIT経験をもとに、率直にお答えします。強引なセールスや勧誘は一切ありません。

野口真一 野口真一

お気軽にご相談ください

記事に関するご質問や、AI・IT技術導入のご相談など、お気軽にお問い合わせください。