Amazon CloudFrontを試してみた

# 背景・目的
CloudFrontについて、今まで全く触ってこなかったので整理します。また、簡単に動作させてみます。

# まとめ
下記に特徴をまとめます。

| 特徴 | 説明 |
|:--|:--|
|CloudFrontとは| ・静的、動的なウェブコンテンツの配信を高速化するWebサービス<BR><BR>・エッジロケーションというデータセンターの世界的なNWを経由してコンテンツを配信する<BR><BR>・CloudFrontでサービス提供されているコンテンツをユーザがリクエストすると、リクエストはエッジロケーションにルーティングされ、レイテンシーが最小になる<BR><BR>・コンテンツが、エッジロケーション内に最も低いレイテンシーで既に存在している場合、CloudFrontはそのコンテンツを即時に配信する。存在しない場合は、定義されたオリジンから取り込む
|キャッシュ|・エッジロケーションに各ユーザのリクエストをAWSのバックボーンNW経由でルーティングすることで、コンテンツの配信を高速化する<BR><BR>・AWS ネットワークを使用することで、パフォーマンスが向上する<BR><BR>・ファイルのコピーが世界中の複数のエッジロケーションに保持されるので、信頼性と可用性が向上する|
|ユースケース|・静的ウェブサイトのコンテンツ配信の加速<BR>・オンデマンドビデオおよびライブストリーミングビデオの配信<BR>・システム処理全体で特定のフィールドを暗号化する<BR>・エッジのカスタマイズ<BR>・Lambda@Edge カスタマイズを使用したプライベートコンテンツの供給|
|コンテンツ配信の流れ|1. ユーザがオブジェクトに対してリクエストを送信する<BR><BR> 2. DNSは、リクエスト最も適切に処理できる CloudFront エッジロケーションにルーティングする<BR><BR> 3.CloudFrontではリクエストされたオブジェクトのキャッシュをチェックし、キャッシュにあればそのまま返す。キャッシュにないときは、オリジンから取得し返す。また、次回に備えてキャッシュする|
|POPとは|Point of Presenceの略。エッジロケーションのこと。ビュワーに最も近い場所。|



# 概要
## Amazon CloudFront とは何ですか?
[Amazon CloudFront とは何ですか?](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html)を基に整理します。

> Amazon CloudFront は、ユーザーへの静的および動的なウェブコンテンツ (.html、.css、.js、イメージファイルなど) の配信を高速化するウェブサービスです。CloudFront では、エッジロケーションというデータセンターの世界的ネットワークを経由してコンテンツを配信します。CloudFront でサービスを提供しているコンテンツをユーザーがリクエストすると、リクエストはエッジロケーションにルーティングされ、レイテンシー (遅延時間) が最小になります。これにより、コンテンツは可能な限り最高のパフォーマンスで配信されます。
> - コンテンツがエッジロケーション内に最も低いレイテンシーですでに存在している場合、CloudFront はそのコンテンツを即時に配信します。
> - コンテンツがこのエッジロケーションに存在しない場合、CloudFront は、コンテンツの最終バージョンのソースとして識別されている Amazon S3 バケット、MediaPackage チャネル、または HTTP サーバー (たとえば、ウェブサーバー) などの定義されたオリジンからコンテンツを取り込みます。

- 静的、動的なウェブコンテンツの配信を高速化するWebサービス
- エッジロケーションというデータセンターの世界的なNWを経由してコンテンツを配信する
- CloudFrontでサービス提供されているコンテンツをユーザがリクエストすると、リクエストはエッジロケーションにルーティングされ、レイテンシーが最小になる
- コンテンツが、エッジロケーション内に最も低いレイテンシーで既に存在している場合、CloudFrontはそのコンテンツを即時に配信する
- 存在しない場合は、定義されたオリジンから取り込む

> CloudFront は、コンテンツを最良の方法で供給できるエッジロケーションに各ユーザーリクエストを AWS バックボーンネットワーク経由でルーティングすることで、コンテンツの配信を高速化します。通常、これはビューワーに最も高速に配信できる CloudFront エッジサーバーです。AWS ネットワークを使用することでユーザーのリクエストが通過しなければならないネットワークの数が大幅に減少するので、パフォーマンスが向上します。ユーザーが経験するレイテンシー (ファイルの最初のバイトがロードされるまでの時間) が低くなり、データ転送速度が高くなります。
> お客様のファイル (オブジェクトとしても知られる) のコピーが世界中の複数のエッジロケーションに保持される (つまりキャッシュされる) ので、信頼性と可用性の向上も得られます。

- エッジロケーションに各ユーザのリクエストをAWSのバックボーンNW経由でルーティングすることで、コンテンツの配信を高速化する
- AWS ネットワークを使用することで、パフォーマンスが向上する
- ファイルのコピーが世界中の複数のエッジロケーションに保持されるので、信頼性と可用性が向上する

### コンテンツを配信するように CloudFront を設定する方法
> CloudFront ディストリビューションを作成して、コンテンツを配信する場所と、コンテンツ配信の追跡と管理の方法の詳細を CloudFront に指示します。こうすることで、誰かがそのコンテンツを表示または使用する際に、CloudFront はビューワーに近いコンピュータ (エッジサーバー) を使用してそのコンテンツをすばやく配信します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/4bc84fb8-b645-5701-7e74-8234cf989f5d.png)

出典：[コンテンツを配信するように CloudFront を設定する方法](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html#HowCloudFrontWorksOverview)

1. S3や独自のHTTPサーバなどのオリジンを指定する
    - CloudFrontがファイルを取得し、CloudFrontエッジロケーションから全世界に配信する
    - オリジンには、オブジェクトのオリジナルの最終バージョンが保存される
1. ファイルをオリジンにアップロードする
    - ファイルには、ウェブページ、イメージ、メディアなどが含まれる
    - HTTP経由であれば何でも良い
    - バケット内のオブジェクトを読み取り可能にして公開することで、オブジェクトのCloudFrontURLを知っているユーザなら誰でもそのオブジェクトにアクセスできる
    - **オブジェクトを非公開にして、オブジェクトにアクセスするユーザを制限することもできる**
1. CloudFrontディストリビューションを作成する
    - このディストリビューションにより、ユーザがウェブサイト、アプリを通じてファイルをリクエストしたときに、どのオリジンから取得するかCloudFrontに指示される
    - ログ記録等の設定も可能
1. CloudFrontは、新しいディストリビューションにドメインを割り当てる
    - CloudFrontコンソールで確認可能
    - プログラムによるリクエスト（APIリクエストなど）ではレスポンスとして返される
    - 代わりに使用する代替ドメイン名を追加できる
1. CloudFrontは、ディストリビューションの構成を関係するすべてのエッジロケーション、POPに送信する

## ユースケース
### 静的ウェブサイトのコンテンツ配信の加速
> CloudFront は、世界中のビューワーへの静的コンテンツ (たとえば、イメージ、スタイルシート、JavaScript など) の配信を高速化します。CloudFront を使用することで、AWS バックボーンネットワークと CloudFront エッジサーバーの利点を活用して、ウェブサイトを閲覧する訪問者に高速かつ安全で、信頼性に優れたエクスペリエンスを提供できます。

- 静的コンテンツの配信を高速化

> Amazon S3 バケットを使用すると、静的コンテンツを簡単に格納し、配信することができます。CloudFront と S3 を組み合わせて使用することには、簡単に S3 コンテンツへのアクセスを制限できるオリジンアクセスコントロールを使用するオプションを含め、多くの利点があります。

- S3バケットにより、簡単に格納し、配信が可能になる
- S3コンテンツへのアクセスを制限できるオリジンアクセスコントロールを使用するオプションを含めて多くの利点がある

### オンデマンドビデオおよびライブストリーミングビデオの配信
> CloudFront では、録画済みのファイルとライブイベントの両方のメディアを世界中のビューワーにストリーム配信するためのいくつかのオプションが提供されています。

> - オンデマンドビデオ (VOD) ストリーミングで CloudFront を使用して、MPEG DASH、Apple HLS、Microsoft Smooth Streaming、CMAF などの一般的な形式であらゆるデバイスにストリーミングできます。
> - ライブストリームをブロードキャストする場合は、フラグメントを正しい順序で配信するマニフェストファイルに対する複数のリクエストを結合して、オリジンサーバーの負荷を軽減できるように、メディアフラグメントをエッジにキャッシュすることができます。

- CloudFrontでは、録画済みのファイルとライブイベントの両方のメディアを世界中にビュワーにストリーム配信するオプショがある
- オンデマンドでは、下記の一般的な形式であらゆるデバイスにストリーミングできる
    - MPEG DASH
    - Apple HLS
    - Microsoft Smooth Streaming
    - CMAF 
- ライブストリームをブロードキャストする場合
    - フラグメントを正しい順序で配信するマニフェストファイルに対する複数のリクエストを結合
    - オリジンサーバーの負荷を軽減できるように、メディアフラグメントをエッジにキャッシュすることが可能

### システム処理全体で特定のフィールドを暗号化する
> CloudFront を使用して HTTPS を設定する場合、すでにオリジンサーバーへのセキュアなエンドツーエンド接続が存在します。フィールドレベルの暗号化を追加する場合、HTTPS セキュリティに加えて、システムの処理中に特定のデータにオリジンの特定のアプリケーションのみがアクセスできるように、そのデータを保護できます。

- CloudFrontで、HTTPSを設定する場合、既にオリジンサーバへのセキュアなE2E接続がある
- フォールドレベル暗号化を追加する場合、HTTPSセキュリティに加えて、特定のデータにオリジンの特定のアプリケーションのみがアクセスできるように、そのデータを保護できる

### エッジのカスタマイズ
> エッジでサーバーレスコードを実行することには、ビューワーのコンテンツとエクスペリエンスをカスタマイズして、待ち時間を短縮することができる様々な可能性があります。たとえば、メンテナンスのためにオリジンサーバーがダウンしているときにカスタムエラーメッセージを表示することができるため、ビューワーには一般的な HTTP エラーメッセージは表示されません。または、CloudFront がリクエストをオリジンに転送する前に、コンテンツにアクセスするユーザーを認証および管理する関数を使用できます。

- エッジでサーバレスコードを実行する
- ビューワーのコンテンツとエクスペリエンスをカスタマイズして、待ち時間を短縮できる可能性がある
- メンテナンスのため、オリジンサーバがダウン子ているときにカスタムエラーメッセージを表示することができる
- CloudFrontがリクエストをオリジンに、転送する前に、コンテンツにアクセスするユーザを認証及び管理する関数を使用できる

### Lambda@Edge カスタマイズを使用したプライベートコンテンツの供給
> Lambda@Edge を使用すると、署名付き URL や署名付き Cookie の使用に加えて、独自のカスタムオリジンからプライベートコンテンツを供給する CloudFront ディストリビューションを設定するのに役立ちます。
> CloudFront を使用してこのプライベートコンテンツを供給するには、次のことを実行します。

- 署名付きURL、署名付きCookieが使用できる
- 独自のカスタマイズオリジンからプライベートコンテンツを供給する事ができる


> - 署名付き URL または署名付き Cookie を使用してコンテンツにアクセスするようにユーザー (ビューワー) にリクエストします。
> - オリジンへのアクセスを制限して、CloudFront のオリジン向けサーバーからのみ利用できるようにします。これは、次のいずれかで実行できます。
>   - Amazon S3 オリジンでは、オリジンアクセスコントロール (OAC) を使用できます。
>   - カスタムオリジンでは、次のように実行できます。
>      - カスタムオリジンが Amazon VPC セキュリティグループまたは AWS Firewall Manager によって保護されている場合、CloudFront マネージドプレフィックスリストを使用して、CloudFront のオリジン向け IP アドレスからのみ、オリジンへのインバウンドトラフィックを許可できます。
>      - カスタム HTTP ヘッダーを使用して、CloudFront からのリクエストのみにアクセスを制限します。詳細については、 カスタムオリジン上のファイルへのアクセス制限およびオリジンリクエストへのカスタムヘッダーの追加を参照してください。カスタムヘッダーを使用して Application Load Balancer オリジンへのアクセスを制限する例については、Application Load Balancers へのアクセスを制限する を参照してください。
>      - カスタムオリジンにカスタムアクセス制御ロジックが必要な場合は、このブログの記事、Amazon CloudFront と Lambda@Edge を使用してプライベートコンテンツを供給するで説明されているように、Lambda@Edge を使用してそのロジックを実装できます。

- オリジンへのアクセスを制限し、CloudFrontのオリジン向けサーバからのみ利用できるようにする
- S3オリジンでは、オリジンアクセスコントロールができる
- カスタムオリジンでは、下記ができる
    - カスタムオリジンが、VPCのセキュリティグループ、Firewall Managerによって保護されているbが愛、CloudFrontマネージドプレフィックスリストを使用して、CloudFrontオリジン向けIPからのみ、インバウンドトラフィックを制御できる
    - カスタムHTTPヘッダーを使用して、CloudFrontからのリクエストのみアクセス制限できる

## CloudFront がコンテンツを配信する方法
### CloudFront がユーザーにコンテンツを配信する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e305b30f-4fcb-f6a0-a35a-9192bd64a921.png)
※ 出典：[CloudFront がユーザーにコンテンツを配信する方法](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/HowCloudFrontWorks.html)

> CloudFront でコンテンツ配信を設定すると、ユーザーがオブジェクトをリクエストしたときに次の処理が行われます。

> 1. ユーザーがウェブサイトまたはアプリケーションにアクセスして、イメージファイルや HTML ファイルなどのオブジェクトに対するリクエストを送信します。
> 1. DNS は、リクエストを、最も適切に処理できる CloudFront POP (エッジロケーション) にルーティングします。通常は、レイテンシーを考慮して最寄りの CloudFront POP が対象となります。
> 1. CloudFront では、リクエストされたオブジェクトのキャッシュをチェックします。オブジェクトがキャッシュにある場合、CloudFront はオブジェクトをユーザーに返します。オブジェクトがキャッシュにない場合、CloudFront は次の処理を実行します。
>    - CloudFront は、リクエストを、ディストリビューションで指定されている内容と照合し、ファイルのリクエストを、対応するオブジェクトに応じてオリジンサーバーに転送します (例えば、Amazon S3 バケットや HTTP サーバー)。
>    - そのオリジンサーバーが、エッジロケーションにオブジェクトを返します。
>    - オリジンから最初のバイトが到着した直後に、CloudFront はそのオブジェクトをユーザーに転送し始めます。また、CloudFront は、そのオブジェクトに対する次回のリクエストに備えて、キャッシュにそのオブジェクトを追加します。


- ユーザがオブジェクトをリクエストする流れは、下記の通り
  1. ユーザがオブジェクトに対してリクエストを送信する
  1. DNSは、リクエスト最も適切に処理できる CloudFront エッジロケーションにルーティングする
  1. CloudFrontではリクエストされたオブジェクトのキャッシュをチェックし、キャッシュにあればそのまま返す。キャッシュにないときは、下記の処理になる
      3a. オリジンに転送する
      3b. オリジンからエッジロケーションにオブジェクトを返す
      3c. CloudFrontは、オリジンから受け取ったオブジェクトをユーザに転送する。またキャッシュに追加する

### CloudFront とリージョン別エッジキャッシュとの連携
> CloudFront ポイントオブプレゼンス (POP またはエッジロケーションとも呼ばれます) を使用することで、人気のあるコンテンツをすばやくビューワーに提供できます。CloudFront にはリージョン別エッジキャッシュもあり、コンテンツが POP に残るだけの人気が十分にない場合でも、より多くのコンテンツをビューワーの近くに配置して、そのコンテンツのパフォーマンスを向上させます。
> リージョン別エッジキャッシュは、すべてのタイプのコンテンツ (特に、時間の経過とともに人気が落ちる傾向にあるコンテンツ) に役立ちます。この例には、ビデオ、写真、アートワークのようなユーザーが生成したコンテンツ、製品の写真やビデオのような e コマースアセット、突然新たに人気が出る可能性があるニュースやイベント関連のコンテンツがあります。

- CloudFrontは、POPを使用することで、素早くビューワーにコンテンツを提供できる
- CloudFrontには、リージョン別エッジキャッシュもある。コンテンツがPOPに残るだけの人気が十分にない場合でも、より多くのコンテンツをビュワーの近くに配置して、パフォーマンスを向上させる

#### リージョン別キャッシュの動作
> リージョン別エッジキャッシュは、ビューワーに近接して世界各地にデプロイされる CloudFront ロケーションです。オリジンサーバーと、ビューワーに直接コンテンツを提供する POP (世界各地のエッジロケーション) の間にあります。オブジェクトの人気が下がると、個別の POP では、これらのオブジェクトを削除し、より人気の高いコンテンツ用に容量を確保する場合があります。リージョン別エッジキャッシュのキャッシュは個別の POP よりも大きいため、オブジェクトは最も近いリージョン別エッジキャッシュロケーションでより長くキャッシュに残ります。これにより、より多くのコンテンツがビューワーの近くに保持されるため、CloudFront がオリジンサーバーに戻る必要がなくなり、ビューワーに対する全般的なパフォーマンスが向上します。

- リージョン別エッジキャッシュとは
    - ビューワーに近接して世界各地にデプロイされるCloudFrontロケーション
    - オリジンとビューワーに直接コンテンツを提供するPOPの間にある
        - ビュワー <-> POP <-> リージョン別エッジキャッシュ <-> オリジン
    - なぜ必要か？
        - POPでは、人気の高いコンテンツ用に容量を確保する必要がある。しかし容量に限りがある。
        - POPよりもキャッシュが大きいリージョン別キャッシュにおいておくことで、オリジンへのアクセスが不要になる

> ビューワーがウェブサイトで、またはアプリケーション経由でリクエストを実行すると、DNS はユーザーのリクエストに対応できる最適な POP にリクエストをルーティングします。通常、この場所は、レイテンシーに関して最も近い CloudFront エッジロケーションです。その POP では、CloudFront によってリクエストされたオブジェクトがキャッシュにあるかどうかをチェックします。オブジェクトがキャッシュにある場合、CloudFront はオブジェクトをユーザーに返します。オブジェクトがキャッシュにない場合、POP は最も近いリージョン別エッジキャッシュをフェッチします。POP がリージョン別エッジキャッシュをスキップして直接オリジンに移動する場合の詳細については、次の注記を参照してください。

- ビューワーがリクエストを行うと、DNSからユーザのリクエストに対応できる、最適なPOPにリクエストをルーティングする
- 通常、この場所はレイテンシが最も速いCloudFrontエッジロケーション（POP）になる
- POPでは、自分にキャッシュがあるかチェックし、なければリージョン別エッジキャッシュをフェッチする

> そのリージョン別エッジロケーションで、CloudFront は要求されたオブジェクトがキャッシュにあるかどうかをもう一度チェックします。オブジェクトがキャッシュにある場合、CloudFront はリクエスト元の POP にオブジェクトを転送します。リージョン別エッジキャッシュロケーションから最初のバイトが到着した直後に、CloudFront はそのオブジェクトをユーザーに転送し始めます。また、CloudFront は、そのオブジェクトに対する次回のリクエストに備えて、POP 内のキャッシュにそのオブジェクトを追加します。

> POP とリージョン別エッジキャッシュロケーションのいずれかでキャッシュされていないオブジェクトについて、CloudFront はディストリビューションの仕様とリクエストを比較し、リクエストをオリジンサーバーに転送します。オリジンサーバーがオブジェクトをリージョン別エッジキャッシュロケーションに送り返すと、POP に転送され、CloudFront はオブジェクトをユーザーに転送します。この場合、CloudFront は次回にビューワーがオブジェクトをリクエストしたときに、POP に加えてリージョン別エッジキャッシュロケーションのキャッシュにオブジェクトを追加します。これにより、リージョン内のすべての POP がローカルキャッシュを共有されて、オリジンサーバーに対して複数のリクエストがおこなわれなくなります。また、CloudFront はオリジンサーバーと永続的接続を保持しているため、可能な限り迅速にオリジンからオブジェクトが取得されます。

- CloudFrontは、POPにも、リージョン別エッジキャッシュにもなければ、オリジンにリクエストを転送する

>注記
> - リージョン別エッジキャッシュには、POP と同等の機能があります。たとえば、キャッシュ無効化リクエストでは、有効期限が切れる前に、POP とリージョン別エッジキャッシュの両方からオブジェクトが削除されます。エンドユーザーが次にオブジェクトを要求したときに、CloudFront はオリジンに戻ってオブジェクトの最新バージョンをフェッチします。
> - プロキシ HTTP メソッド (PUT、POST、PATCH、OPTIONS、DELETE) は POP からオリジンに直接送信され、リージョン別エッジキャッシュを経由してプロキシを実行しません。
> - リクエスト時に決定される動的リクエストは、リージョン別エッジキャッシュを通過せず、直接オリジンに送信されます。
> - オリジンが Amazon S3 バケットで、リクエストの最適なリージョン別エッジキャッシュが S3 バケットと 同じ AWS リージョン である場合、POP はリージョン別エッジキャッシュをスキップして S3 バケットに直接移動します。

- リージョン別エッジキャッシュには、POPと同等の機能がある
    - キャッシュ無効化リクエスト（有効期限が切れる前にPOPとリージョン別エッジキャッシュの両方からオブジェクトが削除される）
- プロキシHTTPメソッド（PUT,POST、PATCH、OPTIONS、DELETE）は、POPからオリジンに直接送信される（リージョン別エッジキャッシュは経由しない）
- リクエスト時に決定される動的リクエストは、リージョン別エッジキャッシュを通過しない
- オリジンがS3バケットのとき、リクエストの最適なリージョン別エッジキャッシュがS3バケットと同じAWSリージョンの場合、POPリージョン別エッジキャッシュをスキップしてS3バケットに直接移動する

## CloudFront エッジサーバーの場所と IP アドレス範囲
CloudFront エッジサーバーの場所の一覧は、[こちらのドキュメント](https://aws.amazon.com/jp/cloudfront/features/?whats-new-cloudfront.sort-by=item.additionalFields.postDateTime&whats-new-cloudfront.sort-order=desc#Global_Edge_Network)を、ご確認ください。

### CloudFront マネージドプレフィックスリストを使用

> CloudFront マネージドプレフィクスリストには、CloudFront のグローバルに分散されたオリジン向けサーバーの IP アドレス範囲が含まれています。オリジンが AWS でホストされ、AmazonVPC セキュリティグループで保護されている場合、CloudFront マネージドプレフィックスリストを使用して、CloudFront のオリジン側サーバーからのみオリジンへのインバウンドトラフィックを許可し、CloudFront 以外のトラフィックがオリジンに到達するのを防ぐことができます。CloudFront がマネージドプレフィクスリストを維持するため、CloudFront のグローバルオリジン向けサーバーの IP アドレスは常に最新になります。CloudFront マネージドプレフィクスリストを使用すると、IP アドレス範囲のリストを自分で読み取ったり、管理したりする必要はなくなります。

- CloudFrontマネージドプレフィックスリストには、CloudFrontのグローバルに分散されたオリジン向けサーバのIPアドレスの範囲が含まれている
- オリジンがAWSでホストされ、VPCのSGで保護されている場合、CloudFrontマネージドプレフィックスリストを使用することで、CloudFront以外のトラフィックがオリジンに到達することを防ぐことができる
- CloudFrontがマネージドプレフィックスリストを維持するため、CloudFrontのグローバルオリジン向けサーバのIPは常に最新になる
- CloudFrontマネージドプレフィックスリストを使用することで、IPアドレス範囲のリストを自分で読み取ったり、管理することは不要

> 例えば、オリジンが欧州 (ロンドン) (eu-west-2) リージョンの Amazon EC2 インスタンスであると想定します。インスタンスが VPC 内にある場合は、CloudFront マネージドプレフィクスリストからのインバウンド HTTPS アクセスを許可するセキュリティグループルールを作成できます。これにより、CloudFront のグローバルオリジン向けのすべてのサーバーがインスタンスに到達できるようになります。セキュリティグループから他のすべてのインバウンドルールを削除すると、CloudFront 以外のトラフィックがインスタンスに到達するのを防ぐことができます。

- 例：オリジンがeu-west-2のEC2
    - インスタンスがVPCのときに、CloudFrontマネージドプレフィックスリストからのインバウンドHTTPSアクセスを許可するSGを作成できる

> CloudFront マネージドプレフィクスリストの名前は com.amazonaws.global.cloudfront.origin-facing です。詳細については、Amazon VPC ユーザーガイドの「AWS マネージドプレフィックスリストの使用」を参照してください。

- AWSマネージドプレフィックスリストのCloudFrontのWeightは、55ある
- VPCのセキュリティグループのクォーターは、60個あり、余りが5個になる
- 詳細は、[こちら](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/working-with-aws-managed-prefix-lists.html#aws-managed-prefix-list-weights)を参照

## コンテンツへのセキュアなアクセスとアクセス制限の設定
> CloudFront には、コンテンツをセキュリティで保護するためのオプションが用意されています。CloudFront を使用してコンテンツへのアクセスを保護および制限する方法を次に示します。
> - HTTPS 接続を設定する
> - 特定の地理的な場所にいるユーザーがコンテンツにアクセスできないようにする
> - CloudFront の署名付き URL または署名付き Cookie を使用してコンテンツにアクセスするようにユーザーに要求する
> - 特定のコンテンツフィールドのフィールドレベルの暗号化を設定する
> - AWS WAF を使用してコンテンツへのアクセスを管理する

- CloudFrontには、コンテンツをセキュリティで保護するためのオプションが用意されている
    - HTTPS接続を設定する
    - 特定の地理的な場所にいるユーザーがコンテンツに、アクセスできないようにする
    - CloudFrontの署名付きURL、または署名つきCookieを使用してコンテンツにアクセスするようにユーザに要求する
    - 特定のコンテンツフィールドのフィールドレベルの暗号化を設定する
    - WAFを使用してコンテンツへのアクセスを管理する


# 実践
[基本的な CloudFront ディストリビューションの開始方法](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html)を基に試します。

## 前提
1. AWSドキュメントに添付されている「[hello worldWebページ](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/samples/hello-world-html.zip)」をダウンロードし、解凍しておきます
1. ファイル構成は下記のようになっています
    ```
    $ pwd
    /XXXXX/hello-world-html
    $ tree
    .
    ├── css
    │   └── style.css
    └── index.html
    
    2 directories, 2 files
    $  
    ```


## ステップ 1: Amazon S3 バケットを作成する
1. AWSにサインインします
1. S3に移動します
1. バケットを作成します。（このとき、地理的に近いリージョンを選択することが推奨とのことなので）ap-northeast-1に作成します

## ステップ 2: コンテンツをバケットにアップロードする
1. 前提でダウンロードしたCSSフォルダとindexファイルをステップ1で作成した、S3バケットにアップロードします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f0a1e6be-c5b5-0af8-6f71-eb6fec0d4de9.png" width=450/>

## ステップ 3: OAC で Amazon S3 オリジンを使用する CloudFront ディストリビューションを作成する
1. CloudFront コンソールへ移動します
1. 「CloudFront ディストリビューションを作成」をクリックします
1. 下記を入力します
    - Origin domain: ステップ1で作成したS3を指定
    - オリジンアクセス: Origin access control settingsを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/5bce27d6-92f8-9d54-ccfb-f7f1afe32a72.png)
1. Create new OACをクリックします
1. 下記を入力し、「Create」をクリックします
    - 署名動作：署名リクエスト（推奨）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/46276a50-f6f0-93dd-5f26-881021d4b9c4.png)
1. WAFでは、セキュリティ保護を有効にします
1. その他はデフォルトのままで、「ディストリビューションを作成」をクリックします
1. S3バケットポリシーを更新する必要がありますとバナーが表示されるので、「ポリシーをコピー」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2cf217d4-0578-f1b4-1802-a987ceea4829.png)
1. 「S3バケットの権限に移動してポリシーを更新する」をクリックします
1. 「S3のアクセス許可」タブをクリックします
1. バケットポリシーで「編集」をクリックし、コピーしたポリシーを貼り付け、「変更の保存」をクリックします
    ```
    {
            "Version": "2008-10-17",
            "Id": "PolicyForCloudFrontPrivateContent",
            "Statement": [
                {
                    "Sid": "AllowCloudFrontServicePrincipal",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "cloudfront.amazonaws.com"
                    },
                    "Action": "s3:GetObject",
                    "Resource": "arn:aws:s3:::XXXXXXX/*",
                    "Condition": {
                        "StringEquals": {
                          "AWS:SourceArn": "arn:aws:cloudfront::XXXXXXXXX:distribution/YYYY"
                        }
                    }
                }
            ]
          }
    ```
1. ディストリビューションドメイン名をコピーしておきます

## ステップ 4: CloudFront からコンテンツにアクセスする
1. 上記でコピーしたドメインを基にリクエストします。表示されました

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c3f80f8b-2cd5-6012-8da7-895c22b85d7c.png)

## ステップ 5：クリーンアップ
### CloudFront
::: note info
一度、無効にしたあと、削除が可能になります。

::: 

はじめに、ディストリビューションを削除し、次にS3を削除します
1. CloudFrontに移動します
1. 対象のディストリビューションを選択し、「無効」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6a1bf16f-d6e1-7775-9541-7c16294e51f7.png)
1. ステータスが「無効」、最終更新日が「デプロイ」になります
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c47ea040-dde7-3bad-e46f-cad150bfb1f4.png)

1. しばらくすると、最終更新日に、日時が反映されるので、チェックし、「削除」ボタンをクリックします

### S3バケット
1. ファイルを削除したあと、バケットを削除します

# 考察
今回は、CloudFrontの基礎的な知識整理と、簡単なハンズオンを試してみました。
次回以降は、エッジ関数やWAF、ディストリビューションを調べてみたいと思います。

# 参考
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/working-with-aws-managed-prefix-lists.html#aws-managed-prefix-list-weights