😳

CloudFront Functions(cloudfront-js-2.0) と KeyValueStores でリダイレクトする

2024/02/06に公開

対象読者

この記事は以下のような人を対象としています。

  • AWS初心者
  • AWS S3 + CloudFront がホスティング環境である
  • リダイレクトのやり方に悩んでいる
  • CloudFront KeyValueStore の存在を初めて知った

はじめに

S3 + CloudFront でホスティングしている環境で、特定のファイルにアクセスされた場合のリダイレクト処理は予めJSONを用意しておいて、CodeBuild の post_build で、 aws-clis3api を叩いて前述のJSONをもとにオブジェクトのmeta情報を書き換えていました。
そう、今までは。

そして先日、久々にCloudFrontのダッシュボードから関数を覗いたら 「KeyValueStores」 っていうのが増えてて「なんじゃコリャ?」となりました。
KeyValueStores

おまけに関数一覧にも Runtime というタブが増えていて同じく「なんじゃコリャ?」となりました。
Runtime

どうやら 「KeyValueStores」は2023年11月にリリースされたらしい。
このリリースに併せて CloudFront Functions に新しい Runtime も追加されたもよう。[1]

みんな大好きクラスメソッドさんの記事[2]を見る限り、CloudFront Functions の Runtime2.0 [3] にすれば、 CloudFront KeyValueStores を使えるようになって、 async/await とか JavaScript ES6 の機能がいくつか使えうようになるらしい。

つまり、前述したリダイレクト処理が CloudFront Functions + KeyValueStores を使えばできそうじゃん?と思ったのでやってみました。
この記事はその備忘録になります。

やること

  1. リダイレクト用のKeyValueStoresを作成する
  2. Key Value のペアを追加する
  3. リダイレクト用のCloudFront Functionsを作成する
  4. 1と2を紐付ける
  5. 作成した関数を公開してディストリビューションの Viewer Request に紐づける
  6. 動作確認

1.リダイレクト用のKeyValueStoresを作成する

AWSにログインし、CloudFrontに入ったら左メニューの関数から関数一覧に遷移し、KeyValueStoresを選択しましょう。

するとKeyValueStores一覧にたどり着きますので画面右の「Create KeyValueStores」をクリックして新しい KeyValueStores を作成します。

KeyValueStoresを選択

KeyValueStoresの新規作成画面に入ったら、Nameを入力(必須)しましょう、Descriptionは任意なので入力しなくても良いですが、後から見たときに何に利用する KeyValueStores か理解しやすいので入力したほうが良いかなと個人的には思います。

指定のフォーマットに沿ったJSONをS3に置いてそれを参照することも可能ですが、今回は割愛します。
JSONのフォーマットは公式ドキュメントやこの記事の注釈にあるクラメソさんのブログ [2:1] に書いてあるのでご確認ください。

Name(と、Description)の入力が終わったら「Create」ボタンをクリックしてKeyValueStoresを作成しましょう。
ボタンクリック後、プロビジョニングに少しだけ時間がかかりますが体感的に10秒くらいです。

KeyValueStoresを作成

無事に作成が終わると、作成したKeyValueStoresの詳細画面に遷移し、画面上部にグリーンのアラートが表示されます。
無事に作成が終わった

2.Key Value のペアを追加する

さっそく先程作成した KeyValueStores に Key と Value のペアを追加してきましょう。
詳細画面に Key value pairs というセクションがあると思うので、そこから「Add key value pairs」ボタンをクリックして、 Key と Value のペアを追加する画面(編集画面)に遷移します。
編集画面へ遷移する

Key value pairs に入ったら「Add pair」ボタンをクリックします。
すると新しい Key / Value を入力するための行が追加されます。
この際、Key には リダイレクト元となるURLを入力し、Value にはリダイレクト先となるURLを入力してください。
Key / Value を入力した際は入力欄横の✅を必ずクリックしましょう。
✅をクリックしないと入力した値が正しく反映されないためです。
keyとvalueを入力する

Key / Value の入力が完了し、一覧に反映されたら「Save changes」ボタンをクリックして保存しましょう。

クリックすると保存状態を知らせるモーダルが表示されますので、モーダルのテキストが「Success」と表示されれば完了です。
「Done」をクリックして、 KeyValueStoresでの操作を完了します。

次はリダイレクト用のCloudFront Functionsを作成しましょう。

3.リダイレクト用のCloudFront Functionsを作成する

CloudFront Functionsの一覧から「関数を作成」ボタンをクリックして、新規作成画面に遷移します。
名前と説明(任意)を入力し、Runtimeは cloudfront-js-2.0 を選択しましょう。
cloudfront-js-2.0 を選択しないと先ほど作成した KeyValueStores が利用でいないので注意してください。
これらの入力が終わったら「関数を作成」ボタンをクリックして関数を作成します。
関数を作成

関数が作成できたら次のようなコードを入力します。

リダイレクト用サンプルコード

// CloudFront Functionsのランタイム 2.0 から
// KeyValueStoresにアクセスできるヘルパーメソッド
import cf from 'cloudfront';

const kvsId = '作成したKeyValueStoresのIDが入る';

// キー・バリュー・ストアが関数と関連付けられていない場合、これは失敗する。
const kvsHandle = cf.kvs(kvsId);

async function handler(event) {
  const request = event.request;
  const host = request.headers.host.value;
  const uri = request.uri;

  // URLに index.html が入っていた場合はkeyに合わせるため取り除く
  const urlRemoveIndex = uri.replace('index.html', '');

  // KeyValueStores に対象となるキーが存在するか
  const hasKey = await kvsHandle.exists(urlRemoveIndex);

  if (hasKey) {
    try {
      // キーが存在した場合、対象となるKeyValueStoresからキーを元に value を取得する
      const value = await kvsHandle.get(urlRemoveIndex);

      // リダイレクト処理
      return {
        statusCode: 301,
        statusDescription: 'Moved Permanently',
        headers: {
          "location": {
            "value": `https://${host + value}`
          }
        }
      }
    } catch (err) {
      console.log(`Kvs key lookup failed for ${urlRemoveIndex}: ${err}`);
    }
  }
  // キーが存在しなければ何もしない
  return request;
}

作成したKeyValueStoresのIDはKeyValueStoresの詳細画面から確認できます。[4]
KVSのID

4.作成した1と2を紐付ける

作成した関数とKeyValueStoresを紐づけましょう。
この時点で恐らく関数の詳細画面にいると思いますので「Associated KeyValueStore」から「Associate existing KeyValueStore」ボタンをクリックして、 表示されるモーダルの中にあるプルダウンから紐づけします。

紐づけ

無事に紐づけが完了すると、関数の画面に先ほど作成したKeyValueStoresが表示されます。

5.作成した関数を公開してディストリビューションの Viewer Request に紐づける

ここまでの手順が完了すれば発行タブから、関数を発行して、ディストリビューションの Viewer Request に紐づけましょう。

関数を発行

リダイレクト処理を適用したいディストリビューションのビヘイビアへ遷移し、 Viewer Request に先程作成した関数を紐づけます。

リダイレクト処理を適用

6. 動作確認

ディストリビューションがデプロイされたら、実際にリダイレクトを設定したURLにアクセスしましょう。
KeyValueStoresに設定した Key/Value に沿ってリダイレクトができていれば作業完了です。
お疲れ様でした!

最後に

普段の業務はフロントエンドのコードを書くことがメインなので、AWSはたま〜にしか触らないのですが、たまに触るといつの間にかアップデートが施されていたりして、便利な機能が追加されている事があります。
いつも業務で触るのとは違う技術に触れるのは良い刺激になるし、勉強になるのでとても面白いですね。

最後まで見ていただきありがとうございました!

脚注
  1. Amazon CloudFront が、グローバルなマネージドキー値データストアである CloudFront KeyValueStore をリリース ↩︎

  2. CloudFront KeyValueStoreがリリース。CloudFront Functionsからキーバリューストアを利用可能に! ↩︎ ↩︎

  3. 正しくは cloudfront-js-2.0 という名称です ↩︎

  4. 関数とKeyValueStoresの紐づけが終わったらKeyValueStoresのIDが画面に表示されるようになるのでそこからも確認できます ↩︎

株式会社HAMWORKS

Discussion