Motivation
CloudFront + S3 でインデックスドキュメント動作を実現する。Lambda@Edge ではランタイムのサポート期間の長いPythonを使いたい。
背景
CloudFront + S3 で Static Website hosting を使わない場合、インデックスドキュメントの動作を行うためには CloudFront Function または Lambda@Edge での対応が必要になる。
Pythonで実装したいが Lambda@Edge - Python 版実装の情報は少ない。
インデックスドキュメントの動作は CloudFront Functions でも実現可能だが、アプリケーションの構成上、 Lambda@Edge を使いたいこともある。
静的ウェブサイトホスティングはS3バケットをpublic accessにする必要があり、最近のセキュリティ施策で有効にすることの多い Block Public Access と相性が悪い。
実装
appy.py:
def lambda_handler(event, context):
request = event["Records"][0]["cf"]["request"]
old_uri: str = request["uri"]
if old_uri.endswith("/"):
new_uri = old_uri + "index.html"
else:
new_uri = old_uri
request["uri"] = new_uri
return request
- CloudFront の S3オリジンに対し オリジンリクエスト にこのLambda関数を設定する。
-
event
オブジェクトに対してevent["Records"][0]["cf"]["request"]
をreturnするのがデフォルトの動作と同じになる。 -
event["Records"][0]["cf"]["request"]["uri"]
を変更することで、リクエストに対し、S3オブジェクトを変国することができる。
参考
-
https://dev.classmethod.jp/articles/directory-indexes-in-s3-origin-backed-cloudfront/
- できた!S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法
-
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/example-function-add-index.html
- index.html を追加してファイル名を含まない URL をリクエストする
-
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-generating-http-responses-in-requests.html
- リクエストトリガーでの HTTP レスポンスの生成
-
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html
- Lambda@Edge イベント構造