AWS S3 + CloudFront + 独自ドメインを使った静的サイトの作成方法をめちゃくちゃ詳しく解説する

# はじめに
独自ドメインを取得し、AWS S3 + CloudFrontを使って静的サイトを作成していきます。
この記事には以下の内容が含まれます。
- REST APIエンドポイントを用いて、AWS S3 + CloudFrontを使って静的サイトを作成する方法
    - 各設定項目についての詳細な説明
- 独自ドメイン（Google Domains）を導入する方法
- DNSSECの設定方法
- DNSレコードについての説明

# 独自ドメインを取得する
ドメインを取得するのは何でも構いませんが、この記事では[Google Domains](https://domains.google/intl/ja_jp/)を使用します。各レジストラの指示に従って欲しいドメインを購入してください。

# 独自ドメインをAWSに追加する
1. Route53のダッシュボードに移動し、「ホストゾーン」をクリックします。
    ![スクリーンショット 2022-11-05 23.37.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/d74830b3-f97b-d39c-3546-0af9abb16df1.png)
1. 「ホストゾーンの作成」をクリックします。
    ![スクリーンショット 2022-11-05 23.38.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/4880849b-a8e4-e76c-e330-abd03942d856.png)
1. 「ドメイン名」を入力し、「パブリックホストゾーン」を選択し、「ホストゾーンの作成」をクリックします。
    ![スクリーンショット 2022-11-05 23.40.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/e003ef28-68fc-355d-14dc-0e87b375b2e5.png)
1. ホストゾーンの一覧ページに飛ぶので、「レコード」の「タイプ」が「NS」の行の「値/トラフィックのルーティング先」の列に表示されている値（ネームサーバー）はあとで使うので確認できる状態にしておきます。
    - メモを取る必要はなくて、ブラウザ上でタブを消さないでいればそれで大丈夫です。
1. [Google Domains](https://domains.google.com/)にアクセスし、「マイドメイン」を開いて、使用するドメインの「管理」をクリックします。
    ![スクリーンショット 2022-11-05 23.43.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/e6d82840-3866-54b5-de49-70503d15e9e5.png)
1. 「DNS」にアクセスし、「カスタムネームサーバー」タブを選択して、「ネームサーバー」に前述したAWSのホストゾーン一覧のページに表示されているネームサーバーを全て入力して保存します。
    - 一応ネームサーバー名の最後のドットも含めてGoogle Domainsの方にコピペしよう。[こういう記事があるので](https://qiita.com/tobari_ko/items/1310384f7b6b24d01fc7)。ただ保存後は最後のドットが消えた状態で表示されるので果たして意味があるのかはわからない。だけどつけて悪いことは起こらないのでつけとくのがいいかも。
    ![スクリーンショット 2022-11-05 23.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/2f75b02c-3502-0a79-9481-a1cddd68a83c.png)
1. ネームサーバーを保存後、上に表示される「これらの設定に切り替える」をクリックする。そうすると２枚目の画像のようになる。
    ![スクリーンショット 2022-11-05 23.56.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/0117ee34-2c5b-d659-e9e3-c4eb24a02eb1.png)
    ![スクリーンショット 2022-11-05 23.56.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/0c4420bf-8471-fc2a-16bc-b89c658f1da6.png)
1. AWSに戻り、リージョンを「バージニア北部（us-east-1）」に変更する。
    - CloudFrontからはバージニア北部にある証明書（後述）しか利用できないため。
1. AWS Certificate Manager（ACM）のダッシュボードにアクセスし、「証明書をリクエスト」をクリック
    ![スクリーンショット 2022-11-06 0.03.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/d7f4f6ec-28eb-3919-0e0b-01188c927ef5.png)
1. 「パブリック証明書をリクエスト」を選択し、「次へ」をクリックします
    ![スクリーンショット 2022-11-06 0.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/4f1ea31e-823b-136f-bb58-00ae96398eb3.png)
1. 「完全修飾ドメイン名」にドメイン名とワイルドカード証明書用のドメイン名を入力し、「検証方法」は「DNS検証」を選択して、「リクエスト」をクリックします。
    - [ワイルドカード証明書について](https://jprs.jp/pubcert/about/wildcard/)が参考になります。これで全てのサブドメインに対して有効な証明書を発行できますが、注意点として複数階層のサブドメイン（`auth.www.example.com`など）に対しては有効ではありません。その場合は１階層上のサブドメイン（`www.example.com`など）に対する証明書を別途発行する必要があります。
    ![スクリーンショット 2022-11-06 0.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/1107b72f-3805-cb58-bd26-e4b40c3fa441.png)
1. 証明書の一覧ページに遷移するので、作成した証明書IDをクリックします。
1. 証明書の詳細ページに行ったら、「Route53でレコードを作成」をクリックします。
1. ページ遷移後、対象の２つのドメインが選択されているのを確認したら、「レコードを作成」をクリックします。
1. 再度証明書の詳細ページに遷移するので、１分ほど待ってページをリロードするとステータスが「発行済み」になります。
1. AWSのリージョンを「東京（ap-northeast-1）」に戻しておきましょう。

# DNSSECを有効にする

https://aws.amazon.com/jp/premiumsupport/knowledge-center/route-53-configure-dnssec-subdomain/

https://support.google.com/domains/answer/6387342#zippy=%2C%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0-%E3%83%8D%E3%83%BC%E3%83%A0%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88

DNSSECはキャッシュポイズニング攻撃やDNSスプーフィングなどを防ぐためのDNSのセキュリティ設定です。今まではGoogle DomainsがDNSSECの設定を自動でしてくれていましたが、AWSのネームサーバーを使うように変更したので、DNSSECの設定を再度行わなければなりません。以下のようにして設定します。

1. Route53のダッシュボードにアクセスし、「ホストゾーン」を開き、ドメイン名をクリックします。
    ![スクリーンショット 2022-11-06 13.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/559cd5c4-240c-10f6-df6b-f7df9a7e5fcf.png)
1. 「DNSSEC署名」タブを開き、「DNSSEC署名を有効化する」をクリックします。
    ![スクリーンショット 2022-11-06 13.56.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/3400414b-df88-8961-5b93-39f05fe2f604.png)
1. 以下のように設定して、「KSKを作成して署名を有効化する」をクリックします。
    - KSKを作成すると月$1の費用がかかります。
    - 「KSK名の指定」には任意の名前を入力します。
    - 「AWS KMSのカスタマー管理のCMK」は、「カスタマー管理のCMKの作成」を選択します。
    - 「カスタマー管理のCMKの作成」には、任意のキーのエイリアス（名前）を入力します。
    ![スクリーンショット 2022-11-06 14.06.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/07b72af2-40ab-99e9-240a-68a8a099cc21.png)
1. 遷移先のページで「DSレコードを作成するための情報を表示」をクリックします。
    ![スクリーンショット 2022-11-06 14.23.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/83d478ae-1bb9-4792-9a9e-f2918346d197.png)
1. 表示されたページ上の「別のドメインレジストラ」を開き、「キーのタグ」「ダイジェストアルゴリズム」「ダイジェストアルゴリズムのタイプ」「ダイジェスト」「署名アルゴリズム」「署名アルゴリズムのタイプ」の値があることを確認します。
1. 先ほどと同じようにGoogle Domainsの「DNS」ページを開き、「DNSSEC」の「レコードを管理する」をクリックします。
    ![スクリーンショット 2022-11-06 14.38.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/9f028605-bcb4-23b6-4b53-31ee8b74d8f6.png)
1. 以下の値を入力し、「保存」をクリックします。
    - 「キータグ」には先ほどAWS上で確認した「キーのタグ」を入力します。
    - 「アルゴリズム」には、「署名アルゴリズムのタイプ」の番号のものを選択し、念のため選択したアルゴリズム名と「署名アルゴリズム」の値が一致するか確認します。
    - 「ダイジェスト タイプ」には、「ダイジェストアルゴリズムのタイプ」の番号のものを選択し、念のため選択したダイジェストタイプ名と「ダイジェストアルゴリズム」の値が一致するか確認します。
    - 「ダイジェスト」には、先ほど確認した「ダイジェスト」の値を入力します。

# Google Workspaceのメールを使えるようにする
もしGoogle Workspaceを使用している場合、カスタムネームサーバーを使用するように変更すると、そのままではメールが届かなくなってしまいます。メールが届くようにするには、MXレコードをAWS Route53のホストゾーンに追加する必要があります。以下にその手順を示します。

1. Google Domainsの「DNS」ページにアクセスし、「デフォルトのネームサーバー」のタブを開き、「ネームサーバー」のMXレコードの「データ」の部分をコピーします。
    ![スクリーンショット 2022-11-10 15.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/847f572d-9ed7-2dad-d1c4-3b3c01c4f2eb.png)
1. AWSのRoute53のダッシュボードにアクセスし、「ホストゾーン」に行き、「ドメイン名」をクリックします。
    ![スクリーンショット 2022-11-10 15.54.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/0e9f8a3c-034a-3a85-00a5-7ac9a3d36f93.png)
1. 「レコード」タブを開き、「レコードを作成」をクリックします。
    ![スクリーンショット 2022-11-10 15.56.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/e2548cd2-25f2-31a3-370b-cc55b2550fae.png)
1. 「レコードタイプ」で「MX」を選択し、「値」にGoogle Domainsにてコピーした「データ」の値を貼り付けし、「TTL」は3600秒（1時間）を選択、「ルーティングポリシー」は「シンプルルーティング」を選択し、「レコードを作成」をクリックします。
    ![スクリーンショット 2022-11-10 15.58.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/bf04664d-77a6-c6ba-2c29-aaf0569dc684.png)
1. [Google Workspace で Gmail を使用できるようにする](https://support.google.com/a/answer/140034?hl=ja)の「設定ツールを開く」という青いボタンを押し、「Gmailが有効になりました」という表示がされたらOK。「テストメールを送信」を押してテストしてみる
    ![スクリーンショット 2022-11-10 16.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/9671c308-f8a7-c6bf-5006-8f2aebdd1ceb.png)
    ![スクリーンショット 2022-11-10 16.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/d625d625-f608-292d-53ce-c4f52089ff73.png)

# S3 + CloudFrontを使用して静的サイトを作成
## 構成の種類
CloudFrontとS3で静的サイトを作成する場合、ウェブサイトエンドポイントを使う方法とREST APIエンドポイントを使う方法の２通りの構成方法があるようです。それぞれについては以下の記事が参考になります。

この記事で以下のように述べられているように、今回はREST APIエンドポイントを使った構成方法で作成します。
> 個人的には「まずはREST APIを使うパターンで設計し、インデックスドキュメントなどの機能が必要で構成をシンプルにまとめたい場合にのみ静的ウェブサイトホスティングを使う」のが良いのかな、と、いまのことろ考えています。

https://dev.classmethod.jp/articles/s3-cloudfront-static-site-design-patterns-2022/

## 1. S3のバケットを作成する
1. S3のダッシュボードに行き、「バケットを作成」をクリックします。
    ![スクリーンショット 2022-11-01 16.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/c60505c7-f673-3018-9a29-505e81a15c22.png)
2. 作成画面にて、以下のように設定を行います。
    ### 一般的な設定
    ![スクリーンショット 2022-11-01 17.25.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/c4acf811-f1f5-d936-d78d-2f1f4566499f.png)

    #### バケット名
    任意の名前を入力します。
    
    #### AWSリージョン
    主にアクセスされるであろう場所と地理的に一番近いリージョンを設定することが望ましいです。

    #### 既存のバケットから設定をコピー
    既にバケットを作成していて、そのバケットの設定をコピーしてきたい時に使います。やりたければ「バケットを選択する」をクリックして設定をコピーしたいバケットを指定します。ここでは使いません。

    ### オブジェクト所有者
    ![スクリーンショット 2022-11-01 17.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/2aefa672-da04-93cb-4a6e-0d9f2476cf72.png)

    原則「ACL無効」を選択すべきようです。S3のアクセス制御は原則としてポリシーを使って行うべきで、ACL（アクセスコントロールリスト）を使って行うべきではないようです（以下の記事を参照）。

    [S3のアクセスコントロールリスト(ACL)の基礎を学ぼう](https://dev.classmethod.jp/articles/amazon-s3-acl-basics/)

    [何が嬉しい？S3 Object ACL無効化 - 聞いた後、速攻で忘れていい知識をお届けします -](https://speakerdeck.com/takashi_toyosaki/he-gaxi-sii-s3-object-aclwu-xiao-hua-wen-itahou-su-gong-dewang-reteiizhi-shi-woojie-kesimasu)
    
    ### このバケットのブロックパブリックアクセス設定
    ![スクリーンショット 2022-11-01 17.29.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/4273bb05-5fe1-4fac-6bcb-c04e3c98d352.png)

    「パブリックアクセスをすべてブロック」を選択します。含まれている項目を見るとわかるように「パブリックアクセスをすべてブロック」を選択するとACLを使ったアクセスも全て拒否してくれます。こうすることでACLに誤った設定をしてしまい気づかないうちにバケットやその中身のオブジェクトが全世界から自由にアクセス可能になっていたなんて事態を防ぐことができます。前述したように基本的にACLを使ってアクセス制御することはないので事故をなくすためにも「パブリックアクセスをすべてブロック」を選択しときましょう。

    加えて今回のREST APIエンドポイントを使った構成の場合、S3へのアクセスはCloudFrontからのみに限定される（前述した『[CloudFrontとS3で作成する静的サイト構成の私的まとめ](https://dev.classmethod.jp/articles/s3-cloudfront-static-site-design-patterns-2022/)』に構成図が載ってます）のでそもそもパブリックアクセスは必要ありません。

    ### バケットのバージョニング
    ![スクリーンショット 2022-11-01 17.29.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/046d4683-9ee9-048a-566a-02517aecc7d5.png)

    まずバケットのバージョニングとは何かということから説明しましょう。例えば`dog.jpg`という犬の画像がバケットに入っているとします。これを誰かが`dog.jpg`という画像名はそのままで、猫の画像に変更してしまいました。このとき、バージョニングを有効にしていると、たとえ`dog.jpg`が猫の画像に変更されたとしても前のバージョンの`dog.jpg`（つまり犬の画像）は古いバージョンとして残ります。バージョニングを無効にしている場合は`dog.jpg`が猫の画像に変更されてしまったら元の犬の画像は無くなってしまいます。

    削除の場合も同様です。たとえ`dog.jpg`を削除したとしても削除フラグという印を`dog.jpg`につけて削除扱いにするだけで実際には`dog.jpg`は削除されません（これを論理削除と言います）。そのため、バージョニングを有効にしておくと、間違ってバケット内のオブジェクトに変更や削除を行ったとしても前のバージョンが保持されているので復元が簡単になるということです。

    ただ、注意点としては変更しても前のバージョンが保持されたり、削除しても削除扱いにするだけで実際には削除しないため、意図せずファイル容量が増えてその分コストがかかってしまうといったことが考えられます。個人で使用する分にはそれほど問題にはならないでしょうから、ここでは「有効にする」を選択します（その方が勉強になるので）。より詳しく知りたい人は以下の記事が参考になります。

    [絵で見て 3分でおさらいする Amazon S3 のバージョニングとライフサイクル](https://dev.classmethod.jp/articles/3minutes-s3-versioning-lifecycle/)

    ### タグ
    ![スクリーンショット 2022-11-01 17.57.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/9b2cbd16-88f8-1adb-4390-f86c8f09ae7f.png)

    このバケットにタグをつけることで後でAWS全体でコスト等を可視化したり、検索することが容易になります。今の段階では必要ないと思うので、後になって使用するAWSのサービスが増えてどこでコストがかかってるのか知る必要が出てきた時につければいいでしょう。なのでここでは何もタグはつけません。

    ### デフォルトの暗号化
    ![スクリーンショット 2022-11-01 17.58.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/c3c70e7a-2c97-ba2d-e070-e9c2a58d9ece.png)

    これは、バケットにオブジェクトを保存する際に暗号化をするかどうかの設定です。暗号化することのメリットとしては、第三者がS3のオブジェクトに直接アクセスしたとしても暗号化されているので情報が流出しづらくなります。デメリットとしては、暗号化は重い処理なので、その分、パフォーマンスが落ちます。
    
    [S3デフォルト暗号化によるパフォーマンスを検証してみた](https://blog.jicoman.info/2018/06/s3-default-encrytion-performance/)

    暗号化する場合は、暗号化に使用するキーが２種類あるので選択する必要があります。それぞれの違いと使い分けについては以下の記事が参考になります。
    
    [SSE-S3とSSE-KMSの違いを知る](https://ktrysmt.github.io/blog/difference-between-sse-s3-and-sse-kms/)

    今回はバケット内のオブジェクトは静的サイト上で公開するわけなので、特に暗号化するメリットはありません。よってここでは「無効にする」を選択します。

    ### 詳細設定
    ![スクリーンショット 2022-11-01 18.07.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/f917bb9a-1a87-57d2-9dd6-7a1059064b9f.png)

    「オブジェクトロック」を有効にするとたとえrootユーザーであってもバケット内のオブジェクトを変更したり、削除することができなくなります（有効にすると自動的に「バケットのバージョニング」も有効になります）。これは法律等によって必要な時にのみ使うもので、通常であれば使う必要は全くありません。なので「無効にする」を選択しましょう。詳しくは以下の記事が参考になります。
    
    [Amazon S3のオブジェクトロック機能についてあらためて調べてみた](https://dev.classmethod.jp/articles/amazon-s3-object-lock-research/)

3. 上記の設定が終わったら「バケットを作成」をクリックします。
    ![スクリーンショット 2022-11-01 18.07.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/b2d9134e-55d4-53a2-a7e3-93c420f4ee7b.png)

4. 作成後はバケットの一覧ページに行くと思うので、先ほど作成したバケットの名前をクリックします。
    ![スクリーンショット 2022-11-01 18.13.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/ca9adbae-1a0e-3d7b-1543-b6e2dd1ac805.png)

5. バケットの詳細画面に行きます。ここでバケットの設定を確認したり、変更することができます。
    - 「プロパティ」タブの「静的ウェブサイトホスティング」項目で「静的ウェブサイトホスティング」が「無効」になっていることを確認します
    - 「アクセス許可」タブの「ブロックパブリックアクセス」項目で「パブリックアクセスをすべてブロック」が「オン」になっていることを確認します
    ![スクリーンショット 2022-11-01 18.16.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/670209b9-56bd-8f4e-c1a5-0e3ac7d1afd3.png)
6. ローカルにて以下の内容の`index.html`を作成します
    ```html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>Hello, World!</h1>
    </body>
    </html>
    ```
7. バケットの詳細画面にて「オブジェクト」タブを開き、先ほど作成した`index.html`をドラッグ＆ドロップします
    ![スクリーンショット 2022-11-05 15.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/d7bfecfd-2bde-1b08-b20c-db8866038f51.png)
8. アップロード画面に行くので、「アップロード」をクリックします
    ![スクリーンショット 2022-11-05 15.56.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/60df7e74-2a35-af2e-f49a-ed6130a6846e.png)

## 2. CloudFrontを作成する
### 2-1. 「セキュリティ」の設定を行う
1. CloudFrontのダッシュボードに行き、「オリジンアクセス」をクリックします
    ![スクリーンショット 2022-11-05 16.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/82fe95f1-a8ec-1cfc-b2a7-e479412b74d0.png)
1. 「コントロール設定」タブの「コントロール設定を作成」をクリックします
    - [Amazon CloudFront オリジンアクセスコントロール（OAC）のご紹介](https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/)の通り、オリジンアクセスアイディンティティ（OAI）は非推奨になっています。
    ![スクリーンショット 2022-11-05 16.10.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/5113ed51-b394-758b-cd7a-fab51f3a80d0.png)
1. 「名前」に任意の名前を入力し、「設定」は「署名リクエスト」を選択し（「認証ヘッダーを上書きしない」は選択しません）、「作成」をクリックします
    - [Amazon S3 オリジンへのアクセスの制限](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)に書いてあるように、OACはユーザーがオリジンであるS3のコンテンツに直接アクセスしたり、意図しないCloudFrontディストリビューションを介してコンテンツにアクセスすることを防ぎ、ユーザーが指定されたCloudFrontディストリビューションを介してのみバケット内のコンテンツにアクセスできるように制御するものです。

### 2-2. ディストリビューションの作成

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-creating.html

1.  「ディストリビューション」に行き、「ディストリビューションを作成」をクリックする。
    - これ以下の設定については前述した[Amazon CloudFront オリジンアクセスコントロール（OAC）のご紹介](https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/)に書かれている内容をもとにしています。
    ![スクリーンショット 2022-11-05 16.22.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/68947d25-1f09-43b8-f21f-1e84b186f75e.png)
1. 以下のように「オリジン」の設定をします。
    - 「オリジンドメイン」は作成したS3のドメインを選択
    - 「オリジンパス」は入力しない
        - [オリジンのパス](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html?icmpid=docs_cf_help_panel#DownloadDistValuesOriginPath)が参考になります
        - もちろんパスを追加したければ任意のパスを入力してください
    - 「名前」は自動で入力された内容のままにするか任意の名前を入力
    - 「S3 バケットアクセス」は「Origin access control settings」を選択
    - 「Origin access control」は先ほど作成したコントロール設定を選択
    - 「オリジンシールドを有効にする」は「いいえ」を選択
        - 「オリジンシールドを有効にする」はキャッシュのヒット率を高めてくれたりして、可用性を高めるのに役立ちますが、料金がかかるので、そこまでアクセス数の見込めない個人サイトであれば「いいえ」を選択するのがいいかなと思います。

    ![スクリーンショット 2022-11-05 16.28.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/5e2b83dc-eb0d-a679-9420-d08b22fab502.png)
1. 「デフォルトのキャッシュビヘイビア」の設定をする
    - 「パスパターン」はそのままにします。
        - 「パスパターン」は、キャッシュを行うリクエストのURIパスのパターン
    - 「オブジェクトを自動的に圧縮」は「Yes」を選択する
        - [圧縮ファイルの供給](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html?icmpid=docs_cf_help_panel)によると、「Yes」を選択すると、ユーザーにコンテンツを配信する際に、CloudFrontはコンテンツを圧縮してユーザーに送ってくれるので、サイトの表示時間が速くなる可能性がある。
        - また、CloudFront のデータ転送コストは供給されたデータの総量に基づくため、圧縮オブジェクトを処理する方が、非圧縮オブジェクトを供給するよりもコストが安くなる可能性がある
    - 「ビューワープロトコルポリシー」は「Redirect HTTP to HTTPS」を選択する
        - [ビューワーと CloudFront 間の通信で HTTPS を必須にする](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https-viewers-to-cloudfront.html)が参考になります。
        - 「HTTP and HTTPS」を選択した場合、ユーザーはHTTPとFTTPSのどちらを使ってもCloudFrontからコンテンツを取得できますが、わざわざREST APIエンドポイントを使ったメリットがなくなるのでやめときましょう。
        - 逆に「HTTPS only」を選択した場合、ユーザーがHTTPでCloudFrontにリクエストを送ると403が返ってきますので、HTTPSで通信しないとユーザーはコンテンツを閲覧できません。
        - 「Redirect HTTP to HTTPS」を選択した場合、ユーザーがHTTPでCloudFrontにリクエストを送るとHTTPSにリダイレクトするので、ユーザーは強制的にHTTPS通信することになります。この方法だとHTTPでリクエストされた場合、HTTPSにリダイレクトされるので二重の料金がかかってしまいますが、たとえHTTPで通信してしまってもエラーになることはないので、「HTTPS only」に比べてUXを下げずに済みます。なので「HTTPS only」と「Redirect HTTP to HTTPS」のどちらを選ぶかは好みですが、今回は「Redirect HTTP to HTTPS」を選びました。
    - 「許可される HTTP メソッド」は「GET, HEAD」を選択します
        - 今回作成するのは静的サイトなので「GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE」は選択する必要がないのはわかると思います。
        - 「GET, HEAD, OPTIONS」についてですが、OPTIONSメソッドはCORSのプリフライトリクエストの際に使用するメソッドです。なので、今回のような静的サイトでは必要ありません。[OPTIONSメソッドが気になったのでCORSとプリフライトリクエストについて少し調べました](https://woshidan.hatenablog.com/entry/2018/11/26/215356)が参考になります。
    - 「ビューワーのアクセスを制限する」は、プライベートコンテンツとして限定公開したいわけでなければ「No」を選択します。
    ![スクリーンショット 2022-11-06 11.56.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/69d8fdce-bd1f-1403-77ae-219cab05db1b.png)
    - 「キャッシュキーとオリジンリクエスト」は「Cache policy and origin request policy」を選択し、「キャッシュポリシー」には「CachingOptimized」を選択します。「オリジンリクエストポリシー」はお任せします。
        - キャッシュについては自分の理解が追いついてないので、後日アップデートできたらと思います。
    - 「追加設定」の「スムーズストリーミング」は「No」を選択します。
        - [ディストリビューションを作成または更新する場合に指定する値](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%BA%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%9F%E3%83%B3%E3%82%B0,-Microsoft%20Smooth%20Streaming)によると、Microsoft Smooth Streaming 形式のメディアファイルを配信するが、IIS サーバーがない場合はYesを、Microsoft Smooth Streaming 形式のメディアファイルを配信するためのオリジンとして使用する Microsoft IIS サーバーがある場合、または Smooth Streaming メディアファイルを配信しない場合は、Noを選択すると言っているので、今回は「No」を選択します。スムーズストリーミングについてより詳しく知りたい人は[スムーズ ストリーミング 入門](https://learn.microsoft.com/ja-jp/iis/media/smooth-streaming/smooth-streaming-primer)が参考になります。
    - 「フィールドレベル暗号化」はそのままにします。
        - 選択できない状態になっているはずです。この項目は「ビューワープロトコルポリシー」にて「HTTPS only」を選択し、「許可されたHTTPメソッド」で「GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE」を選択しないと選択できるようになりません。フィールドレベル暗号化とはユーザーがPOSTリクエストでデータをアップロードする際にCloudFrontが公開鍵を用いて暗号化し、秘密鍵を持つアプリケーションコンポーネントのみが復号できるようにすることでデータをずっと保護した状態にします。なので常にHTTPS通信を使用し、POSTとPUTリクエストを利用できる状態にしないと「フィールドレベル暗号化」を有効化できないのです。
    - 「リアルタイムログを有効にする」は「No」を選択します。
        - これを有効にするとCloudFrontがデータを受信してから数秒以内にディストリビューションが受信したリクエストに関する情報が取得できるようになります。リアルタイムログは、Amazon Kinesis Data Streams で選択したデータストリームに配信されます。今回は必要ないので「No」を選択します。

    ![スクリーンショット 2022-11-05 20.59.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/a7be0779-cba8-2e1f-d5c8-bc116452de6f.png)

4. 「関数の関連付け」
    - ユーザーに近いエッジで実行できる関数（エッジ関数）を設定できます。エッジ関数はCloudFront FunctionsとLambda@Edgeの2つのタイプから選択できます。
    - ここでは何も設定しません。[エッジで爆速コード実行！CloudFront Functionsがリリースされました！](https://dev.classmethod.jp/articles/amazon-cloudfront-functions-release/)とか参考になりそうです。

5. 「設定」
    - 「料金クラス」は「すべてのエッジロケーションを使用する」を選択します。
        - その分高くなるので、心配なら「北米、欧州、アジア、中東、アフリカを使用」を選択してもいいと思います。私はそこまでアクセスされないならあまり関係ないかなと（憶測）思って、せっかくCloudFront使うならと「すべてのエッジロケーションを使用する」にしました。
    - 「AWS WAF ウェブ ACL」は何も選択しません。
        - WAFを使っている場合は選択すればいいと思います。
    - 「代替ドメイン名 (CNAME)」に使用したドメイン名を入力します。
    - 「カスタムSSL証明書」は前に作成したものを選択します。もし表示されない場合は証明書をバージニア北部以外のリージョンで作ってしまったのかもしれません。「レガシークライアントサポート」はオフのままで、「セキュリティポリシー」は推奨されているものを選択します。
    - 「サポートされているHTTPバージョン」は「HTTP/3」も含め全部有効にしましょう。せっかくワンクリックで有効にできて料金も変わらずにHTTP/3を利用できるのに使わない手はないです。
        - ただ既存のサービスがある場合は影響が出る場合があるのでもう少し調べたほうがいいです。[これとか](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%82%8B%20HTTP%20%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3,-%E3%83%93%E3%83%A5%E3%83%BC%E3%83%AF%E3%83%BC%E3%81%8C%20CloudFront)
    - 「デフォルトルートオブジェクト」は例えばユーザーが`https://example.com/`とリクエストしてきた時にどのコンテンツを返すかということです。設定しないと`https://example.com/`とリクエストしてきた時にディストリビューション内のコンテンツが公開されちゃいます。無難に前に作成した`index.html`とかを入力すればいいんじゃないでしょうか。注意点として`/`は含められません。オブジェクト名だけで大丈夫です。詳しくは[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88,-%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%82%E3%83%93%E3%83%A5%E3%83%BC%E3%83%AF%E3%83%BC%E3%81%8C)に書いてあります。
    - 「標準ログ記録」は「オン」でも「オフ」でもどっちでもいいです。「オン」にするとCloudFrontがオブジェクトに対するリクエストの情報をログに記録して、そのログファイルをS3バケットに保存してくれます。ログ出力自体に料金はかからないですが、ログファイルはS3に保存されるのでその分は課金されます。僕はログ見るの好きなので「オン」にします。「オン」にするとログを保存するバケットを選択する必要がありますが、ログ保存用のバケットに関しては別途作ったほうがいいです。ログを見られるのはセキュリティ上あまりよろしくないので。ログ用のバケットを作成する際は基本的にはこの記事で作成した設定通りでいいのですが、「オブジェクト所有者」のところだけ「ACL有効」を選択してください。そうしないとCloudFrontがログを保存できなくなるようです。ログが保存できない場合は 「ディストリビューションを作成」をクリック時にエラーが出て作成されません。逆に言えば問題なく作成された場合はログ保存は問題なくできることがわかります。詳しくは[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,%E6%B3%A8%E8%A8%98,-Amazon%20S3%20%E3%83%90%E3%82%B1%E3%83%83%E3%83%88)を見てください。
    - 「ログのプレフィックス」は任意のプレフィックスを入力します。ちなみに見やすくなるので末尾に`/`をつけたほうがいいと[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E6%9C%AB%E5%B0%BE%E3%81%AE%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%20(/)%20%E3%81%AF%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%99%E3%81%8C%E3%80%81%E3%83%AD%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%8F%82%E7%85%A7%E3%82%92%E5%AE%B9%E6%98%93%E3%81%AB%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AB%E3%81%93%E3%82%8C%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)では書かれています。
    - 「cookieのログ作成」は「オフ」にします。[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=Amazon%20S3%20%E3%81%AF%20Cookie%20%E3%82%92%E5%87%A6%E7%90%86%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%E3%81%97%E3%81%9F%E3%81%8C%E3%81%A3%E3%81%A6%E3%80%81%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%20Amazon%20EC2%20%E3%81%BE%E3%81%9F%E3%81%AF%E4%BB%96%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E3%82%82%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E9%99%90%E3%82%8A%E3%80%81%5BCookie%20Logging%20(Cookie%20%E3%83%AD%E3%82%B0%E8%A8%98%E9%8C%B2)%5D%20%E3%81%AE%E5%80%A4%E3%81%AB%20%5BOff%20(%E3%82%AA%E3%83%95)%5D%20%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)では、S3はCookieを処理しないので、ディストリビューションにEC2や他のカスタムオリジンが含まれていない限り、基本的に「オフ」にすることがいいと書かれています。
    - 「IPv6 を有効にする」は「オン」にします。[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,IPv6%20%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B,-IPv6%20%E3%81%AF%E3%80%81IP)を読む限り、今までの設定でIPv6が有効になるかどうかはちょっと怪しいですが、有効にしたところで害はないのでとりま有効にしときます。
5. 「ディストリビューションを作成」をクリック
5. 遷移先のページで下記のようなポップアップが表示されるので、「ポリシーをコピー」をクリック後、「S3バケットの権限に移動してポリシーを更新する」をクリックします。
    ![スクリーンショット 2022-11-06 1.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/143f4635-3d37-18af-89d3-7a32e45395c6.png)
5. 「バケットポリシー」にて「編集」を押し、先ほどコピーしたポリシーを貼り付けて保存します。
    - コピーしたポリシーにはS3からオブジェクトを読み取る権限（`s3:GetObject`）しかついてないので、もしS3へのオブジェクトのアップロードを行いたい場合はポリシーに`s3:PutObject`を追加する必要があります。
    ![スクリーンショット 2022-11-06 1.15.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/908e6b1f-6f42-cf84-6e34-d0ef4e63b003.png)

## 3. 独自ドメインとCloudFrontディストリビューションを紐づける
1. Route53のダッシュボードに行き、「ホストゾーン」にアクセスし、前に作成したホストゾーンのドメイン名をクリックします。
    ![スクリーンショット 2022-11-06 12.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/a88296c5-5ad0-9cae-638a-627038e32092.png)
1. 「レコードを作成」をクリックします。
1. 以下のように設定して、「レコード作成」をクリックします。
    - ２枚目の画像のような画面が表示される人は「クイック作成へ切り替える」を選択します。どちらの画面で設定しても変わらないですが、クイック作成の方が設定項目がまとまって表示されているので設定しやすいです。
    - 「レコード名」は自分の使用したいサブドメインを入力してください。サブドメインを使いたくない場合は空白にします。
    - 「レコードタイプ」は「A」を選択します。
    - 「エイリアス」はオンにします。
    - 「トラフィックのルーティング先」は「CloudFrontディストリビューションへのエイリアス」を選択します。
    - 「ディストリビューションを選択」は先ほど作成したCloudFrontのディストリビューションを選択します。
    - 「ルーティングポリシー」は「シンプルルーティング」を選択します。
        - ルーティングの種類について知りたい人は[Amazon Route 53のルーティングがすごすぎる件](https://zenn.dev/seyama/articles/02118b0914183e)が参考になります。
    ![スクリーンショット 2022-11-06 12.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/cbd1a943-c634-28f5-4d97-0b26f87a5d49.png)
    ![スクリーンショット 2022-11-06 12.17.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/8851b8bc-da96-a0e8-dfb6-6011f04f5c88.png)
1. 一応、IPv6も使えるようになっているので、IPv6用のレコードも作成しましょう。先ほどと同じ要領で、「レコードタイプ」だけ「AAAA」にして新規レコードを作成します。

# おわりに
最後に設定したドメインにブラウザを使ってアクセスしてみましょう。以下のように表示されたらOKです。
![スクリーンショット 2022-11-06 12.29.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/aae58177-3db9-9cf4-e333-6343c3cf99f4.png)

# 【おまけ】 DNSレコードについて
## 名前解決とは
DNS（Domain Name System）は、普段目にするドメインネーム（`www.example.com`など）をIPアドレスに変換する（これを名前解決という）を行うシステムのことです。名前解決はネームサーバー（DNSサーバー）によって行われます。ネームサーバーにドメインネームとIPアドレスが紐づいた情報が登録されています。

## 完全修飾ドメイン（FQDN）とは
実はいつも見ているURL（`www.example.com`など）は完全修飾ドメイン（FQDN）と呼ばれるもので、ドメイン名（`example.com`など）とホスト名（`www`など）から構成されます。FQDNにはそれぞれIPアドレスが割り当てられています。違うサブドメイン同士で同じIPアドレスを付けることも可能です。例えば`www.example.com`と`example.com`に同じIPアドレスが割り当てられている場合は、どちらのURLをリクエストしても同じリソースが表示されます。

FQDNとは省略されていないドメインという意味なので、例えばホスト名のないドメイン（`example.com`など）であってもIPアドレスが割り当てられている場合はFQDNです。逆にホスト名のないドメイン（`example.com`など）にIPアドレスが割り当てられておらず、ホスト名のあるドメイン（`www.example.com`など）にのみIPアドレスが割り当てられている場合は、ホスト名のないドメイン（`example.com`など）はそれ自体は存在しないドメインなので、省略されたドメインと見做され、FQDNとは呼びません。ただ狭義には、ルートドメインまで記されてないと（`www.example.com.`など）FQDNではないという意見もあります。

## DNSレコードタイプについて
Route53の「ホストゾーン」にアクセスし、ホストゾーンのドメイン名をクリックすると、「レコード」タブにレコード情報が表示されていると思います。この記事の通りに進めていた場合、5つのレコードが存在しているはずです。レコードには様々なタイプがあります。「タイプ」列を見ると、それぞれ「A」、「AAAA」、「NS」、「SOA」、「CNAME」と表示されていると思います。

Aレコードは、IPｖ4において、ホスト名とグローバルIPアドレスの紐づけを定義するレコードです。このレコードをもとにクライアント側はFQDNに紐づくIPアドレスを取得し、名前解決します。CloudFrontは固定IPアドレスを持たないので、値にはグローバルIPアドレスではなく、CloudFrontが指定されています。その時に応じて、グローバルIPアドレスをAWS側でよしなに指定してくれるということです。

AAAAレコードは、AレコードのIPv6版です。IPv6において、ホスト名とグローバルIPアドレスの紐づけを定義します。

NSレコードは、このドメインのゾーン情報を管理するネームサーバーが載っているレコードです。例えばクライアント側が`www.example.com`にアクセスしたい場合、`com`のネームサーバーに問い合わせを行うと、`com`のネームサーバーは`example.com`のネームサーバーのIPアドレスを返します。`example.com`のネームサーバーは`www.example.com`のAレコードをもとに`www.example.com`のIPアドレスを返してくれます。

SOAレコードは、ネームサーバーの管理者のメールアドレスなどの情報を持ちます。IETFによって定義されているレコードで必須です。

CNAMEレコードは、IPアドレスに別名をつけるレコードです。[この記事](https://wa3.i-3-i.info/word12290.html)とかわかりやすいです。