最強のCDNサービス Amazon CloudFrontの使い方、設定方法を解説！

# はじめに
今回はAWSのCDNサービスAmazon CloudFrontの設定方法について解説します！
最初に、CloudFrontの利点を説明し、実際の設定方法をみていきます。

## 対象
- AWSを使って、高速なコンテンツ配信をしてみたい方
- AWSを使ってサービス開発している方で、CloudFrontの使い方が曖昧な方

# YouTube動画
動画で確認したい方はこちらから視聴できます！
[最強のCDN！ Amazon CloudFront の設定方法について解説します!](https://www.youtube.com/watch?v=xcXC53D75jw&feature=youtu.be)
[![最強のCDN！ Amazon CloudFront の設定方法について解説します](https://img.youtube.com/vi/xcXC53D75jw/0.jpg)](https://www.youtube.com/watch?v=xcXC53D75jw&feature=youtu.be)

# CloudFrontとは
CloudFrontとは、Content Delivery Network (CDN) の代表的なサービスの1つです。
CDNにより、コンテンツを効率的かつ高速に配信することができ、世界中のどこからでも高速なアクセスを実現することができます。

# CloudFrontでできること
CloudFrontでできることは大きく分けて4つほどあります。

## パスごとにAPIとS3を分ける
CloudFrontはパスごとにAPIとS3を分けることができます！
例えば/apiになっていればAPIでサーバに飛ばし、それ以外はS3に飛ばすということができます。

## S3のHTTPS化
CloudFrontではS3をHTTPS化し、自分のドメインで配信することができます。
また、CloudFrontは従量課金制のため、アクセスが少ないWebサイトでは、ほとんど無料のような安さです！

## BASIC認証
Lambda Edgeを使うと、BASIC認証もできます！

# 作成
それでは実際の作成方法をみていきます。
今回は、S3に配置したオブジェクトをCloudFront経由で配信するケースを考えます。

まず、CloudFrontにアクセスし、Create Distributionを選択します。
すると、以下の画面に遷移します。
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/6da899c6-57ae-39cb-1b72-c54e235337f1.png' width='550' />

## Origin Settings
まず、Origin Domain Nameをクリックし、S3の適当なオブジェクトを選択します。

オブジェクトを選択すると、いくつか項目が増えます。

![スクリーンショット 2021-02-14 18.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/5bc6cc10-69bd-3ae2-7b54-6c2f79993069.png)

Origin Pathを設定すると、CloudFrontで配信するオブジェクトを限定することができます。
Enable Origin Shieldに関しては、以下のクラスメソッドの記事が詳しいです。
https://dev.classmethod.jp/articles/amazon-cloudfront-support-cache-layer-origin-shield/

上記2つに関しては今回触りません。

次にある、Restrict Bucket AccessはYesにしておきます。
これをすることで、S3をpublicにしていない状態でCloudFrontから参照させることができます。

また、Restrict Bucket AccessをYesにすると、Origin Access Identityを選択できるようになります。
こちらは今回初めて作るので、Create a New Identityを選んでおきます。

![スクリーンショット 2021-02-14 18.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/db56b291-af51-2b86-4387-826083195549.png)

あと、CloudFrontで設定した内容を元にS3の設定を書き換えてくれるように、Grant Read Permission on BucketもYesにしておきます。

![スクリーンショット 2021-02-14 18.50.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/7e580ba1-5ac2-67f4-e38a-abd0010ff381.png)


## Default Cache Behavior Settings
ここでは、キャッシュへのアクセス制御を設定します。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/c0fc48bc-2d19-87d7-7ea3-8ff985e2d2a1.png' width='850' />

Viewer Protocol Policyでアクセスする際のプロトコルを指定できます。
httpでアクセスされたら、httpsにリダイレクトさせるようにしたい場合は、Redirect HTTP to HTTPSを選択します。
![スクリーンショット 2021-02-14 18.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/9fe577ee-7395-7519-a8c7-afeb0b0a69ab.png)

Allowed HTTP Methodsでメソッドの指定ができます。
S3にアクセスさせるだけならば、GET, HEADだけで十分です。
APIを使いたい場合に、一番下のGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETEを選びます。
![スクリーンショット 2021-02-14 18.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/c67fea60-08c9-7947-a45d-02708b29db2b.png)

最後の方にあるCompress Objects AutomaticallyはYESにしておくと、Gzip・Brotli配信が可能になります。
ブラウザがChromeかFirefoxでHTTPS通信の場合のみ、Brotliになります。
[圧縮ファイルの供給](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html)

![スクリーンショット 2021-02-14 19.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/4d8c1aec-ae0a-2aa3-f262-5460ea3cde6d.png)


また、Brotliに関しては動画にしてるので、こちらでチェックしてみてください！

[えっ、私の圧縮率低すぎ！？ 最新のコンテンツ圧縮技術 Brotliを解説！](https://youtu.be/g7K7Pc7U5z8)
[![最強のCDN！ Amazon CloudFront の設定方法について解説します](https://img.youtube.com/vi/g7K7Pc7U5z8/0.jpg)](https://youtu.be/g7K7Pc7U5z8)


Basic認証を設定したい場合はLambdaを追加することで設定できます (今回は説明しません)。
![スクリーンショット 2021-02-14 19.05.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/2b7d6d1d-181d-272b-dc3a-282febf3ccdf.png)

最後に、ログを取りたい場合はこちらをYesにすることでログを取得できます。
![スクリーンショット 2021-02-14 19.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/77091dac-52d9-b40c-00a7-2592d96aed05.png)

## Distribution Settings
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/5269ab40-4ac0-5d5c-6242-bcd4aac13a5e.png' width='850' />

ドメイン名の設定をしたい場合は、Alternate Domain Namesを設定します。
また、こちらを設定する際は、SSL Certificateの下にある Request or Import a Certificate with ACMを選択する必要があります。
![スクリーンショット 2021-02-14 19.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/958f7d74-ee9d-9c0e-058c-629296d71757.png)


次のSupported HTTP Versionsはデフォルトで大丈夫ですが、Default Root Objectはルートとなるファイルを選択しておく必要があります。
![スクリーンショット 2021-02-14 19.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/3b41961c-4a40-b671-a764-be73d2f06196.png)

以降の設定はデフォルトで大丈夫です。
設定後、東京リージョンの場合は3 ~ 4時間ほどで反映されるようになり、S3をCloudFrontで配信できるようになります！


# Distribution作成後の設定画面
以上の設定を終え、Distributionが作成されると次のような画面になります。
こちらのいくつかのタブについて、補足しておきます。
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083231/bdfa07e7-d2d2-47c4-5b65-8ab50c63dc3a.png' width='850' />

## Invalidations
<b>一番重要</b>なので、こちらを先に説明します！

Invalidationsはすでに配信されたキャッシュを無効化するときに使います。
新しいコードをデプロイしたら必ずInvalidationしましょう！
![スクリーンショット 2021-02-09 18.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083231/3113a483-d883-7d62-b037-c23e0c3410a1.png)


## Origins and Origin Groups
まずそもそも、Originとは配信したい元データをもっているサーバーのことです。
元データはS3にあるので、今回の場合はS3がOriginです。

ここでOriginの編集ができます。

![スクリンショット 2021-02-09 18.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083231/58997998-826f-3ad1-bcb6-aa5e152044b2.png)


## Behaviors
Behaviorsでは、どのOriginから配信するかパスごとに設定することができます。
今回の設定では、どのパスから通信が来ても、S3のyassun-websiteのオブジェクトを返すようにしています。

APIサーバーと通信させたい場合は、ここに/api/*を登録して設定します。

![スクリーンショット 2021-02-09 18.34.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083231/db27fd49-7d25-52fd-9e24-f39d515beeaa.png)


## Error Pages
Error pagesでは、エラーが出たときにどういう挙動をさせるかを定義します。
![スクリーンショット 2021-02-09 18.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083231/c2021de9-da48-f441-bfe8-92ea351d720f.png)

# まとめ
今回、CloudFrontの使い方を解説しました。
NetlifyやVercelと比べると扱いづらいですが、その分カスタマイズできることも多いため、興味を持った方は是非、使ってみてください。