概要
CloudFront と S3 で静的サイトを構築する場合、以下の 2 種類の構成があります。
- CloudFront のオリジンに、 S3 バケットそのものを指定する構成。
- CloudFront のオリジンに、 S3 バケットの Static website hosting のエンドポイントを指定する構成。
できることはだいたい同じですが、微妙に差異があるので、比較します。
まとめ
差異 | 構成 1 | 構成 2 |
---|---|---|
S3 Static Website Hosting の設定 | 不要 | 必要 |
サブディレクトリのインデックスファイル※1 | 利用不可 | 利用可 |
S3 バケットの安全性 | 高 | 低 |
アクセス制限 | CloudFront 側のみで完結 | S3 側でも設定する必要あり |
※1 https://[CloudFront]/foo および https://[CloudFront]/foo/ という URL に対して、 foo/index.html などインデックスファイルを出力する機能。
構成 1. CloudFront のオリジンに、 S3 バケットそのものを指定する構成。
参考: [CloudFront + S3]特定バケットに特定ディストリビューションのみからアクセスできるよう設定する | Developers.IO
主要点
- S3 バケットはパブリックアクセス可能にしない。
- S3 バケットの Static Website Hosting は有効にしない。
- 有効にしても実害はないと思いますが、 CloudFront が S3 バケットに直接アクセスするこの構成では、意味はありません。(多分)
- CloudFront は Origin Access Identity を使って S3 バケットにアクセスする。
メリット
- S3 バケットへ直接アクセスされることを防げる。
- → S3 バケットに大量アクセスがきて、課金額が膨れ上がってしまうケースを防げる。
- S3 バケットの直接アクセスを考えなくていいため、 CloudFront の機能だけである程度のアクセス制限を実現できる。
- AWS WAF や Lambda@Edge によるプログラマブルな制御など。
デメリット
- サブディレクトリのインデックスファイルが効かない。
- S3 バケットに foo/index.html というファイルがあり、 https://[CloudFront]/foo および https://[CloudFront]/foo/ という URL でアクセスしようとしても、エラーになってしまう。
- インデックスファイルは、ルートディレクトリでのみ効く。
- Lambda@Edge を使えば、この機能をある程度エミュレートすることが可能。
- 参考: できた!S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法 | Developers.IO
- ただし (オリジンへの) 全アクセスに対して Lambda が起動するので、パフォーマンス&コストには注意が必要。
- S3 バケットを us-east-1 以外のリージョンで作成した場合、そのバケットを作成してから 1-2 時間?経たないと、正常に動作しない。
構成 2. CloudFront のオリジンに、 S3 バケットの Static website hosting のエンドポイントを指定する構成。
参考: Amazon S3 + CloudFront で始める静的サイトホスティング | kuune.org
主要点
- S3 バケットはパブリックアクセス可能にする。
- S3 バケットの Static Website Hosting を有効にする。
メリット
- サブディレクトリでもインデックスファイルが効く。
- S3 バケットを us-east-1 以外のリージョンで作成しても、すぐ利用できる。
- 構成 1 のデメリットの逆。
デメリット
- S3 バケットの名前が漏れると、 S3 バケットへ直接アクセスされてしまう。
- Amazon S3 + CloudFront で始める静的サイトホスティング | kuune.org にある通り、バケットのポリシーで User Agent による制限を行うことは可能だが……。
- S3の静的ウェブサイトをカスタムオリジンとしてCloudFront運用する場合のS3側接続制限について - Qiita では、S3 バケットのバケットポリシーを定期的に自動更新し、 CloudFront の IP アドレスからのみアクセスできるようにする構成が解説されている。
- S3 バケットに直接アクセスされてしまうため、 CloudFront でアクセス制限を行っていても、それだけでは不十分になってしまう。
後書き
- サブディレクトリの URL には必ず末尾に index.html まで付ける、というルール化が可能であれば、何の問題もなく構成 1 が良いです。
- そうでない場合、構成 2 にするのが設定的には楽ですが、セキュリティに対して留意が必要です。
- 手間とリターンのバランス次第で。