CloudFront Functions は、Amazon CloudFront のサービスであり、Lambda@Edge より手前で動作し、シンプルな処理を高速かつ安価に実行できるように設計された機能です。従来の Lambda@Edge は、CloudFront のエッジロケーションで動作するカスタムの AWS Lambda 関数を作成して、リクエストまたはレスポンスを処理することができます。一方、CloudFront Functions はよりシンプルで軽量であり、Lambda@Edge よりも低いレイテンシと高いパフォーマンスを持っています。
CloudFront Functions を使用すると、よりユーザーに近いエッジロケーションでリクエストを処理できるため、レスポンス時間が短縮され、ユーザーエクスペリエンスが向上します。また、コスト面でも Lambda@Edge よりも経済的であるため、シンプルな処理には CloudFront Functions が適しています。
さらに、CloudFront Functions と Lambda@Edge を組み合わせて使用することも可能です。例えば、シンプルな処理やヘッダーの操作、URL の書き換えなどのタスクを CloudFront Functions で処理し、より高度な処理を必要とする場合には Lambda@Edge で追加の処理を行うことができます。 これにより、より効率的で高速なコンテンツデリバリーサービスを提供することができるため、AWS のクラウドインフラストラクチャを活用したウェブアプリケーションやコンテンツの配信を行う際に便利です。
特徴 | CloudFrontFunction | Lambda@Edge |
---|---|---|
ランタイムサポート | JavaScript (ECMAScript 5.1 準拠) | Node.js、Python |
実行場所 | 218 以上の CloudFront エッジロケーション | 13 の CloudFront リージョンのエッジキャッシュ |
サポートされる CloudFront トリガー | ビューアリクエスト、ビューアレスポンス、オリジンリクエスト、オリジンレスポンス | ビューアリクエスト、ビューアレスポンス、オリジンリクエスト、オリジンレスポンス |
最大実行時間 | 1 ミリ秒未満 | 5 秒 (ビューアトリガー)、30 秒 (オリジントリガー) |
最大メモリ | 2 MB | 128 MB (ビューアトリガー)、10 GB (オリジントリガー) |
合計パッケージサイズ | 10 KB | 1 MB (ビューアトリガー)、50 MB (オリジントリガー) |
ネットワークアクセス | なし | あり |
ファイルシステムアクセス | なし | あり |
リクエスト本文へのアクセス | なし | あり |
料金 | 無料利用枠あり。リクエストごとに課金。 | 無料利用枠なし。リクエストと関数の実行時間ごとに課金。 |
どちらにするかは処理時間か鍵になりそうです。
CloudFrontFunctions は同時実行数のクォータとかが公開されておらず、おそらく無いのではないかと思ってます。
実際に使ってみたので CloudFrontFunctions サンプルコードを載っけてみます。
LambdaEdge はロール作ったりデプロイするのが面倒なのですが、CloudFrontFunctions はコードだけ書けばいいので楽ですね。
function handler(event) {
var request = event.request;
var viewer = event.viewer;
var allowIP = ["1.1.1.1", "0.0.0.0"];
if (allowIP.indexOf(viewer.ip) !== -1) {
return request;
}
return {
statusCode: 403,
statusDescription: "Forbidden",
body: "Access to this resource is forbidden.",
};
}
var querystring = require("querystring");
// クエリストリングを文字列化するヘルパー関数
function stringifyQueryString(eventQueryString) {
var query = {};
Object.entries(eventQueryString).forEach(function (q) {
query[q[0]] = q[1].multiValue
? q[1].multiValue.map(function (m) {
return m.value;
})
: q[1].value;
});
return querystring.stringify(query);
}
function handler(event) {
var request = event.request;
var newurl = "https://www.domain.jp" + request.uri;
// クエリストリングが存在する場合は、文字列化して newurl に追加
if (Object.keys(request.querystring).length > 0) newurl += "?" + stringifyQueryString(request.querystring);
return {
statusCode: 301,
statusDescription: "Found",
headers: { location: { value: newurl } },
};
}
function handler(event) {
var request = event.request;
var headers = request.headers;
var viewer = event.viewer;
var idpw = "dGVzdF8xOnRlc3RfMg=="; // common IDPW
var allowPathFlag = false;
var optionPathSettingFlag = false;
var pathRules = {
"^/test/*": { idpw: "dGVzdF8xOnRlc3RfMw==" },
"^/aiu/*": { idpw: "dGVzdF8xOnRlc3RfMw==" },
"^/hoge/aiu/*": { idpw: null },
};
for (var path in pathRules) {
if (pathRules.hasOwnProperty(path) && new RegExp(path).test(request.uri)) {
allowPathFlag = true;
if (pathRules[path].idpw !== null) {
optionPathSettingFlag = true;
idpw = pathRules[path].idpw;
break;
}
}
}
if (allowPathFlag && !optionPathSettingFlag) {
return { request: request };
}
// IDPW
var authString = "Basic " + idpw;
if (typeof headers.authorization === "undefined" || headers.authorization.value !== authString) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: { "www-authenticate": { value: "Basic" } },
request: request,
};
}
return { request: request };
}
超カンタン。こんな感じでデプロイできます。
resource "aws_cloudfront_function" "hoge" {
name = "hoge-${terraform.workspace}"
runtime = "cloudfront-js-1.0"
publish = true
code = file("hogehoge.js")
}