index.html を省略して
CloudFrontのサブディレクトリへアクセスしたときにindex.htmlを表示させたい!
CloudFrontにデフォルトディレクトリインデックスというものを実装して実現していきます。
index.html を省略してルートURLにアクセスする方法は↓をご覧ください
現状
CloudFrontのオリジンにしているS3バケットにはこんな感じでindex.htmlを配置しています
1 2 3 4 |
~$ aws s3 ls --recursive s3://<S3バケット名> 2023-07-23 23:38:50 0 about/ 2023-07-23 23:42:30 279 about/index.html 2023-07-23 23:42:48 273 index.html |
aboutというサブディレクトリにアクセスした場合、index.htmlを指定しないと表示しません
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// ファイル名指定 ~$ curl https://test.hisui-app.com/about/index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>about/index.html</h1> </body> </html> // ファイル名省略 ~$ curl https://test.hisui-app.com/about/ ~$ |
ただ、デフォルトルートインデックスにindex.htmlを設定しているため、
ルートURLにアクセスした場合にはindex.htmlが返ってきます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// ファイル名指定 ~$ curl https://test.hisui-app.com/index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>index.html</h1> </body> </html> // ファイル名省略 :~$ curl https://test.hisui-app.com <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>index.html</h1> </body> </html> |
CloudFront Functions とは?
まずは、デフォルトディレクトリインデックスの実装に必要なCloudFront Functionsについて。
特定のイベントタイプに対して、事前に定義しているJavaScriptの関数を実行できる機能のこと。
イベントタイプには2種類あり、
- ビューワーリクエスト:ビューワーからリクエストを受信したとき
- ビューワーレスポンス:ビューワーにレスポンスを返す前
リクエスト(レスポンス)ヘッダーの操作やリダイレクト処理などを実現できます。
公式ドキュメントは↓です。目を通してみるといいと思います
デフォルトディレクトリインデックスとは??
デフォルトルートオブジェクトを設定しただけでは、サブディレクトリに対してはエラーを返してしまいます。
そこで、デフォルトディレクトリインデックスを実装し、
デフォルトインデックスファイル(今回は index.html)を返すようにします。
アーキテクト図はこちらです
例えば、https://example.com/about にアクセスするとします。
- Cloudfront Fuctions で https://example.com/about/index.html に書き換え
- CloudFrontやオリジンからレスポンスを返す
このような機能(デフォルトディレクトリインデックス)を実装していきます。
CloudFront Functions の料金
公式サイトより、
100 万件の呼び出しあたり 0.10 USD です (1 回の呼び出しごとに 0.0000001 USD)。
また、無料枠として
各月 2,000,000 件の CloudFront Function 呼び出し
が設けられています。
実装
CloudFront Functions
CloudFront Functions で実行する関数はこちらのコードをそのまま使います
jsファイルを作成し、tfファイルから参照するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function handler(event) { var request = event.request; var uri = request.uri; // Check whether the URI is missing a file name. if (uri.endsWith("/")) { request.uri += "index.html"; } // Check whether the URI is missing a file extension. else if (!uri.includes(".")) { request.uri += "/index.html"; } return request; } |
if文を使ってリクエストURIをindex.html を付与したものに書き換えます。
Terraform
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
resource "aws_cloudfront_distribution" "main" { ... default_cache_behavior { ... # CloudFront Functionsの紐づけ function_association { event_type = "viewer-request" function_arn = aws_cloudfront_function.main.arn } } ... } ... # CloudFront Functions resource "aws_cloudfront_function" "main" { name = "function" runtime = "cloudfront-js-1.0" comment = "default directory index" publish = true code = file("./CloudFront_Functions/function.js") } |
aws_cloudfront_distribution > default_cache_behavior ブロック内で
CloudFront Functionsを紐づけていきます
プロパティ | 説明 |
event_type | どのイベントタイプで実行するか viewer-request に対して関数を実行します |
function_arn | 後ほど定義するCloudFront Functions のARNを指定します |
aws_cloudfront_function にて、CloudFront Functions を定義します。
プロパティ | 説明 |
name ※ | CloudFront Functions の名前 |
runtime ※ | ランタイム。2023/07現在、cloudfront-js-1.0 のみ指定可能 |
comment | コメント。 |
publish | 関数をデプロイするかどうか。デフォルトはtrue。 テストなどをしたい方はデプロイしない(false) ことも可能。 |
code ※ | 関数のソースコード。先ほど作成したjsファイルを相対パスで指定。 |
※ は必須項目
plan , apply
1 2 |
$ terraform plan $ terraform apply -auto-approve |
ダウンタイムはなかったと思います。。。
動作確認
サブディレクトに対してもindex.htmlが返ってくればOKです!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
~$ curl https://test.hisui-app.com/about/ <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>about/index.html</h1> </body> </html> |
参考文献
コメント