CloudFront + S3 + Route53 + ACMで高速静的ファイル配信

[QualiArts Advent Calendar 2020](https://qiita.com/advent-calendar/2020/qualiarts)、16日目担当の末吉です！

今回、AWSを使って高速静的ファイル配信を実現する方法をまとめさせて頂きました。

# はじめに
静的ファイルの配信速度を高めるために、S3とCloudFrontを組み合わせて、CloudFrontから静的ファイルを配信する、、、というのはよくある王道な設計だと思います。
でも設定がダルくてS3コンテンツへ直接アクセスできるようにしてしまいがち。


そこで今回は、
・<b>CloudFrontをS3の前に置いて静的ファイルの配信を高速化する</b>
・<b>CloudFront経由以外のアクセスを禁止する</b>
・<b>https通信でCloudFrontとのやり取りは暗号化する</b>

という3つの条件を満たす方法を紹介します。

# ゴール

![Untitled Diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/f64496bb-73d6-49e3-26c9-e1b7355e0cbe.png)

上記の図のように
・S3コンテンツに直接アクセス出来ないようにする
・CloudFront経由の時のみS3コンテンツが見れる
・CloudFrontとの通信はhttps通信で暗号化する

という感じの構成にします。

# 今回やらない事
・初学者向けの記事にしたいので、Terraformなど使ってインフラのコード化は今回してないです。
(コンソールでポチポチしてください)

# 手順
1: S3バケットの作成
2: オリジンアクセスアイデンティティ付きのCloudFrontの作成
3: CloudFront経由で画像を見れるか動作確認
4: Route53とACMを使って、https通信にする
5: https通信のCloudFront経由で画像を見れるか動作確認

という感じです。

# 実装
それでは作っていきましょう！

## 1: S3バケットの作成
まず、S3バケットを作成します。
AWSコンソールからS3をクリックして下さい!

![6B7FD1DC-6F6D-4C16-962F-A3A38D9E89DA_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/95fb5d12-53c0-a56e-e5d7-0b51a16879ba.jpeg)

バケットの作成を選択します。


<img width="901" alt="A2E9C7D1-B13A-4854-9E26-AE135214DB41_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/e5f7d16a-1bcd-aa35-8b48-79b9625880a6.jpeg">

バケットの作成画面で作っていきましょう。
バケット名は適当に決めちゃって大丈夫ですが、既に他のバケット名が使われていると作成出来ないので注意。今回僕はqiita-imagesにしました。
リージョンも基本的にお好みで大丈夫です。

重要なのが<b>パブリックアクセスをすべてブロック</b>がしっかり設定されている事。

基本的にデフォルトで選択されているのでいじらずにそのまま作成しちゃいましょう。
詳細設定はしなくても大丈夫です。

![460B6407-D2DE-45FD-B1E3-BDD169B87A8E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/fcd9dff8-7033-e975-2953-4f0c5ce4f7ca.jpeg)

![9A779152-48F8-4423-90FB-5516A3B2A8B8_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/ac349140-e2f7-1fc3-9a3e-242036d5ba40.jpeg)


下記の画面のようにバケットがちゃんと作成されていて、アクセスが非公開になっていることを確認。

<img width="1429" alt="302927F6-044C-4101-A6E1-B747CEA995C9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/16349f77-79a7-c9c1-3c71-7be3b231da6d.png">

動作確認用に画像をバケットにブチ込んでおきましょう。

作ったバケットをクリックして、

![908CDF74-8598-43BE-87DB-35E7E2BA36D5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/e695f015-f3c2-1742-191a-87e75e769a98.jpeg)

アップロードを選択。
![12D058F4-F92A-43E7-8AD3-03AFD34BF274_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/78e1a56b-fb9d-e021-fcf4-090f10376178.jpeg)

適当に画像を入れる。
今回はいらすとやの可愛いワンちゃんの画像でも使いましょう。

![fantsy_haneinu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/663d4945-6a41-aa55-b953-c2618982fa28.png)


![27FBBE3D-C478-4320-AB88-1CB92F881844.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/f7b0ad9d-716d-3373-5642-1c50dd80ba57.jpeg)


セット出来たら何も設定せずにそのままアップロード。




しっかり作成出来たら、アップロードしたファイルをクリック。

![D5B9D9F3-79E2-4BE8-B159-84E5F15F6FC7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/0a09828e-4718-c0ae-dd6e-7fb8f271aede.jpeg)

詳細画面に来たら、オブジェクトURLをクリック。
このURLはS3から直接ファイルを見にいくURLです。

![0A53CA26-CF75-43FF-B8C0-CCC4D3C482B1_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/9293e943-0119-2bec-d595-bcace9f495e9.jpeg)

そうすると<b>AccessDenied</b>が表示されると思います。
ちゃんとS3コンテンツへ直接アクセス出来ないようになっていますね！

<img width="1396" alt="スクリーンショット 2020-05-03 13.38.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/e659d623-ae35-cf55-827d-a40acd4a7667.png">

## 2: オリジンアクセスアイデンティティ付きのCloudFrontの作成

S3の作成が終わったので、今度はCloudFrontを作成していきましょう。

AWSのコンソールからCloudFrontをクリックして下さい。


![AB773598-DCE1-4EB3-8912-11E06A95B426_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/d4a4e797-eddf-87d3-7b08-52ac35e69fb2.jpeg)


Create Distributionを選択。

![13684346-B23A-46ED-8276-DF4CCB70EAD4_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/1b17b623-ecb7-ab5a-5f69-addfc4189c58.jpeg)

<b>Web</b>のGet Startedを選択。

![CAA23914-5A64-4DC2-8097-E40D541E56C3_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/14e656c8-6c15-6d15-2a9d-bd0738a836c0.jpeg)

<b>Origin Domain Name</b>を先ほど作ったS3バケットに指定。

![1736A1BA-8708-4EE5-89F4-3CDE0BD539B7_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/b59c2f9b-14d4-2309-5741-a7c0bde70e17.jpeg)

<b>Restrict Bucket Access</b>をYesに選択し、<b>オリジンアクセスアイデンティティ</b>を使用する設定にします。

![DE3B818E-CF37-4B53-B185-835FDD5C7B37_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/84c49fbb-03f6-9457-819d-e07d425b9758.jpeg)

<b>Create a New Identity</b>でYesを選択して新規作成をするように設定し、分かりやすいようにCommentにバケット名を追記しておきましょう。
そして、<b>Grant Read Permissions on Bucket</b>でYes, Update Bucket Policyを選択して、S3コンテンツの読み取りを許可するためにバケットポリシーを更新するようにしておきます。

![CB0078C8-D9F2-47C4-9B90-B079A3345018.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/6cb8b920-4255-17c6-87b0-1e467b1db0e5.jpeg)

他の設定はとりあえずそのままでオッケーなので、画像を1番下までスクロールしてCreate Distributionをクリックして作成してください。

![58E2BF25-561F-4A29-9F56-4234EC7442F3_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/1da330a0-e4d5-bf51-ba3f-fc5f126aff11.jpeg)

これでCloudFrontの設定は完了です！
作成に15分くらいかかるので、しばらく待ちましょう。
15分くらい経ってStatusがDeployedになったら次に進んでください！


![8098F4E2-C840-45FC-A642-12E1D048C0BA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/bd509323-0aa2-9a95-7299-58890ee60d72.jpeg)



## 3: CloudFront経由で画像を見れるか動作確認

15分程経ってCloudFrontが無事に作成されたら、次に動作確認を行なっていきます。
冒頭で作ったS3バケットの詳細画面に行って、アクセス権限をクリックしてください。

![88103A0B-A74D-4167-AD5F-59E100B15BFC_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/f294b6c8-bef9-6309-fd12-2f1b7f32e8c1.jpeg)

バケットポリシーをクリック。

![6467A09B-1A6F-4D62-9726-73EB776EF19F_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/52e83ac1-31f3-f823-f941-404e3adf01d6.jpeg)

Resouceのところだったり細かい文字やIDはバケットによって異なるので、下記のような感じでバケットポリシーが自動で設定されていたらオッケーです。


![56380987-BF34-4495-914E-B0416E063791_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/2a210b19-057b-38de-13c1-473095ae8dee.jpeg)


では、画像にアクセスしていきましょう。

CloudFrontの画面に行って、作ったDistributionのIDをクリック。


![6005497A-AD98-446D-A680-B524629CAD85_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/3c4ccecc-df61-d44c-1e1c-98524fd8dca0.jpeg)

Distributionへのドメインが表示されるので、これをコピーします！

![E08AFFC0-BB6C-4B66-86BA-B5C59F741FAD_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/868df883-4fc3-365a-922e-17108e5e1d06.jpeg)

先ほどアップロードした犬の画像のファイル名は、fantasy_haneinu.pngでしたね。

なので、ブラウザで
<b>d1h87ehtf3c9o.cloudfront.net/fantsy_haneinu.png</b>
みたいな感じで、コピーしたドメインの後ろに画像のファイル名を入れてあげると、、

![1780C070-A952-45EC-A641-56FE2CE1EAA1_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/dfc0a546-af84-c069-0b10-bb79d6fc3de8.jpeg)


無事に表示されましたね！

念の為にS3から直接アクセスしてみましょう。

![0A53CA26-CF75-43FF-B8C0-CCC4D3C482B1_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/f8d2cb6a-068b-1394-dd9b-ef830ec2cfbf.jpeg)


<img width="1396" alt="スクリーンショット 2020-05-03 13.38.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/e659d623-ae35-cf55-827d-a40acd4a7667.png">

変わらず、S3からの直接アクセスは禁止されていますね。
これで無事に<b>CloudFrontを経由する時のみ</b>S3コンテンツに直接アクセスする事が可能になりました！

## 4: Route53とACMを使って、https通信にする
次に、Route53を使って、https通信にしていきましょう。

まず、Route53でドメインを取得していきます。
<b>ドメイン取得には少しだけお金がかかるので注意しましょう！</b>


![BB5FB25F-568E-4580-A562-A24D5044E3E1_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/a6fcfc3c-d0d5-c1fe-0924-2a984a0616f2.jpeg)

登録済みドメインを選択。


![41D19C8E-720C-4AA7-995A-368980C39EE6_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/79e86a17-77e9-e664-7dc3-15fac346e9ed.jpeg)

ドメインの登録を選択。

![F41B8C8E-5E85-4354-9551-D43462AE8875_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/1981b355-f7ad-6a3a-bb7e-d464ea004e8a.jpeg)

ドメインの選択欄でご自身が設定したい名前のドメインとトップレベルドメイン(.comなど)を決め、<b>チェック</b>を押してください。
ここでは例として、ドメイン「example」、トップレベルドメイン「.de」としています。(.deは安いのでオススメです！)


![FE68F317-3C1A-4EB6-B7C0-F8AF5E88310D_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/d51d6460-6eeb-d6db-652a-9454aab61810.jpeg)


なお、チェックを押下した際、使用不可と出力されることがあります。
ドメインは世界中で重複しないため、貴方が設定しようとしたドメインは既に他の誰かが登録しているということとなります。
チェックが通るまでドメインの変更を行なってください。

チェック完了後、購入者の連絡先詳細画面となるため、ご自身の情報を記入し続行を押下してください!
(個人情報なので、画面は割愛します)

その後、記入内容に問題なければ注文を完了を押下してください。
注) 注文完了を行うと料金が発生します。問題ないか再確認を行なってください。

![CAD7DA2D-E246-488B-928E-C99F67AF4728.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/62794dbf-a44e-bf46-43f2-3479279239a9.jpeg)

注文完了後、数分ほど時間をおいてドメインの登録に成功するはずです。
サイドバーの<b>登録済みドメイン</b>から確認を行なってください。


![1EC474BD-3B21-49DF-BFA7-0D8D7CAEB276_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/4f2104ed-e30c-791f-745d-5ada969afb7e.jpeg)

これでドメインの取得が出来ました！

次に、CloudFrontのドメインと、今入手したドメインを結び付けていきます。

まずはCloudFrontのドメインを確認していきましょう。
先ほどコピペしたやつですね。

![6005497A-AD98-446D-A680-B524629CAD85_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/ce895141-cad1-a337-c404-6e2ed7405fc6.jpeg)

![E08AFFC0-BB6C-4B66-86BA-B5C59F741FAD_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/0422dd12-7f77-3356-3c15-dc9daa08ca30.jpeg)


コピーしたら、次にRoute53のサイドバーにある<b>ホストゾーン</b>を選択して、先ほど作ったドメインをクリック。


![A7E26B2C-110E-46F3-A3FB-5C2A4FD82996.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/7a3d1049-3c3e-2bcb-1ca3-eff91ec4d4a2.jpeg)

<b>レコードセットの作成</b>をクリック。

![0C59A155-67E4-40AD-9571-74099E989379_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/cbb7cd6c-756c-d91e-65f5-f553a59cd79f.jpeg)

名前: www(基本何でも大丈夫です)
タイプ: CNAME - 正規名
値: コピペしたCloudFrontのドメイン

という感じで設定して、<b>作成</b>をクリックしてください。

![9A79979B-5BB1-4BF6-B31F-A49BAF377D19.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/8cebc93e-43c5-f132-394e-d2d85e884f9e.jpeg)



無事にレコードセットの作成をして、このドメインとCloudFrontのドメインの結び付けが出来ましたね！

次に、このドメインに対して、ACM(AWS Certificate Manager)を使って、SSL/TLS証明書を発行しましょう。
この証明書がないとhttps通信が出来ません。

さて、この証明書なのですが、<b>CloudFrontで使う時にはバージニア北部で発行した証明書でなければならない</b>という仕様のため、リージョンを切り替えて証明書を発行していきます。
* 2020/05/03現時点での情報です。今後変わる可能性もあるかも、、

というわけで、リージョンをバージニア北部にしましょう。

![52F54284-33D7-470F-928F-379B7BBC949A_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/282b6f27-fd89-5c47-0c86-3bf2b8039e30.jpeg)

切り替えたら、Certificate Managerを選択。

![43231531-0FFE-4D8D-86A3-4E61549708D6_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/8113ec54-4aa5-33fe-56ef-3473b8778e20.jpeg)

画面が切り替わったら、証明書のプロビジョニングの<b>今すぐ始める</b>をクリック。

![8EBC879D-7215-426C-A66A-9D4A1DD0F2A5_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/a3bb7968-f7ad-5579-c5db-4c5cff39a1fb.jpeg)

デフォルトの<b>パブリック証明書のリクエスト</b>のままで大丈夫です。
次に進みましょう。

![BF34B675-8472-4C3C-AE77-E04D1357524D_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/b1b92217-4975-1f5c-61c6-93c555821da8.jpeg)

ドメイン名に、先ほどCloudFrontと結び付けた「www.{ドメイン名}」というドメインをここに入力して、<b>次へ</b>をクリック。

![2FC1DE24-2119-42B7-BF6D-734E515E506C_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/56b8ec0d-015b-93ef-cc49-b9113c5067a6.jpeg)

ここもデフォルトのDNSの検証で大丈夫です。<b>次へ</b>をクリック。


![0D484E13-0A5E-4AAE-A126-3CDF8F4830AB_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/e03e2614-f6fa-0b3a-bad0-b14e2db6655a.jpeg)

タグはあってもなくても大丈夫です。<b>確認</b>をクリック。

![F595A8B9-28AE-45A3-A2C7-390B2A251B68_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/d6f8922a-0c46-d3b8-01df-bf73845ca6a4.jpeg)

<b>確定とリクエスト</b>をクリック。

![C1159A9A-647F-4955-B82A-9B83801B1DFD_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/952146d5-105f-d859-4a06-fa2fc615cded.jpeg)

画面が切り替わったら、ドメインの横にある三角のマークをクリック。

![47189F91-B14E-4198-AACC-C0327360C641_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/4f139903-4093-4fea-a981-153115d5fb8f.jpeg)

1番下にある<b>Route53でのレコードの作成</b>をクリック。

![907B8C82-C875-4DD3-8AB3-C4B72F196729_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/9d0886c2-6f8e-8ac5-2a85-e69f0e2467ca.jpeg)

結構時間がかかる場合があります、、、
数分待って、状況が<b>発行済み</b>になったら成功です！

![2CE58EA9-1A3A-45A8-AC3F-73A1712C03C1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/0e8ae79b-d42d-fa2f-47e7-aab1b8ce02dd.jpeg)


ここまでで、ドメインを取得して、CloudFrontと結びつきの土台を作って、SSL/TLS証明書を発行してきました。

いよいよラストです。
CloudFrontの設定を行います！

まず、今まで通りCloudFrontのIDをクリックしてください。

![6005497A-AD98-446D-A680-B524629CAD85_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/f811fc84-e51c-ccdd-32aa-dbebbba30636.jpeg)

GeneralのEditをクリック。

![2EBC491A-3EEE-426F-BC61-89074D97F044_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/95ed5492-f85f-c02b-47c8-43014fd5dafa.jpeg)

<b>Alternate Domain Names</b>に、お馴染みのwwwドメインを入力します。
そして、<b>Custom SSL Certificate</b>を選択し、先ほど作った証明書を選択。

![CEEDC73B-BB41-46B2-9CE5-E308DC3F495D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/85ca0033-e92a-e811-ce62-25356e47d53e.jpeg)

他はガン無視で大丈夫なのでYes, Editしちゃいましょう。

<img width="1419" alt="C84C6D36-AF7C-4A95-9B1C-41433FF8C981.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/5239095d-66ca-c561-2d79-18889564b4b5.png">

これでGeneralの設定が終わりました。
次に、Behaviorsの設定を行なっていきます。
Editを選択してください。

![A8ACEDC9-C4D4-4468-9091-379A8CA26F9E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/596c6e44-3ed1-20c3-ac89-1312621be5f4.jpeg)

<b>Viewer Protocol Policy</b>を下記のようにhttpsへリダイレクトするように設定。

![C2022A15-AE74-4CE6-8E2F-778100848330_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/46a088a5-fd5e-c054-e0d0-185e65175519.jpeg)

他は同じくガン無視でYes,Editしちゃいましょう。

![0A4FDEC8-7283-4511-B56E-29CB2BF930D6_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/261bd58b-cadd-03b6-1532-a11ce222b79b.jpeg)

これで設定は完了です！


反映に数分かかる事があるので、しばらく待ってみてください。


## 5: https通信のCloudFront経由で画像を見れるか動作確認

数分待った後に、

<b>wwwドメイン/fantsy_haneinu.png</b>

をブラウザで叩いてみると、、、

![E3260FAB-31C9-4CDD-AF8A-FF87720C4FB3_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301628/b38b3ced-7fe9-ce97-f229-9294cdbb13e5.jpeg)


ちゃんと鍵マークがついていますね！
ワンちゃんもしっかり表示されてます！！これで完成です🎉🎉🎉🎉🎉

## 最後に
<b>(お金がかかってしまうので、今回お試しでやった方はお掃除を忘れずに！)</b>