CloudFront Functions を使ってリダイレクトサーバを作る
CloudFront 上で JavaScript を実行できる CloudFront Functions なる機能が出てきました。
この機能を用いて、CloudFront 単体でリダイレクトサーバを立ててみます。
ヘッダ編集など軽めの処理が想定されていて、画像処理やレスポンス生成など重めの処理は、既存の Lambda@Edge を引き続き使うことが推奨されています。価格は Lambda@Edge の 1/6 でお安い。
利用用途と活用例
AWS 公式ブログ を見ると以下の例が挙げられています。
- キャッシュキーの操作や正規化
- URL 書き換えやリダイレクト
- HTTP ヘッダ操作
- アクセスコントロール
User-Agent を見てデバイス種別でキャッシュキーをまとめたり、条件を満たさない場合にリダイレクトかけたり、HSTS ヘッダを CloudFront 側で付与したり、JWT の検証をしたりなどなど。
最大実行時間が 1ms、メモリ上限が 2MB なので本当に軽い処理で使うのが無難そう。
(5/6追記) 実行時間が 1ms を超えた場合は 503
が返ります。
CloudFront Functions を試してみる
CloudFront コンソールを開くと左メニューに Functions
が増えています。
適当に名前をつけると、Lambda のようなエディタが出てきました。
とりあえず何も変えずに保存して Publish します。
Distribution、Event type、Behavior を選択して紐付ければ終わり。
今回登録したコード(初期値そのまま)はこんな感じ。200
のステータスコードで cloudfront-functions
というヘッダを返しています。
function handler(event) {
var response = {
statusCode: 200,
statusDescription: 'OK',
headers: {
'cloudfront-functions': { value: 'generated-by-CloudFront-Functions' }
}
};
return response;
}
実際に叩いてみたところ、上記通りのレスポンスが返ってきました。
真ん中あたりに cloudfront-functions
がいます。
% curl -i https://hoge.yuu26.com
HTTP/2 200
server: CloudFront
date: Tue, 04 May 2021 07:32:01 GMT
content-length: 0
cloudfront-functions: generated-by-CloudFront-Functions
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 5216b5aef38f6d8e7d7ca4ab8c47ead0.cloudfront.net (CloudFront)
CloudFront をリダイレクトサーバとして使う
先ほどのコードを以下のように書き換えて、再度 Publish してみます。
CloudFront Functions の書き方は 公式ドキュメント を参考に。
function handler(event) {
var response = {
statusCode: 301,
statusDescription: 'Moved Permanently',
headers: {
'location': { value: 'https://blog.yuu26.com/' }
}
};
return response;
}
応答が 301
に切り替わりました。割とすぐ反映されるようです。FunctionGeneratedResponse from cloudfront
というメッセージも見えますね。
% curl -i https://hoge.yuu26.com
HTTP/2 301
server: CloudFront
date: Tue, 04 May 2021 07:38:57 GMT
content-length: 0
location: https://blog.yuu26.com/
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 1906941751220f747982bec9cf3c2480.cloudfront.net (CloudFront)
次は User-Agent を見てリダイレクト先を振り分けてみましょう。
iPhone からのアクセスであれば Amazon に飛ばしてみます。(雑)
function handler(event) {
var redirectUrl = 'https://blog.yuu26.com/';
var userAgent = event.request.headers['user-agent'];
if (userAgent != null && userAgent.value.match(/iPhone/)) {
redirectUrl = 'https://www.amazon.co.jp/';
}
var response = {
statusCode: 302,
statusDescription: 'Found',
headers: {
'location': { value: redirectUrl }
}
};
return response;
}
テスト用ツールも用意されていて、任意のリクエスト内容をシミュレートできます。
今回は IP アドレス 1.2.3.4
から iPhone っぽいリクエストを投げて試しました。
生成されたレスポンスと Function の実行ログを確認できます。
問題無さそうなので Publish してから確認。
% curl -i https://hoge.yuu26.com
HTTP/2 302
server: CloudFront
date: Tue, 04 May 2021 08:01:16 GMT
content-length: 0
location: https://blog.yuu26.com/
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 0932afdcbb622a4425fd671f0d67863a.cloudfront.net (CloudFront)
% curl --user-agent 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X)' -i https://hoge.yuu26.com
HTTP/2 302
server: CloudFront
date: Tue, 04 May 2021 08:01:19 GMT
content-length: 0
location: https://www.amazon.co.jp/
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 c29e436c21072b427d47688aaf874625.cloudfront.net (CloudFront)
https://hoge.yuu26.com から試せます。iPhone で踏むと Amazon に飛ばされるはず。
まとめ
- CloudFront Functions というのが出た
- CDN のエッジで JavaScript を実行できる
- ヘッダ操作など軽めの処理におすすめ
個人的に便利そうだなーと思ったのは HSTS のヘッダ追加用途。
CloudFront 側で一括で付与できるのは楽になりそう。