yasudacloudの日記

札幌に住むソフトウェアエンジニア

CloudFrontとLambda関数URLを紐づける@Terraform

CloudFrontのドキュメントを読んでいたら先日公開されたLambda関数URLに関する記述があったので軽く触ってみました。CloudFront FunctionとLambda Edgeに加えてプレーンなLambdaが追加されたという話です。

docs.aws.amazon.com

Lambda関数URLは1つの関数にhttpsのURLを持たせることができるためAPI Gatewayがなくても簡単なフォーム機能をさくっと作れるよ!というものでした。コンソールからの作り方はググると記事が沢山出てくるのでそちらをご覧ください。

CloudFrontとLambda関数URLの紐付け

CloudFrontのオリジンにLambdaのURLのドメインを設定するだけでCloudFront→Lambdaの実行が可能になります。ただし上の公式ドキュメントにパブリックアクセスできることあるので留意しましょう。

Terraform

このように書いてみました。

gist.github.com

実行すると一連のリソースが生成されてこのようにオリジンにLambdaのドメインが紐づきます。

1ファイルでRoute53やIAMロールの記述もあるせいか長く感じますが、要所はoriginのdomain_nameとorigin_idにLambda関数URLの情報を記述する点です。

データの中にドメインが見当たらなかったのでURLから先頭httpsと末尾/をreplaceで取り除いています。Terraformの正規表現よく分からず重ねています😅が、module化して独自関数定義っぽい手法もありそうです。

上記のコードではCloudFront→Lambdaへカスタムヘッダーを付与していて、Lambda側でリクエストヘッダーの簡易的なチェックを入れることが望ましいです。なぜかというとLambda関数URL自体はパブリックなのでCloudFrontを経由しないと以下のような意図しないケースが起こり得ます。

  1. CloudFrontに設定しているWAFをすり抜ける
  2. CloudFront側で非公開(無効)にしているはずが実行されてしまう

ちなみにCloudFront→ALB(後ろにWebサイト)のような構成にしている場合にALBのデフォルトドメインが検索エンジンに拾われて問題になったのを過去に2度ほど見たことがあります。意外と見落としがちなポイントなので注意が必要です。

使い所、メリデメを考える

API Gatewayは機能が多い分、IaC観点で見てもコード量が多くなるので軽めのワークフローはCloudFront-Lambdaの方が使いやすそうです。

また、前段にCloudFrontがあることでLambdaのURL(ドメイン)が変えやすくなったり、呼び出し元のAPIエンドポイントの管理がシンプルになります。後者は例えばWebフロントエンドFWのSPAからLambda関数URLを直接使うとAPI毎にURLをフルパスで管理しなければなりません。加えて公式の紹介にあったようなLambda関数URLをWebフックとして使うケースでもCloudFrontを挟んでドメイン/パスを指定していればコントロールしやすくなります。

デメリットないのか?と色々考えましたがパッと思いつきませんでした。強いて挙げるなら

  • 直接アクセスを防ぐための仕組みが必要
  • 複数のLambdaを簡潔に管理したいのでIaCが前提となる
  • Serverless FrameworkではCloudFront-Lambdaの実装が出来なさそう(ドキュメント見当たらなかった)

↓でちょこっと触れていますが、Lambda Function URLでカスタムドメイン使いたいならCloudFrontだと書かれていますね。

www.serverless.com

今後普及(認知)されていくと採用しやすくなるのでもっと広まってほしいです(´-`).。oO