Next.js静的サイトをS3 + CloudFrontで公開したら403になった話(CloudFront Functionで解決)
「デプロイは成功しているのに403。」
Terraformも成功。
GitHub Actionsも成功。
S3にもファイルはある。
それなのに個別記事だけ表示されませんでした。
最初はS3の権限やCloudFrontのOACを疑いましたが、原因はまったく別のところにありました。
Next.jsを静的エクスポートすると、記事ページは /posts/hello/index.html のように生成されます。しかしCloudFrontは /posts/hello というURLを自動ではそのファイルへ変換してくれません。
さらに厄介だったのが、CloudFront Function用のJavaScriptファイルは用意していたものの、Terraformの管理対象に含めていなかったことです。
コードはある。
でもAWSにはFunctionが存在しない。
その結果、URLリライトが実行されず403が返っていました。
最終的にはCloudFront FunctionをTerraformで管理し、Distributionへ関連付けることで解決しました。
この記事では、
- 403になる理由
- なぜS3やIAMではなかったのか
- CloudFront Functionで解決する方法
- Terraformで確認すべきポイント
を実際のコード付きでまとめています。
半日ハマった経験ですが、その分CloudFrontのリクエスト処理の流れを理解できました。
同じ症状で悩んでいる人の参考になれば嬉しいです。
本記事はこちら
https://d3o7t81m8nyt3g.cloudfront.net/blog/2026-06-26-cloudfront-403-url-rewrite