初心者が初心者のためにCloudFrontをまとめてみた

## はじめに

### 概要
 
CloudFrontとはAWSが提供するCDN（Content Delivery Network）サービスです。
S3やALBの配信の際によく用いられます。

### この記事で得られること

- CDNとは
- CloudFrontとは
- CloudFrontの設定項目
- キャッシュを考える上での注意点

## CDNとは

まず、CloudFrontの前にCDNとはなんでしょうか。

CDNとはユーザーからのリクエストのあったコンテンツをキャッシュ(一時的に保存)することで、
同じリクエストがあった際にコンテンツを素早くユーザーに届けることができる仕組みです。

さらに、世界中に分散されたエッジロケーションを使って、ユーザーに近いサーバーからコンテンツを配信することで高速なコンテンツの配信を実現しています。

これらの仕組みのおかげでオリジンサーバーの負荷軽減にも役立っています。

### 用語

用語について少し解説します。

- キャッシュ
    - ファイルを一時的に保存する仕組みのことです。
- キャッシュサーバー
    - キャッシュを行うサーバーのことです。CDNとよく混同されますが、CDNは世界中に配置されたキャッシュサーバーのネットワークのことを言います。
- エッジロケーション
    - エッジは「端」という意味です。
    その名前の通り、世界中に存在するCDNの端に存在するキャッシュサーバーが配置された場所のことを言います。
- オリジンサーバー(オリジン)
    - ユーザーが求めるファイルが置かれたサーバーです。
    キャッシュサーバーはコンテンツをキャッシュしていない場合は、このオリジンサーバーにファイルをもらいに行きます。

では、CDNの仕組みを図で表しました。
上側がキャッシュを行う前で、
下側が世界中のエッジロケーションに配置されたキャッシュサーバーからコンテンツを配信する流れです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/1492a54a-003a-daed-8136-da46ffc23c7f.png)


CloudFrontはこれらの仕組みをAWSがマネージドで行なってくれるサービスです。

### 何ができるの？

以下にCloudFrontができることを記載しました。

これはあくまでも一部の機能ですが、こんなにもたくさんの機能を持っています。
| 機能 | 説明 |
| --- | --- |
| キャッシュ | HTML, CSS, Javascript, 動画, API呼び出しなどのキャッシュ |
| パスベースルーティング | パスによって通信を行うオリジンを切り替えることができる |
| 暗号化通信 | CloudFrontにSSL証明書を持たせてHTTPS通信が可能 |
| ロギング機能 | アクセスログや、WAFを使った監視が可能 |
| 圧縮機能 | キャッシュするコンテンツを圧縮することで転送時間の短縮が可能 |
| カスタムドメイン名 | 独自のドメイン名で配信することができる |
| アクセス制限 | 国ごとにアクセスの許可、拒否を設定可能 |

## CloudFrontで重要な設定項目

CloudFrontでは必須の項目があります。

- オリジン（何に対して）
- ビヘイビア（何を行うか）

以下はCloudFrontのコンソール画面です。

![ .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/b07c6fdc-af73-64bf-06a3-7fc92e3260ed.png)


それでは一つづつ見ていきましょう

## オリジン

オリジンとはHTML, CSS, Javascriptなどを持っているサーバーや、サーバーの負荷分散を行うロードバランサーのことを指します。

ユーザーから見るとCloudFrontの後ろに隠れているものです。
ちなみにCloudFrontではリクエストの送信元をビューワーと言います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/1fd8f5f5-d42b-fab5-65fc-04a598f60ef7.png)


### オリジンの種類

オリジンとして使用されるのは
S3, Application Load Balancer(ALB), Network Load Balancer(NLB), EC2, オンプレサーバーなどがあります。

## ビヘイビア

ビヘイビア(behavior)とは日本語で「振る舞い」という意味です。
これはビューワーからのアクセスに対してどのように振る舞うか(動作するか)を設定します。

主に以下のような設定を行います

| 設定項目 | 説明 |
| --- | --- |
| パスパターン | リクエストのURLパスを元に、特定のビヘイビアを適用するためのパターン |
| オリジン | リクエストをルーティングするオリジンサーバーを指定 |
| リクエストメソッド | 許可するHTTPリクエストメソッドを指定（GET、HEAD、POST、PUT、DELETE、OPTIONSなど） |
| キャッシュポリシー | CloudFrontのキャッシュ動作を制御するための設定 |
| オリジンリクエストポリシー | オリジンサーバーへのリクエストヘッダーを制御するため設定 |
| レスポンスヘッダーポリシー | HTTPレスポンスヘッダーを制御するための設定 |
| トラフィックの署名付きURL/署名付きCookie | 署名付きURLまたは署名付きCookieを使用してコンテンツへのアクセスを制御する設定 |

### パスパターン

CloudFrontではパスパターンを設定することで、リクエストのURLによってオリジンを切り替えることができます。

例えば、以下の図のように各ファイルが格納されたS3へルーティングしたい場合や、APIリクエストの場合はALBにルーティンングするなど、パスに基づいたルーティングが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/1ed1aa0d-107f-1bb1-cb4f-775bf67776f3.png)


### キャッシュポリシー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/6590a3dd-987f-2298-27c9-62a9e8fd9179.png)


| TTL | CloudFrontでキャッシュしておく時間 |
| --- | --- |
| ヘッダー | ヘッダーの値をキャッシュ時に考慮するか |
| クエリ文字列 | URLの”?”以降の文字列をキャッシュ時に考慮するか |
| cookie | cookieの値をキャッシュ時に考慮するか |

キャッシュポリシーはキャッシュ時の設定です。

最もイメージしやすいのがTTLです。
これはCloudFrontがコンテンツをキャッシュしておく時間です。

これを長く設定することで、キャッシュヒット率が上昇します。
しかしその反面、サーバー側でコンテンツの更新が行われてもCloudFrontでキャッシュしているコンテンツは更新されないので注意が必要です。

:::note info
キャッシュヒット率とは
CloudFrontにはキャッシュヒット率という考え方があります。
これはいかにCloudFrontを使えているか？という指標になります。
CloudFrontがキャッシュしているファイルをユーザーに返すとキャッシュヒット率が上がります。
逆にユーザーからリクエストされたファイルを持っていない場合はサーバー(オリジン)にファイルをリクエストします。この場合はキャッシュヒット率が下がります。

このキャッシュヒット率を上げるには、ビヘイビアのTTLでキャッシュする時間を伸ばす、キャッシュ時の検討項目を減らすということがあげられます。
:::

キャッシュポリシーのヘッダー、クエリ文字列、cookieの設定を行うと、より細かいキャッシュ設定が可能となります。それぞれ、特.定の値を設定することも可能です。

例えば以下の様な情報がリクエストに含まれていた場合のみキャッシュを行うといった設定が可能です。

ex.) 
User-Agent:Chrome(ヘッダー)
URL:https://www.example.com?category=electronics&page=2
session_id=abc123(cookie)

しかし、このこれらの設定を厳しくすればするほどキャッシュヒット率が下がるので、何でもかんでもキャッシュすれば良いという訳ではありません。

### オリジンリクエストポリシー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/669a1634-4365-3d7d-175e-a5b7c10dfaa8.png)

キャッシュポリシーと同様にリクエストに含まれる値を設定することができます。

こちらはビューワーから受け取った値から何をオリジンに渡すのかを決めます。
不要な値を渡さないことで、オリジンの処理速度の向上することができます。

また、特定の値をオリジンに渡すことでその値に応じた処理を行うことも可能です。

### レスポンスヘッダーポリシー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/a4e3bf30-861e-82df-3259-15f9979f42e8.png)


レスポンスヘッダーポリシーでは、CloudFrontがクライアントに返すHTTPレスポンスヘッダーを制御します。

ヘッダーを制御することで、ウェブページで実行・読み込みが許可されるコンテンツの制限を行い、クロスサイトスクリプティング (XSS) などの攻撃を防ぐなどセキュリティの向上が図れます。

それ以外にも、クロスオリジンリソース共有 (CORS) を制御できます。これにより、異なるオリジンからのリソースアクセスを許可したり、制限したりすることができます。

### 署名付きURL,Cookie

これはCloudFrontでプライベートコンテンツを安全に配信するために使用される機能です。

まずCloudFrontのプライベートキーを使用して署名付きURL(Cookie)を作成します。

それを特定のユーザーに渡し、ユーザーからのリクエストに含まれた署名付きURLをプライベートキーを使ってアクセス権を確認します。

さらに有効期限を持たせることも可能です。

ユースケースとしては、会員制サイトや限定公開サイトなどがあります。

## キャッシュを考える上での注意点

これまでにコンテンツをキャッシュすることの有用性を語ってきましたが、キャッシュを設計する上で考えなければならないことがあります。

キャッシュに向いたコンsテンツと向かないコンテンツがあります。

- キャッシュに向いたコンテンツ
    - 更新の少ない静的コンテンツ
    - ZIP, 動画, 音楽などのダウンロードファイル
    - HTML, CSS, Javascriptなどの静的ファイル
- キャッシュに向かないコンテンツ
    - 頻繁に更新されるコンテンツ
    - ショッピングカートなどユーザー固有の動的コンテンツ
    - 個人情報や機密情報
    - フォーム送信など、サーバーへ処理をリクエストするコンテンツ

これらを踏まえた上で、キャッシュの設計を行う必要があります。

## まとめ

CloudFrontはCDNの役割をマネージドで行なってくれる素晴らしいサービスです。
設定項目が多岐に渡るので、キャッシュの必要性を考えた上で設計を行う必要があります。

### 所感

以前にハッカソンでCloudFrontを使ってS3のファイルを配信するという構築を行いましたが、その際はあまり深く考えずパスベースルーティングとHTTPS通信のみ行っていました。

深く調べてみると設定項目が山のように出てきたので、あの時こうしておけばよかったのか〜という発見がたくさんありました。
長文になってしまいましたが、最後まで読んでいただきありがとうございました。