こんにちは!TAMの石川です。
みなさんは、AWSのCloudFrontを使っていますか?
AWS CloudFront を活用していると、ディレクトリのリクエストが 403 Forbidden になったり、より柔軟なカスタマイズが必要になったりすることがありますよね。そんなときに役立つのが Lambda@Edge です!
本記事では、Lambda@Edge の基本的な使い方から、CloudFront の 403エラーを回避する実装方法 まで、ステップごとに解説していきます。あわせて、CloudFront Functionsや2026年時点で選択肢に加わったCloudFront KeyValueStoreとの使い分けも整理し、「どれを選ぶべきか」で迷わないようサポートします。
この記事でわかること
- Lambda@Edge / CloudFront Functions / KeyValueStore の違いと選び方
- CloudFrontで403 Forbiddenが起きる理由
- Lambda@Edgeでディレクトリインデックスを実装する手順(コード付き)
- テスト・動作確認の方法
Lambda@Edge・CloudFront Functions・KeyValueStoreの違い
CloudFrontのエッジで処理を挟む方法は、2026年現在おもに3つあります。まずは全体像を比較表で押さえましょう。
| 特性 | Lambda@Edge | CloudFront Functions |
|---|---|---|
| 言語 / ランタイム | Node.js / Python | JavaScript(専用runtime 2.0) |
| 適用タイミング | ビューワー/オリジンのリクエスト・レスポンス4種 | ビューワーのリクエスト・レスポンス2種 |
| 実行場所 | リージョナルエッジキャッシュ(13拠点) | エッジロケーション(225拠点以上) |
| 実行時間の上限 | 数秒(ビューワー系5秒 / オリジン系30秒) | 1ミリ秒未満の超軽量 |
| メモリ | 128MB〜3GB | 2MB |
| ネットワークアクセス | 可 | 不可 |
| リクエストボディへのアクセス | 可 | 不可 |
| 主な用途 | A/Bテスト、動的配信、オリジン処理、複雑なロジック | URLリライト、リダイレクト、ヘッダー操作など軽量処理 |
選び方のフロー
- URLリライト・リダイレクト・ヘッダー操作など軽量で高頻度 → CloudFront Functions(低コスト・超高速)
- ネットワークアクセス・オリジントリガー・複雑なロジックが必要 → Lambda@Edge
- フィーチャーフラグやリダイレクトマップなどの設定値を参照したい → CloudFront Functions + KeyValueStore(エッジでネットワーク呼び出しなしに設定を読み取れる)
※単純なディレクトリインデックス付与だけなら、実は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
※ランタイムは、公開時点でサポートされている最新のPython/Node.jsバージョンを選択してください(古いランタイムはサポート終了に注意)。
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" }
]
}
}
}
}
]
}
よくある質問(FAQ)
Q. まずCloudFront FunctionsとLambda@Edge、どちらから検討すべき?
URLリライトやリダイレクトのような軽量処理なら、コストと速度で有利なCloudFront Functionsから検討するのがおすすめです。ネットワークアクセスやオリジンレスポンスの加工が必要になった時点でLambda@Edgeに切り替えます。
Q. 反映されない・削除できないときは?
Lambda@Edgeはエッジ全体にレプリケートされるため、関連付け解除後もレプリカ削除まで時間がかかります。ディストリビューションからトリガーを外し、伝播完了を待ってから関数を削除してください。
【まとめ】Lambda@Edge を活用してCloudFrontを最適化しよう
本記事では、Lambda@Edgeを使ってCloudFrontの403対策(ディレクトリインデックス)を実装する方法を紹介しました。
ポイントは、Lambda@Edge / CloudFront Functions / KeyValueStoreの特性を理解し、用途に応じて使い分けることです。軽量処理はFunctions、複雑な処理はLambda@Edge——この基準を押さえれば、エッジ活用の設計で迷うことは少なくなります。
AWSの設計・運用でお困りですか?
\ AWS構築・運用、マネージドセキュリティまで、クララがご支援! /
