CloudFront Functionsの始め方

# はじめに
CloudFront Functions はAWSエッジ環境で軽量なJavaScriptを実行できるサービスです。
同じ様なサービスに Lamda@Edge がありますが、CloudFront Functions の方が処理が高速で、利用費が安くなっています。（いくつか制約はありますが。）
この記事では CloudFront Functions の特徴から使い方について、ご紹介していきます。

#### こんな方におすすめ
- CloudFront Functions を初めて使う方
- すでに Lamda@Edge を利用している方

# CloudFront Functions の特徴
Lambda@Edge に比べ以下の特徴があります。いくつか制約がありますが、「呼び出し 1,000,000 件あたり 0.10 USD」と Lambda@Edge の利用料金の６分の１になっています。ですので、制約内で対応可能であれば積極的に CloudFront Functions を活用し、それ以外をLambda@Edge で対応すると良いかと思います。
（* Lambda@Edge の利用料金は　「リクエスト 1,000,000 件あたり 0.60USD」）

- JavaScript (ECMAScript 5.1)
- 実行場所は 218以上の CloudFront エッジロケーション
- Viewer Request,Response のみ （Lambda@EdgではOrigin Request,Responseの利用が可能）
- 実行時間は 1ミリ秒未満
- 最大メモリは 2MB以内
- 合計パッケージサイズは 10MB以内
- ネットワークアクセス なし
- ファイルシステムアクセス　なし
- リクエスト本文へのアクセス なし

### CloudFront Functions の処理イメージ
![スクリーンショット 2021-08-09 15.53.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/9b356251-ee68-fc98-1391-a196ddc96e17.png)
（引用：https://aws.amazon.com/jp/blogs/news/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/）

CloudFront Functions は、CloudFront によって生成されたイベントに応答してコードを実行します。
CloudFront Functions は、CloudFront がビューアからのリクエスト (ビューアリクエスト) を受信した後、および CloudFront がビューアへのレスポンス (ビューアレスポンス) を転送する前にトリガーできます。
上記の図にもある通り、Lambda@Edge と一緒に利用することも可能です。

### Lambda@Edgeとの比較
![スクリーンショット 2021-08-09 15.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/c9a33d2f-d5bb-5bcd-2393-b185bff6a246.png)
（引用：https://aws.amazon.com/jp/blogs/news/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/）

## できること
- キャッシュキー操作と正規化
- URLの書き換えとリダイレクト
- HTTPヘッダーの操作
- アクセス承認
  
公式ドキュメントには上記の処理を実行するのに最適であると紹介されています。
ちなみに制約を守らない JavaScript を実行するとエラーが発生するのでご注意ください。（コンソール上のテスト実行で確認いたしました）
##### 制約違反で試してみたこと  
- ECMAScript6 の記述（let,const etc）
- setTimeoutで1ミリ秒以上処理を遅延させる
- ネットワークアクセスを実行する

![スクリーンショット 2021-08-09 18.09.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/587ec1eb-5be6-e806-54a7-7d5c62f125c9.png)（このようなエラーが出てきます。コードをデプロイする前にはテスト実行しておきましょう）

# 始め方
### 1.AWSコンソール > CloudFront > Functions　を選択
![スクリーンショット 2021-08-09 17.58.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/466cea2e-0970-e8d2-b28f-d041dc089ddf.png)

### 2.「Create Function」で関数名を入力
![スクリーンショット 2021-08-09 17.58.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/82bef333-40bf-ae6d-c013-bf86f5ae019e.png)

![スクリーンショット 2021-08-09 17.59.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/15a7e95b-0652-46a2-f336-39657246fded.png)

### 3.JavaScriptで処理を実装
今回は参考にメンテナンスページへのリダイレクトを想定した実装をしています。
ECMAScript 5.1 互換のため新しい記述は使えないので注意してください。
![スクリーンショット 2021-08-09 18.19.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/b4421c21-33f1-d3f6-4f45-81dde4c942c1.png)

``` sample.js
function handler(event) {
    var request = event.request;
    var maintenanceUrl = 'https://sample.com/maintenance.html'

    var response = {
        statusCode: 302,
        statusDescription: 'Maintenance',
        headers: {
            "localtion": { "value": maintenanceUrl }
        }
    };

    return response;
}
```

### 4.テスト実行
「Test function」を実行して、テストが通ることを確認しましょう。
制約に違反した実装になっている場合は、エラーでテストが通らないようになっているので不適切な処理をデプロイすることを防ぐことができます。

![スクリーンショット 2021-08-09 18.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/c58b0d6e-7420-43d8-b19b-86719522d3b4.png)

### 5.「Publish」を選択し、コードをデプロイ
![スクリーンショット 2021-08-09 18.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/8a06b3ea-e3c6-09fb-1d04-182c32a3084e.png)

### 6.「Add association」でCloudFront ディストリビューション、Event type および Behavior を選択
![スクリーンショット 2021-08-09 18.24.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/cb61d357-8ae9-4098-55b0-566ab395f5d1.png)

割り当て先の CloudFront ディストリビューション、Event type および Behavior を選択して「Add association」を選択
![スクリーンショット 2021-08-09 18.24.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94596/3da942c1-4d53-5342-4110-d25e655f79f1.png)

以上の操作でCloudFront Functionsを適用することができます。

いかがでしたでしょうか？少しでもお役に立てましたら幸いです🙇‍♂️