CloudFront Functionsのテストツール「cfft」を導入した
はじめに
こんにちは、READYFORでエンジニアをしているshmokmtです。
READYFORでは歴史的な背景[1]からLPを様々な構成でホスティングしています。
- Netlify
- CloudFront + S3
- CloudFront + ALB + Ruby on Rails
- STUDIO
しかし、近年では非エンジニアが主体となってLPを制作する際のファーストチョイスとして、STUDIO[2]を利用する機会も増えてきました。その結果、REDYFORでは下記の構成でホスティングしているLPをSTUDIOに移行する機会が増えてきました。このLPを移行する作業では、元のURLのリンクは切らしたくないため、リダイレクトは必須の要件でした。
- CloudFront + S3
- CloudFront + ALB + Ruby on Rails
リダイレクトの要件
リダイレクトの要件は以下のとおりです。
- 特定のprefixを持つパスをリダイレクト対象とする。(例:
/corp
、/info
)- ただし、リダイレクト対象のprefixの中でも特定の文字列を含むパスだけは業務の関係上、リダイレクトしてはならない。(例:
/corp/a
、/corp/b
はリダイレクトするが、/corp/c
はリダイレクトしてはならない。)
- ただし、リダイレクト対象のprefixの中でも特定の文字列を含むパスだけは業務の関係上、リダイレクトしてはならない。(例:
- リダイレクトする際にあらかじめコードに保持したマップを元にパスのマッピング処理をする必要があるときもある。(例:
/corp/dog
を/wanko
にリダイレクトする。dogとwankoはあらかじめリダイレクト用のソースコード内でマップで関連付けされている。)
上記の要件とREADYFORの現状のインフラ構成を踏まえた上でCloudFrontのレイヤーで統一的にリダイレクトすることにしました。
CloudFront Functionsでのリダイレクト
CloudFrontのレイヤーでリダイレクトをする場合は以下のサービスが選択肢として候補に挙がります。
・CloudFront Functions
・Lambda@Edge
今回のユースケースではURLを元にした条件分岐が複雑ではあるものの、aws-sdkを必要とする処理は一切ありませんし、ライブラリも必要としません。
そこで今回はランタイムが安定しているCloudFront Functionsでリダイレクトのコードを運用することとしました。
CloudFront Functionsを運用することで見えてきた課題
CloudFront Functionsの運用が始まると次第に条件分岐は複雑化していき、下記のようなコードになりました。
↓あくまでもイメージです。
function handler(event) {
try {
const request = event.request;
const uri = request.uri;
if (uri.startsWith("/A")) {
return processA(request);
} else if (uri.startsWith("/B")) {
return processB(request);
} else if (uri.startsWith("/C")) {
return processC(C);
} else if (uri.startsWith("/D")) {
return processD(request);
} else if (uri.startsWith("/E")) {
return processE(request);
} else if (
uri.startsWith("/OTHERS")
) {
return processOthers(request);
}
}
そのため、コード内の条件分岐を修正したときに手元ですぐに動作確認をしたいというモチベーションが生まれてきました。手元ですぐに動作確認ができれば、PRのレビュープロセスも楽になると考えました。
動作確認をするための選択肢として、awscliのaws cloudfront test-function
が挙げられます。しかし、複数のテストケースを実行したい場合にawscliで実行するのは煩わしさがありました。
そこでほかに良いツールがないか探していたところ、fujiwaraさん作のcfftを発見しました。
検証してみたところ、ユースケースとマッチしていたため採用しました。
下記のようにcfft test
で全てのテストケースに対してテストが実行されるため、awscliで感じていた課題感が解決されました。
↓テストの実行例
❯ cfft test
2024-09-18T13:19:46+09:00 [info] function apply-redirect found
2024-09-18T13:19:47+09:00 [info] function is not changed
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to A] [etag:ETVPDKIKX0DER] testing function
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to A] ComputeUtilization: 7 optimal
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to A] TestFunction API succeeded
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to A] checking function output with expected value
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to A] expect and actual are equal
2024-09-18T13:19:47+09:00 [info] [testcase:redirect to B] [etag:ETVPDKIKX0DER] testing function
2024-09-18T13:19:48+09:00 [info] [testcase:redirect to B] ComputeUtilization: 7 optimal
2024-09-18T13:19:48+09:00 [info] [testcase:redirect to B] TestFunction API succeeded
2024-09-18T13:19:48+09:00 [info] [testcase:redirect to B] checking function output with expected value
2024-09-18T13:19:48+09:00 [info] [testcase:redirect to B] expect and actual are equal
2024-09-18T13:19:48+09:00 [info] 2 testcases passed
おわりに
READYFORで抱えていたCloudFront Functionsの課題は fujiwara/cfft
により解決されました。
複雑な条件分岐を含んだCloudFront Functionsを運用している方は是非検討してみてください。
参考
- Fujiwara Tech Conference 2025 - connpass
- cfft - CloudFront Functionsをテスト、デプロイ - fujiwara-ware 2024 day 7 Zenn
- 9: fujiwara ware conferenceの機運 (fujiwara)
-
雑に言ってしまえば、すぐに返済できない技術的な負債のこと。返済しても事業インパクトがあまり大きくないため、長年優先度が低いままになってしまっている。 ↩︎
「みんなの想いを集め、社会を良くするお金の流れをつくる」READYFORのエンジニアブログです。技術情報を中心に様々なテーマで発信していきます。 ( Zenn: zenn.dev/p/readyfor_blog / Hatena: tech.readyfor.jp/ )
Discussion