見出し画像

CloudFront Functionsでリダイレクトする

CloudFrontでのリダイレクトをCloudFront Functionsでやってみました。

構成

構成としては以下の通り。オリジンを設定しないとCloudFrontのディストリビューションが作れないので、S3を設定しています。

オリジンS3バケットの作成

まずは、オリジンとなるS3バケットを作成します。

バケット名を入力して、それ以外はデフォルトで大丈夫です。

バケットが作成されたら、バケットの詳細画面に入ります。

アクセスが来た際に表示するHTMLファイルをアップロードしておきます。

CloudFrontオリジンアクセスコントロールの作成

次は、CloudFrontからS3バケットにアクセスするためのオリジンアクセスコントロール(以降OAC)を作成します。CloudFrontのコンソールから、セキュリティのオリジンアクセスに遷移します。コントロール設定を作成ボタンをクリックします。

OACの名前を入力し、オリジンタイプはS3に設定してCreateボタンをクリックしてOACを作成します。

CloudFrontディストリビューションの作成

次は、CloudFrontのディストリビューションを作成します。

Origin domainには、作成したS3バケットを指定します。名前は、S3バケットを選択した際に自動で設定されますので、そのままでも変えてもどちらでも良いです。本記事ではそのままで行きます。

オリジンアクセスは、Origin access control settings (recommended)を選択し、先ほど作成したOACを選択します。

WAFは無しで進めます。

料金クラスは、北米、欧州、アジア、中東、アフリカを選択にしておきます。

その他はデフォルトのままで、ディストリビューションを作成ボタンをクリックして、ディストリビューションを作成します。

作成されたらポリシーをコピーボタンが黄色の帯の右側にあるので、クリックしてポリシーをコピーしておきます。

オリジンS3バケットのバケットポリシーを設定

S3バケットに戻り、アクセス許可のタブのバケットポリシーの編集ボタンをクリックします。

先ほど、CloudFrontのディストリビューションを作成後にコピーしたポリシーを、ポリシー欄にペーストして、変更の保存ボタンをクリックします。

CloudFrontとS3の連携を確認

前述までで、CloudFrontのURLで、S3に配置したHTMLファイル見えるようになっています。CloudFrontのURLをコピーします。

最終変更日がデプロイになっている場合は、まだ作成されていないため、日付が表示されるまで待ちます。

URLの末尾に/index.htmlをつけて、ブラウザからアクセスしてみます。
※ここでは、デフォルトルートオブジェクトをindex.htmlで設定していないため、URLの末尾につける必要があります。

以下のような形で、S3に配置したファイルの内容が見れれば、確認完了です。

無事に表示されたので、CloudFrontとS3の連携は無事にできたことが確認できました。

CloudFrontのリダイレクト関数の作成

最後に、CloudFront Functionsを作成しますので、関数の画面に遷移し、関数を作成ボタンをクリックします。

名前を入力し、Runtimeにcloudfront-js-2.0を選択し関数を作成をクリックします。cloudfront-js-1.0でも出来ますが、今であればcloudfront-js-2.0の方が古い書き方で書かなくて済むので良いかと思います。

作成されたら下部のタブまでスクロールします。

作成されたら下部の構築タブで、リダイレクト用のコードを記述して、変更を保存ボタンをクリックします。

今回はコードとしては以下を記述しました。

function handler(event) {
  const uri = event.request.uri
  if (isNotRedirect(uri)) return event.request

  const newUri = getNewUri(uri)
  return {
    statusCode: 301,
    statusDescription: 'Moved Permanently',
    headers: { location: { value: newUri } },
  }
}

function isNotRedirect(uri) {
  return uri === '/' || uri === '/index.html'
}

function getNewUri(uri) {
  if (uri === '/page1.html') {
    return 'https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html'
  }
  return 'https://aws.amazon.com/jp/'
}

以下の通りのリダイレクトになっています。

  • / or /index.html

    • リダイレクトしない

  • /page1.html

    • CloudFrontのドキュメントにリダイレクトする

  • それ以外

    • AWSのトップページにリダイレクトする

発行タブをクリックして、関数を発行ボタンをクリックします。

関連付けられているディストリビューションのエリアが表示されるので、関連付けを追加ボタンをクリックします。

ディストリビューションに、作成したCloudFrontディストリビューションを選択します。イベントタイプにはViewer requestを選択し、キャッシュビヘイビアにDefaultを選択して、関連付けを追加ボタンをクリックします。

CloudFrontの関数一覧に戻ると、ステータスが更新中になっているので、しばらく待ちます。

ステータスがデプロイ済みになったら完了です。

リダイレクト処理の確認

最後に、リダイレクト処理が想定通りにされているか確認します。確認の前にキャッシュの削除はしてから確認します。

まずは、/index.htmlにアクセスして、S3に配置してあるindex.htmlが表示されるか確認します。

次に、/page1.htmlにアクセスして、CloudFrontのドキュメントが表示されるか確認します。

最後に、page2.htmlなど、適当なパスを指定してアクセスし、AWSの画面が表示されるか確認します。

事後処理

今回作成したリソースの削除は以下になります。

  1. 作成したCloudFrontのディストリビューションを削除する

    1. 無効にする

      1. 最終変更日がデプロイから日付に変わるまで待つ

    2. 削除する

  2. 作成したCloudFrontのオリジンアクセスを削除する

  3. 作成したCloudFrontの関数を削除する

  4. S3バケットを削除する

    1. 空にする

    2. 削除する

まとめ

関数を作成して設定するだけで実現できるのは、意外と楽だなと感じました。Apache、Nginxでのリダイレクト処理などは、対象が増えると見通しが悪くなることと、正規表現などで実現しないといけないこともあり、複雑になってくると、理解が難しくなってきますが、コードであれば自動テストも書けると思うので、テストのしやすさもあるかもしれません。

IaC版も作ってみました。


この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?