Next.js, Gatsby.js, Nuxt.jsなどのStatic Site Generatorを使ったLPや、JAMStack構成でビルドされたファイルをS3にアップロードしてCloudFrontでキャッシュすることで、サーバーダウンなどを気にしないでページを運用したいなどあると思います。ただの1枚ページのHTMLだけならいいのですが、サブディレクトリにもHTMLファイルがある場合、どうすればいいのか。

https://example.cycloud.io/subdir/

このようなURLにアクセスすると、CloudFrontから Access Denied 403 のレスポンスが返ってきます。

https://example.cycloud.io/subdir/index.html

こうすればアクセスできるのですが、ちょっとかっこ悪いですよね。

Lambda@Edge を使うとこの問題を解決できるので、その方法を紹介します。詳しいセキュリティの説明や、S3のバケット作成手順、CloudFrontのディストリビューションの作成手順は割愛させていただきます。

手順

  • リージョンを us-east-1 にする
  • Lambda関数の新規作成
  • コードソースを書き換えてDeployする
  • 新しいバージョンを発行
  • CloudFrontのトリガーを追加して設定する
  • サブディレクトリのURLにアクセスして表示確認する
  • 参考

リージョンをus-east-1にする

2021年5月時点では、後述する トリガーの選択でCloudFrontを選択できるのがus-east-1リージョンのみ となっているため、リージョンは 米国東部 (バージニア北部)us-east-1 を選択してください。

Lambda@Edge 関数を作成

AWS Lambdaのページから 関数の作成 ボタンを押して、Lambda関数の新規作成を一から作成します。関数名を記入して、ランタイムを Node.js にします。今回は新規から作る紹介なので、デフォルトの実行ロールの変更AWSポリシーテンプレートから新しいロールを作成 を選びます。ロール名を任意で入力し、 ポリシーテンプレートは「cloudfront」と検索 して、 基本的なLambda@Edgeのアクセス権限(CloudFrontトリガーの場合) を選択します。内容を確認して 関数の作成ボタンを押します。

コードソースを書き換えてDeployする

コードソース?ソースコード?どっちかわかりませんが、ここではコードソースと書いてあるのでコードソースと書きます。 index.js を選択して、下記の内容に書き換えます。次に、 新しいバージョンを発行 をクリックします。

index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'use strict';
exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to Lambda@Edge
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;

    // Return to CloudFront
    return callback(null, request);

};

新しいバージョンを発行

バージョンの説明は任意で入力しても良いですし、空白のままでも大丈夫です。 発行 ボタンをクリックして新しいバージョンを発行します。

次の画面は新規で作ったバージョンの画面です。ここから トリガーの追加 ボタンをクリックして、トリガーを追加します。

CloudFrontのトリガーを追加して設定する

トリガーの設定、トリガーを選択から「cloudfront」と検索して CloudFront を選択します。

次のトリガーの設定をします。 CloudFrontトリガーの設定 では、 CloudFrontのディストリビューションIDを入力して選択します。 オリジンリクエストボディを含めるにチェック して、 Lambda@Edgeへのdeployを確認 に同意するにチェックして追加ボタンをクリックします。

サブディレクトリのURLにアクセスして表示確認する

サブディレクトリのURLに直接アクセスして表示確認します。 トリガーの設定してから直ぐにアクセスできないかもしれませんが、 しばらくするとアクセスできたり、何回かリロードすると見れるようになると思います。以上で終わりです。。

参考

▼Lambda@Edge 用の IAM アクセス権限とロールの設定 https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html

▼Implementing Default Directory Indexes in Amazon S3-backed Amazon CloudFront Origins Using Lambda@Edge https://aws.amazon.com/jp/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/