CloudFront Functionsを使用して過去の記事を特定のページへリダイレクトしてみた

CloudFront Functionsを使用して過去の記事を特定のページへリダイレクトしてみた

CloudFront Functions を使って特定の日付以前の記事をリダイレクトする方法についてご紹介しています。
Clock Icon2025.03.25

どうもさいちゃんです。皆さん CloudFront Functions でリダイレクト設定を行ったことはありますか?
今回は CloudFront Functions を使用して過去の日付の記事を最新ページへとリダイレクトする設定を試してみました。
CloudFront Functions を使用してリダイレクトをしたいという方の参考になれば幸いです。

CloudFront Functions について

まずは、Cloudfront Functions とはどんなサービスなのかについて簡単に説明します。

CloudFront Functions は CloudFront のエッジロケーションでコードを実行できるサービスです。主に URL の書き換えやリダイレクト、HTTP ヘッダーの操作や簡単な認証設定などの簡単なタスクに使用され、リクエストやレスポンスを高速で処理してくれます。使用できる言語は JavaScript です。
実行時間が短く、メモリ使用量も制限されているため、複雑な処理は Lambda@Edge、簡単な処理は Cloudfront Functions と使い分けることが多いです。

Cloudfront Functions について詳しく記載しているブログと AWS ドキュメントを参考資料として置いておきます。

https://dev.classmethod.jp/articles/amazon-cloudfront-functions-release/
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html

過去の記事を最新ページへリダイレクトする

今回はある特定の日付よりも過去の日付のブログやニュースページを最新のページへリダイレクトする方法を紹介します。
ユースケースは以下の通りです。

  • サイトリニューアルに伴う古い記事の URL 整理やコンテンツ統合により、過去のページを新しいページへリダイレクトしたい
  • 期間限定のキャンペーンやイベントページを、終了後に常設ページへリダイレクトしたい
function handler(event) {
  var request = event.request;
  var uri = request.uri;

  if (uri.startsWith("/news/")) {
    var match = uri.match(/\/news\/(\d{4})\//);
    if (match && parseInt(match[1]) <= 2019) {
      return {
        statusCode: 301,
        statusDescription: "Moved Permanently",
        headers: {
          location: { value: "/news/" },
        },
      };
    }
  }

  return request;
}

この関数コードを使って早速リダイレクト設定をしてみます。

やってみた

まずは、CloudFront コンソールの左側のナビゲーションペインから Functions を選択して、関数を作成しましょう。

CF Functions-6.png

名前と簡単な説明を付けて関数を作成します。ランタイムはデフォルトでcloudfront-js-2.0に設定されているのでそのまま作成します。

CF Functions-7.png

作成出来たら、関数のページの 構築タブから 関数コード内の関数を用意したモノに書き換え、保存します。
この時点では、関数はまだデプロイされていません。

CF Functions-8.png

となりのテストタブについてです。
本ブログでは、実際に関数をデプロイしてディストリビューションに関連付けた後にうまくリダイレクト出来るかをテストしていますが、実際の現場ではそういったテストが難しいという場合の方が多いと思います。
Cloudfront Functions ではデプロイ前にウェブリクエストを模したテストイベントを入力して、どの様な応答結果をしますかのテストを行うことが出来ます。

例えば、今回の場合はURL パスの欄を/news/2019/12/31.html に変更してテストしてみます。

CF Functions-9.png

JSON で入力する場合は以下のようになります。

{
  "version": "1.0",
  "context": {
    "distributionDomainName": "d111111abcdef8.cloudfront.net",
    "distributionId": "EDFDVBD6EXAMPLE",
    "eventType": "viewer-request",
    "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE=="
  },
  "viewer": {
    "ip": "198.51.100.11"
  },
  "request": {
    "method": "GET",
    "uri": "/news/2019/12/31.html",
    "headers": {
      "host": {
        "value": "www.example.com"
      }
    }
  }
}

今回の関数では URI 以外の情報は特に評価の必要がないのですべてダミーの情報で問題ないです。

するとこんなテスト結果が返ってきます

{
  "response": {
    "headers": {
      "location": {
        "value": "/news/"
      }
    },
    "statusDescription": "Moved Permanently",
    "cookies": {},
    "statusCode": 301
  }
}

ステータスコードはページが恒久的に移動した事を示す 301 になっており、レスポンスとしてリダイレクト先の news のトップページの場所を返してあげています。
では 2020 年のページはどうでしょうか?

{
  "request": {
    "headers": {
      "host": {
        "value": "www.example.com"
      }
    },
    "method": "GET",
    "querystring": {},
    "uri": "/news/2020/01/01.html",
    "cookies": {}
  }
}

ステータスコードや location ヘッダーが含まれてませんよね。つまりリダイレクトは行われていません。
やりたかったリダイレクト設定はこのコードで実現可能な事が分かりました。

このようにテストを行った後に、発行タブから関数の発行を選択します。これで関数のデプロイが完了しました。

CF Functions-10.png

しかしまだ、発行した関数とディストリビューションの紐づけがまだです。
関数の発行が無事終わると、下に 関連付けられているディストリビューションという欄が出てくるので 関連付けを追加をクリックします。

CF Functions-11.png

紐づけたいディストリビューションを選び、
今回は、CloudFront がビューワーからリクエストを受信する時にこの関数を実行したいのでイベントタイプは Viewer Requestを選択します。
キャッシュビヘイビアは**Default (*)**で問題ないです。

CF Functions-12.png

CloudFront Functions のコンソールから、対象の関数のステータスの更新を待って、ステータスが デプロイ済みとなれば、関連付けが完了しています。

CF Functions-13.png

上記のテストでレスポンスが意図した通りに帰ってくることは確認できましたが、
せっかくなので実際のページがリダイレクトされるかどうかのテスト結果もこのブログでご紹介します。

テスト

今回はテスト用に HTML ファイルを生成 AI に作ってもらいました。
余談ですが、私は最近何かしらの検証をする際に生成 AI にテスト環境を作ってもらうという使い方をよくしています。
本来の検証に集中できる時間がしっかりと確保できるようになり、とても助かってます。
生成 AI にテスト内容を伝え、テスト用に HTML ファイルを作成するようお願いすると下記のようなディレクトリ構造で HTML ファイルを作成するスクリプトを作ってくれました。

root/
│
├── index.html
│
└── news/
    ├── index.html  (ニューストップページ - 薄い青)
    │
    ├── 2018/
    │   └── 01/
    │       └── 01.html  (2018年の記事 - 薄い赤)
    │
    ├── 2019/
    │   └── 12/
    │       └── 31.html  (2019年の記事 - 薄い黄色)
    │
    └── 2020/
        └── 01/
            └── 01.html  (2020年の記事 - 薄い緑)

しかも色分けまでしてくれてます。ありがたい。

それぞれ下記の様に 2020 年よりも前の記事をトップページの/news/index.html へとリダイレクトできれば成功です。

  • /news/2018/01/01.html → /news/index.html へとリダイレクト
  • /news/2019/12/31.html → /news/index.html へとリダイレクト
  • /news/2020/01/01.html → リダイレクトなし

早速試してみましょう。

まず、先ほど作成した関数をディストリビューションに関連づける前にそれぞれのページを確認します。

  • /news/index.html:ニューストップページ(古い記事のリダイレクト先)

CF Functions-2.png

  • /news/2018/01/01.html:2018 年の記事(リダイレクトされるはず)

CF Functions-3.png

  • /news/2019/12/31.html:2019 年の記事(リダイレクトされるはず)

CF Functions-4.png

  • /news/2020/01/01.html:2020 年の記事 (このまま表示されるはず)

CF Functions-5.png

では実際にアクセスしてみます。
リダイレクトされたものに関してはリダイレクト先の画像では分かりづらいと思うので開発者ツールのキャプチャを載せます。

  • /news/2018/01/01.html

CF Functions-14.png

  • /news/2019/12/31.html

CF Functions-15.png

  • /news/2020/01/01.html

CF Functions-16.png

開発者ツール

CF Functions-17.png

意図したとおりにリダイレクトされていますね。

最後に

今回は Cloudfront Functions を使ったリダイレクトの例として過去の記事を特定のページへリダイレクトする方法をご紹介しました。
私はリダイレクト処理を ALB でしか行ったことがなかったのですが、Cloudfront Functions の方が簡単に設定出来ました。CloudFront がある環境の場合は絶対に Cloudfront Functions を活用しようと思います。この記事がどなたかのお役に立てば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.