4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CloudFront Functions でサブドメインをS3のフォルダ名にルーティングする

Posted at

やりたいこと

下記の図のように、CloudFrontにワイルドカードのドメインを設定して

  1. サブドメイン名に応じてS3のフォルダ名にルーティングする
  2. サブディレクトリのルートオブジェクトに index.html を指定する

というのをやってみたいと思います。

fig1.png

CloudFront Functionsについて

以前は、CloudFrontでリクエストによるルーティング処理を行おうとすると、Lambda@Edgeを使う必要がありましたが、 CloudFront FunctionsはLambda@Edgeよりもシンプルな処理に向いているのでこういったリクエストやレスポンスの操作を行うのに向いています。

CloudFront FunctionsとLambda@Edgeの違いや使い分けについてはクラスメソッドさんのブログがよくまとまっているのでこちらを参考にしてください。

やってみる

まずはCloudFront Functionsでファンクションを作成します。

AWSコンソールのCloudFrontのページから、Functionsを選択して新規にFuctionを作成します。
Function codeDevelopment に既にサンプルのコードが入力されていますが、それを下記のようなコードに書き換えます。

fig4.png

コード例
function handler(event) {
    var request = event.request;
    var uri = request.uri;
    var host = request.headers.host.value;

    var prefix = host.split('.', 1)[0]
    if (uri.startsWith('/')) {
      request.uri = '/' + prefix + uri;
    } else {
      request.uri = '/' + prefix + '/' + uri;
    }

    if (uri.endsWith('/')) {
        request.uri += 'index.html';
    } else if (!uri.includes('.')) {
        request.uri += '/index.html';
    }

    return request;
}

コードを保存した後、Test タブに切り替えるとコードのテストが行えます。

fig5.png

問題がなければ Publish タブから Publish function をクリックします。

Terraform を使って管理する場合は以下のようなコードになります。デフォルトの挙動はpublishまで行うので、既に本番運用しているコードを更新する場合など注意が必要です。

main.tf
resource "aws_cloudfront_function" "this" {
  name    = "url-routing"
  runtime = "cloudfront-js-1.0"
  comment = "Managed by Terraform"
  publish = false
  code    = file("${path.module}/functions/index.js")

  lifecycle {
    create_before_destroy = true
  }
}

次に、CloudFunctionを作成します。
作成したファンクションを Viewer request に紐付けます

fig7.png

CNAME に *.exmaple.com のようにワイルドカードのドメインを指定します。

fig8.png

また、HTTPSによるリクエストを受け付ける場合は ワイルドカードに対応した証明書を設定します。

まとめ

同様のことは Lambda@Edge を使ってもできるのですが、 CloudFront Functions を使った方が 1/6 ほど安価で、比較的簡単に導入することができます。
ただ、やはりランタイムがJavaScriptのみ、ライブラリ等も導入できないので複雑な処理は難しいかなという印象です。その場合は素直に Lamba@Edge を使った方がいいと思います。

他にも、CloudFront Functions のサンプルコードは AWS が以下の GitHub レポジトリに公開しているのでこれを参考にするといいと思います。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?