AWS CloudFront + S3構成について
まず、AWS CloudFront + S3で構成するパターンは下記2パターンあります。
- CloudFront のオリジンにS3バケットそのものを指定する構成
- CloudFront のオリジンにS3バケットのStatic website hostingのエンドポイントを指定する構成
ですが、現状、2のパターンはS3への直接アクセスを許可してしまうため、セキュリティとして非推奨のようです。
なので1のパターンで構成することを考えます。
「 1. CloudFront のオリジンにS3バケットそのものを指定する構成」ではデフォルトルートオブジェクトのファイル名(index.html)をディストリビューションで指定しているオリジンのルートにしか設定できません。
そのため、サブディレクトリへのパス(例) xxx.com/aaa/
へアクセスすると、そのディレクトリにindex.htmlがあったとしても403エラーとなります。
これを解決するには Lambda@Edgeを作成します。
Lambda@Edge作成手順
Lambda@Edge作成の手順として下記のようになります。
-
Lambda関数作成
コンソールから「関数の作成」をクリックして関数を作成する
※注意:Lambda@Edge 関数の作成は、現時点ではバージニアリージョンでしかできないようですので、us-east-1(米国東部:バージニア北部)を選択します -
Lambda関数のコードを実装
下記のような実装をします。(参考リンクにあるソースをそのまま使用できます)
CloudFrontイベント「オリジンリクエスト」イベントをハンドルし、リクエストパスの末尾が「/」で終わっているものを「/index.html」に置き換える。
-
Lambda関数を CloudFront ディストリビューションに関連付けるために必要なIAM アクセス許可の設定をする
参考:https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html -
Lambda関数のトリガーを設定
CloudFrontを選択し、下記を設定する
- ディストリビューション:任意のディストリビューション
- CloudFrontイベント:オリジンリクエスト
- レプリケートの有効化:チェックする
これでサブディレクトリのパスにアクセスしてもindex.htmlを返すようになりました!!!
参考:
CloudFront が、サブディレクトリからデフォルトのルートオブジェクトを返さないのはなぜですか?
Lambda@Edgeの設定例
S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法
Lambda@Edgeのログ確認方法
CloudWatch LogsでLambda@Edgeのログの確認ができます。
CloudWatchコンソール
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1
※CloudFrontにアクセスしたとき、Lambda@Edgeを動作させたエッジロケーションによってログ出力されるリージョンが決定されます。(Lambda@Edge作成したときに選択したリージョンに出力されるわけではないことに注意です)
参考:
https://dev.classmethod.jp/articles/where-is-the-lambda-edge-log/