はじめに
基本的な構築方法は省略
ルーティング問題
URLを/foo
/bar
の用に Router系でパス指定した場合、ローカルやNginx等では動いてたのにCloudFrontだと、403エラーになるという問題が起きる。これを回避するために CloudFrontで403エラーが発生したら /index.html
に転送するという方法がよく行われている(というか自分もVue Routerで下記などの事例を参考に適用していた)。
なんでも200 OK問題
- ファビコンをちゃんと用意してないとブラウザーが
/favicon.ico
を引っ張ってくるが/index.html
のHTMLが転送される。(まあ、アイコンとして表示されないけど気持ち悪い) - 脆弱性検知ツール等がデバッグ用とか管理用のファイルとかのよくあるパスでアクセスしてきて、それに対して200で応答を返すので、そのファイル消したほうが良いって警告される。(まあ、そういうもんだって話ですが、監査を受けると説明しなきゃいけない)
-
foo.png
bar.js
hage.css
とかなんでも/index.html
のHTMLなのはどうなのか…。
CloudFront Functions
AWS samplesにそれっぽいものがある /
-> /index.html
と /foo/
-> /foo/index.html
って書き換えなので、上記のような書き換えだとうまく行かない。
なので、上記をベースに拡張子なし=ルーティングされたもの、と言う判断で書き換えれば良い。
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file extension.
if (!uri.includes('.')) {
request.uri = "/index.html";
}
return request;
}
Terraform
resource "aws_cloudfront_function" "test" {
name = "test"
runtime = "cloudfront-js-1.0"
comment = "my function"
publish = true
code = file("${path.module}/function.js")
}
resource "aws_cloudfront_distribution" "example" {
# 省略
default_cache_behavior {
# 省略
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.test.arn
}
}
# 省略
}