こんにちは!TAMの石川です。
みなさんは、AWSのCloudFrontを使っていますか?
AWS CloudFront を活用していると、ディレクトリのリクエストが 403 Forbidden になったり、より柔軟なカスタマイズが必要になったりすることがありますよね。そんなときに役立つのが Lambda@Edge です!
本記事では、Lambda@Edge の基本的な使い方から、CloudFront の 403エラーを回避する実装方法 まで、ステップごとに解説していきます。また、CloudFront Functions との違い についても触れながら、どちらを選ぶべきか迷わないようにサポートします。
CloudFront をよりパワフルに使いこなしたい方は、ぜひ最後までご覧ください!
Lambda@Edgeとは?CloudFront Functionsとの違いを徹底比較
AWS の CloudFront を活用する際に、「痒い所に手が届く」機能として提供されているのが Lambda@Edge です。
さらに近年では CloudFront Functions も登場し、CloudFront のトリガーを活用したカスタマイズがより柔軟になりました。
本記事では、Lambda@Edge の基本的な使い方を紹介し、特に ディレクトリインデックス(DirectoryIndex)を CloudFront で実現する方法 について解説します。
Lambda@Edge vs CloudFront Functions|どちらを使うべき?
| 特性 | Lambda@Edge | CloudFront Functions |
|---|---|---|
| 対応プログラム言語 | Python 3.13, Node.js | JavaScript(KeyValueStoreサポート) |
| 適用タイミング | ビューワーリクエスト、オリジンリクエスト、オリジンレスポンス、ビューワーレスポンス | ビューワーリクエスト、ビューワーレスポンス |
| 関数設置場所 | バージニア北部 (us-east-1) | CloudFront 設定画面から直接指定 |
| 主な用途 | A/B テスト、レスポンスヘッダーの変更、コンテンツの動的配信 | HTTP リクエストの変更、レスポンスの変更、動的オリジン選択 |
| リクエストボディのアクセス | 可 | 不可 |
| 処理時間(タイムアウト) | 5秒 | 1ミリ秒 |
CloudFront Functionsはシンプルな処理に向いていますが、 「リクエストボディを触りたい」「動的なレスポンスを作りたい」といった場合は Lambda@Edgeを選ぶのが正解です!
【実践】Lambda@EdgeでCloudFrontのディレクトリインデックスを実装する
CloudFrontの「403 Forbidden」問題とは?
CloudFront 経由でオリジンが S3 の場合、ディレクトリにアクセスすると 「403 Forbidden」 が発生することがあります。これは、CloudFront が / だけのリクエストをそのままオリジンに転送するため、適切なオブジェクトが見つからないためです。
例えば:
https://example.com/aaaこのリクエストが S3 に転送されると、aaa/ というオブジェクトは存在せず、エラーが発生します。
この問題を解決するために、Lambda@Edge を活用し、リクエストされた URI の末尾が / の場合に index.html を付与する処理を実装します。
【設定ガイド】Lambda@Edge の導入方法
Lambda@Edge の実行ロールを作成する
Lambda@Edge を実行するために、以下の IAM ポリシーを設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-east-1:703056629600:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:703056629600:log-group:/aws/lambda/*:*"
}
]
}
Lambda@Edge の関数コードを作成する
import json
import re
def lambda_handler(event, context):
request = event["Records"][0]["cf"]["request"]
uri = request["uri"]
if uri.endswith("/"):
uri += "index.html"
elif not re.search(r'\.', uri):
uri += "/index.html"
request["uri"] = uri
return request
CloudFront に Lambda@Edge を適用する
Lambda を作成したら、CloudFront の ビヘイビア設定 で「ビューワーリクエスト」のトリガーに適用します。
注意: Lambda@Edge を CloudFront に適用する際は、関数の バージョンを発行 する必要があります。エイリアスではなく、バージョン番号 ($LATEST ではない) を指定してください。
【検証】Lambda@Edge のテストと動作確認
テスト用イベント(JSON)
以下の JSON をテストイベントとして Lambda のテストを実施できます。
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d111111abcdef8.cloudfront.net",
"eventType": "viewer-request"
},
"request": {
"clientIp": "203.0.113.178",
"uri": "/",
"method": "GET",
"headers": {
"host": [
{ "key": "Host", "value": "d111111abcdef8.cloudfront.net" }
]
}
}
}
}
]
}
【まとめ】Lambda@Edge を活用してCloudFrontを最適化しよう
本記事では、Lambda@Edge を活用して CloudFront でディレクトリインデックスを実現する方法を紹介しました。
Lambda@Edge と CloudFront Functions の違いを理解し、適切なツールを選択することが重要です。 AWS のエッジコンピューティングを活用し、より柔軟なコンテンツ配信を実現してみてください!
