CloudFront Functions の試し

4 min read読了の目安(約4100字

触ってみた記事です。
軽量の Function at Edge のサービスである CloudFront Functions がリリースされたので、早速使ってみました。
Introducing CloudFront Functions – Run Your Code at the Edge with Low Latency at Any Scale | AWS News Blog

CloudFront Functions の特徴

詳細は上記のドキュメントにありますが、いくつか抜粋します。

  • Lambda@Edge より安い(無料枠もあり)がタイムアウトが短い
  • 言語はJavaScriptのみ
  • ランタイムはNode.jsではないので Node.js にデフォルトで用意されているモジュールはほとんど利用できない
  • 関数からファイルシステムへのアクセスや外部へのリクエストは行えない

Lambda@Edge とのアーキテクチャの違いやパフォーマンスについては以下のような説明があります。

To give you the performance and scale that modern applications require, CloudFront Functions uses a new process-based isolation model instead of virtual machine (VM)-based isolation as used by AWS Lambda and Lambda@Edge. To do that, we had to enforce some restrictions, such as avoiding network and file system access. Also, functions run for less than one millisecond. In this way, they can handle millions of requests per second while giving you great performance on every function execution.

制約や特性が違うので単純に Lambda@Edge から移行すれば安くなるという理解での移行はよろしくなさそうです。
タイムアウトが短く、外部(ヘッドレスCMSなど)への通信もできないため、リッチなフレームワークを利用した Web ページのレンダリングなどには利用できなさそうな印象です。上記のドキュメントに適した用途などの案内も説明があります。
CloudFront Functions はエッジロケーションで動作して、Lambda@Edge はリージョン別エッジキャッシュで動作するという説明もあって構成がわかりやすいです。

触ってみた記録

背景

もともと SSG で生成した Web ページを S3 にデプロイし、CloudFront を被せてホスティングしてました。
その構成で URL の末尾に /index.html をつける処理を Lambda@Edge で実装していたので、今回 CloudFront Functions で試してみます。

工程

CloudFront Functions は CloudFront のコンソールから操作します。(Lambda@Edge は Lambda のコンソール)

[Create function] をクリックして関数名を入力すると以下のようなエディタが開きます。

今回実装したかった内容のコードがちょうどドキュメントで例示されていたのでそのまま使います。
もともと Lambda@Edge で使っていた Node.js の path モジュールが使えなかったり、そもそも constletサポートされていないことなどにハマったため、以前の実装をそのまま流用するのは諦めました。

関数の入力となる event の構造はドキュメントにありますが、Lambda@Edge のものとは異なるので移行時には気をつける必要があります。

次に関数をテストします。テスト画面ではサンプルとなるリクエストのヘッダ、クエリ文字、クッキーなどを指定して関数に渡せます。関数の返り値や console.log での出力を確認できます。

2021/05/04 時点では console.log の第2引数以降の内容が出力されなかったので注意が必要です。

テストで期待する動作を確認できたら次は関数を Publish します。操作はボタンをクリックするだけ。

関数には DevelopmentLive というステージがあって、Development で実装とテストを行い、実際に関連付けられる段階になったら関数を Publish して Live ステージに反映させます。Live ステージの実装内容を CloudFront ディストリビューションに関連付けるとディストリビューションにデプロイされます。
関連付ける画面が以下です。今回はリクエストの改変なので Viewer Request タイプを選んでいます。

一度ディストリビューションと関連付けられた関数は Publish するだけで変更がデプロイされるようになります。
ディストリビューションに関数がデプロイされるとディストリビューションの状態が InProgress に遷移し、完了すると Deployed になります。ここまでで CloudFront Functions の利用は完了です。

API

ドキュメント
コードを取得するときは GetFunction、設定を取得するときは DescribeFunction を使います。
変更操作は Create/Update/Delete Function や Publish Function が用意されていました。
ディストリビューションへの関連付けは UpdateDistribution で行います。

ログやメトリクス

ドキュメント
Lambda@Edge はリージョン別エッジキャッシュで実行されていた都合か、実行された場所に近い AWS リージョンの CloudWatch にログや多くのメトリクスが出力されます。
一方で CloudFrot Functions は us-east-1 リージョンの CloudWatch にログやメトリクスが集約されるので確認しやすいです。
CloudWatch に出力されるのは Live ステージの関数の記録のみです。

まとめ

今回 Lambda@Edge で実装していた内容を CloudFront Functions で試してみました。
コードの面で Lambda@Edge と異なる制約がいくつかあり、そのまま移行するのは難しい印象を受けました。
デプロイの工程自体は Lambda の操作感に依存していないためシンプルで使いやすいです。