【AWS】Amazon CloudFrontの理解〜高速配信機能編〜

# はじめに
どうも、道産子エンジニアのkitonです。
SAP取得に向けての知識整理していきます。
今回はCloudFront。その中でも高速配信機能にフォーカスを当ててみます。
（CloudFrontのデータ保護、レポーティング機能については別記事で投稿します。）
専門用語が多いですが、都度調べていくと理解が深まるかと思います。

# 難易度（個人的感想）
★★★☆☆
### Why??
- Webアプリケーションを本番稼働する上で重要な技術を理解している必要がある。
    - アクセスの分散や、レスポンス速度の向上、キャッシュ、Cookie、セキュリティ対策など
- CDN(Contents Delivery Network)を理解しておく必要がある。
    - コンテンツをユーザーに配信するための仕組み
- 個人開発でAWSアカウントがあれば容易に始められる。
    - 手を動かせば理解度が深まる。
- バックエンドアプリケーションがあればすぐにでも導入できる。

僕の場合はある程度CDNの知識があり、かつバックエンド業務中心なので難易度は高くはなかったですが、初学者の方は結構苦戦するサービスかな・・？と思います。

# CloudFront
## できること
- 高性能な分散配信
- 高いパフォーマンス
- キャパシティアクセスからの解放
- セキュリティ機能(WAF連携、DDoS対策)
- 設定が容易で即時利用可能
- 充実したレポーティング機能 (ログ、ダッシュボード、通知機能)
- 完全従量課金

要するに、Webコンテンツ配信を高速化するサービスで、CloudFront単体の利用ではなく、バックエンドのアプリケーションのサポートとして利用される。
利用者からすると早くWebサイトを見ることができる。

## CloudFront ディストリビューション
- ドメイン毎に割り当てられるCloudFrontの設定のこと。
- HTTP/1.0,HTTP/1.1,HTTP/2,WebSocket対応
※HTTP/2 使用時はクライアントがTLS1.2以降とSNI(Server Name Identification)
サポートが必要。
- IPv6対応
- デフォルトでは「xxxx.cloudfront.net」が ディストリビューション のドメイン名とし
て割り当てられる。
    - CNAMEエイリアスを利用して代替(独自)ドメイン名の指定ができる。
    - CNAMEエイリアスのワイルドカード指定もサポート(例:*.hogehoge.comなど)
    - Route53と組み合わせたZoneApex(例:hoge.comなど)が利用できる。

## エッジでのgzip圧縮機能
- **CloudFrontエッジでコンテンツをgzip圧縮する**ことでより高速にコンテンツを配信できる。
- リクエストヘッダーに``Accept-Encoding:gzip``が指定されており、オリジンがgzip
に対応していない場合は、CloudFrontエッジでgzip圧縮を行い配信する。
- Amazon S3はgzip圧縮をサポートしていないため、有効なオプション
※BlackBelt資料から参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1225450/6983781f-df83-2789-1d34-a69922b0475f.png)

## Webディストリビューション
- サポートプロトコル/HTTPメソッド
    - HTTP/HTTPS対応
        - GET,HEAD,OPTION(選択可能)(Cacheモード)
        - PUT,POST,DELETE,OPTION,PATCH(Proxyモード)
    - オリジンへのアクセス
        - Internet経由でアクセスできることが必要
        - Range GET対応
 
※BlackBelt資料から参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1225450/9c658775-aea9-4e65-d6d2-9c208e9b7274.png)

## キャッシュ動作
### キャッシュコントロール
キャッシュヒット率を向上させることがCDN導入におけるポイント。
**URLおよび有効化したフォーワードオプション機能のパラメータ値の完全一致でキャッシュが再利用される**

- キャッシュコントロールヘッダー
    - キャッシュ時間のコントロールが可能
    - オリジン側がHTTPキャッシュコントロールヘッダーを付与しない場合でも上書きが可能
    - キャッシュ動作(Behavior)毎にキャッシュ設定を行うことで、URLパス毎にキャッシュ期間を変えることが可能
        - デフォルトTTL：オリジンがキャッシュコントロールヘッダーを指定しない場合に利用(デフォルト24時間)
        - 最小TTL：CloudFront側でキャッシュすべき最小期間
        - 最大TTL：CloudFront側でキャッシュすべき最大期間
- キャッシュファイルの無効化も可能
    - コンテンツ毎の無効化パス指定
    - ワイルドカードを利用した無効化パス指定

### 動的コンテンツ機能
- オリジンサーバに対して Header, Cookie, Query Strings 情報をフォワードすることで、動的なページの配信にも対応可能
- Cookieをオリジンへ転送
    - オリジンに任意のCookie情報を転送することで動的なページ生成にも対応可能
    - CloudFrontは指定されたCookie名と値をセットでキャッシュする
    - 全ての Cookie をフォワードするとキャッシュ効率が大幅に低下するため、必要最小限のCookie を指定することを推奨されている
    - 対象の Cookie 名はワイルドカードの指定も可能
- クエリ文字列パラメータの値をオリジンへ転送する 
    - オリジンに任意のクエリ文字列を転送することで動的なページ生成にも対応可能
    - CloudFrontは指定されたクエリ文字列パラメータと値をセットでキャッシュ
    - 全てのクエリ文字列をフォワードするとキャッシュ効率が大幅に低下するため、必要最小限のクエリ文字列を指定することを推奨
- ヘッダーをオリジンへ転送
    - オリジンに任意のヘッダー情報を転送することで動的なページ生成にも対応
    - 全てのヘッダーをフォワードするとキャッシュ効率が大幅に低下するため必要最小限のヘッダーを指定することを推奨
    - カスタムヘッダーにも対応
    - CloudFront側でクライアントの情報を独自に判定し、オリジンにフォワードする。

※BlackBelt資料から参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1225450/b680bd37-d80c-f2f1-eaab-d3c5874ec0ec.png)

## タイムアウト
- オリジンの読み取りタイムアウト
    - CloudFrontがカスタムオリジンからの応答を待つ時間を指定できる
    - ビジー状態の負荷を軽減したり、ビューアにエラー応答をより迅速に表示したりする場合は、読み取りタイムアウトを小さくする
    - デフォルトのタイムアウトは30秒、4〜60秒の範囲で設定可能
- キープアライブタイムアウト
    - 接続を閉じる前にCloudFrontがカスタムオリジンサーバーとの持続的接続を維持する最大時間を指定
    - デフォルトのキープアライブアイドルタイムアウト値は5秒、1〜60秒の範囲で設定可能

## オリジンフェイルオーバー
CloudFrontオリジンフェイルオーバーによる高可用性が実現可能
- オリジングループを作成し、プライマリオリジン・セカンダリオリジンを指定
- エラー HTTP ステータス(500,502,503等)、オリジンがフェイルオーバー用に設定したHTTPステータスコードを返した場合や接続タイムアウトした場合にバックアップオリジンにルーティングできる
- Lambda@Edge 関数やカスタムエラーページでもオリジンフェイルオーバー可能

## 料金
### 無料枠
1TBのデータ転送(アウト)、10,000,000のHTTP/HTTPSリクエスト、および毎月2,000,000件のCloudFront Functionsの呼び出しが無料
-> 検証で使う分には無料枠でいけそう。
※一括請求 (コンソリデーティッドビリング)利用アカウントは、利用可能な無料利用枠は1組織につき1つのみ。

### 課金対象
- インターネットへのデータ転送(アウト)
Amazon CloudFrontのエッジロケーションから外部に送信されるデータ量に対して、GB単位で課金される。
- オリジンへのデータ転送 (アウト)
Amazon CloudFrontエッジロケーションからオリジン（AWSオリジンおよび他のオリジンサーバーを含む）へ転送されたデータ量に応じて、GB 単位で課金される。
- HTTP/HTTPS リクエスト
コンテンツに対するAmazon CloudFrontへのHTTP/HTTPSリクエスト数に対して課金されます。
- 無効リクエスト
無効リクエストに含めるパスごとに課金されます。無効リクエストにリストされるパスは、CloudFrontキャッシュから無効化するオブジェクトのURL（あるいは、パスにワイルドカード文字が含まれる場合は複数のURL）を表す。
- リアルタイムログリクエスト
リアルタイムログは、生成されたログ行の数に基づいて課金されます。
- 専用 IP 独自 SSL
独自SSL証明書機能の専用IPバージョンを使用する1つ以上のCloudFrontディストリビューションに関連付けられた各独自SSL証明書ごとに、毎月600USDを支払う。
※専用IPの独自SSL証明書サポートを利用するには、SSL証明書をアップロードし、AWSマネジメントコンソールを使用して証明書とCloudFrontディストリビューションを関連付ける。

# 参考サイト
https://pages.awscloud.com/rs/112-TZM-766/images/20190730_AWS-BlackBelt_Amazon_CloudFront.pdf

https://pages.awscloud.com/rs/112-TZM-766/images/20201028_BlackBelt_Amazon_CloudFront_deep_dive.pdf

https://aws.amazon.com/jp/cloudfront/faqs/