AWSでS3/Route53/CloudFrontを使用してWEBサイトを公開する手順を解説

## はじめに
この記事では、AWSを使用してWEBサイトを公開する手順を解説します。
Route53で独自ドメインを取得してS3で公開、CloudFrontで常時SSL化（HTTPS化）までを記載しました。
AWS以外でドメインを取得されている方でも問題ないように書いていますのでご安心ください。

:::note
AWSアカウントの登録方法や設定の説明は省きますが、アカウント登録からされる方はこちらの記事([AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888))がおすすめです。設定する項目が多く大変だと思いますが、IAMユーザーでのログインに切り替えるなどセキュリティ面でとても重要なこともあるので忘れずに行いましょう。
:::

## Route53でドメインを取得
まずはRoute53でドメインを取得しましょう。
![us-east-1.console.aws.amazon.com_route53_v2_home.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/04cc3dd7-13ba-d3a7-2a8e-0642a359baa2.jpeg)
検索窓に`Route53`と入力してダッシュボードを表示し、「ドメインの登録」に登録したいドメイン名を入力して「チェック」をクリックします。

---
![us-east-1.console.aws.amazon.com_route53_v2_home-(1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/f27865e5-ecdc-f6f6-5d3e-85abdd2ee4ba.jpeg)
入力したドメイン名の使用可否がわかり、料金も表示されています。
利用可能であればカートに入れて、「続行」をクリックから個人情報の入力などを終えるとドメインを購入することができます。

## Route53でホストゾーンを作成
ドメインを取得したらRoute53でホストゾーンを作成しましょう。

ホストゾーンは1ゾーン0.5ドル/月です。
26個以降のホストゾーンは0.1ドルに割引、1ゾーンで10,000レコードを超える場合は0.0015ドルの追加課金となります。
[Amazon Route 53 料金表](https://aws.amazon.com/jp/route53/pricing/)
![us-east-1.cons1ole.aws.amazon.com_route53_v2_hostedzones.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/a47d8261-6dde-9865-4bd8-be0082726a7b.jpeg)
Route53のダッシュボードページやサイドバーなどからホストゾーンのページに移動し、「ホストゾーンの作成」をクリックします。

---
![us-east-1.console.aws.ama3zon.com_route53_v2_hostedzones.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/cea917a3-2dc2-3ff0-9bde-53cefd7d6507.jpeg)
「ドメイン名」に取得したドメイン名を入力して「ホストゾーンの作成」をクリックします。

これでホストゾーンの作成が完了しました。

## ホストゾーンとドメインを紐付ける
ドメインの取得とホストゾーンの作成が完了したら、その2つを紐付けましょう。
ホストゾーンのネームサーバーとドメインのネームサーバーを同じ値にすることで紐付けることができます。
この紐付けを先に行っておかないと、これから行うACM証明書の発行ができません。
![us-east-1.consfdsdfsdfole.aws.amazon.com_route53_v2_home.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/8390f9bb-37f5-2b45-823a-bec1bd8b15fb.jpeg)
Route 53のダッシュボードから作成したホストゾーンのページに移動します。
NSとSOA、2つのレコードがあると思います。
このうちNSの「値/トラフィックのルーティング先」に記載されているテキストがホストゾーンのネームサーバーになります。

---
![us-east-1.console.fdsfsdfsdfsdfsaws.amazon.com_route53_v2_home.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/629a79f0-e20d-d45f-2e45-0ab5ed769c81.jpeg)
同じくRoute 53のダッシュボードなどから今度は購入したドメインのページに移動します。
こちらにはドメインに設定されているネームサーバーが記載されています。
「ネームサーバーの追加/編集」からネームサーバーの値がホストゾーンの値と同じになるようにしましょう。

:::note
Route53以外でドメインを購入した方は、ドメインを購入したサービス側でネームサーバーの値をホストゾーンと同じ値に設定してください。
:::

## ACMでSSL証明書を発行する
HTTPS接続をするためにはSSL証明書が必要なので、ACM(AWS Certificate Manager)で証明書を発行しておきます。
証明書の発行は無料です。
![acm_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/ed2b7851-314d-a2c3-5051-d2a51dc1fb89.jpeg)
検索窓に「Certificate Manager」と入力してACMのページに移動します。
画面右上のリージョンを**バージニア北部**に変更してから、「証明書をリクエスト」をクリックします。

:::note warn
リージョンの変更を忘れないように注意しましょう。
バージニア北部以外のリージョンで発行されたACMは、CloudFrontでの作業時に使用できません。
:::

---
![acm_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/df2852de-e045-bdf0-c65d-fa1adb01ea8a.jpeg)
証明書タイプはデフォルトのまま「次へ」をクリックします。

---
![acm_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/29dabf2b-a00a-45e2-8f94-2c2192d97998.jpeg)
「完全装飾ドメイン名」にドメイン名を入力して、そのほかはデフォルトのまま「リクエスト」をクリックします。

---
![acm_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/c9737702-cf63-c00d-96d5-3c1a82565b6a.jpeg)
証明書の発行が完了しました。

### ステータスが保留中の検証から変わらない場合
![acm_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/e6fc6b6d-35ea-478d-7dd5-688849f22767.jpeg)
証明書の発行まではしばらく時間がかかることがありますが、変わらない場合は作成した証明書の詳細ページから「Route 53でレコードを作成」をクリックしてレコードを作成しましょう。
レコード作成後しばらく待つとステータスが発行済みに切り替わります。

時間がかかりそうなら待っている間にS3の設定を行なってしまいましょう。
証明書はS3作業後のCloudFrontで使用します。

## S3でバケットを作成する
S3(Simple Storage Service)はストレージサービスです。
ここにindex.htmlなどの必要なファイルを入れていきましょう。
URLとか気にしないのであれば、S3だけでも公開できちゃいます。

S3はAWSにサインアップしてから12か月は毎月5GBまで無料で使用することができます。
[AWS 無料利用枠](https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all&awsm.page-all-free-tier=1)

無料期間終了後は標準クラスで`0.023USD/GB`となります。
[Amazon S3 の料金](https://aws.amazon.com/jp/s3/pricing/)

では、S3にバケットを作成していきましょう。
![s3_1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/a962385c-8713-63e3-5f71-f8a04021741d.jpeg)
検索窓に「S3」と入力してS3のページを表示し、「バケット作成」をクリックします。

---
![s3_2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/f9d09b4e-a153-5dd9-f183-4d37a2e33c80.jpeg)
バケット名を入力します。

:::note warn
バケット名はドメイン名と完全に同じでなければいけません。
example.comがドメイン名なら、example.comがバケット名になります。
:::

---
![s3_3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/4b3a5215-8971-5c5e-addf-cd6952b96d20.jpeg)
「パブリックアクセスをすべてブロック」のチェックを外します。
チェックを付けたままだとバケット内のファイルを公開できませんので注意してください。
ただ、後から設定で変更することができます。
パブリックアクセスのオフに対する承認チェックボックスにだけチェックを入れて、他はデフォルトのままで大丈夫なので「バケットの作成」をクリックします。

---
![s3_4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/59eaddde-cb59-ed6d-160a-23fbc9814ff1.jpeg)
バケットの作成が終わったら、作成したバケットのページに移動して必要なファイルをS3にアップロードしておきましょう。

## 作成したS3バケットを公開設定する
もう少しS3の設定をしていきます。
![s3_5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/0fab4a8d-84a7-7f11-f28d-67e207dc5c0f.jpeg)
「プロパティ」タブに移動します。

---
![s3_6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/f2fd098f-f424-db96-688d-598dc8a9bdd1.jpeg)
最下部の「静的ウェブサイトホスティング」の編集をクリックします。

---
![s3_7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/6972e1ae-9baa-0c1d-f57c-83ca6ba1c582.jpeg)
「静的ウェブサイトホスティング」は「有効にする」を選択し、
「インデックスドキュメント」にWEBサイトのHTMLファイル名(ここではindex.html)を入力して、「変更の保存」をクリックします。

---
![s3_8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/25d058da-b03b-41f8-bebb-052d679856a0.jpeg)
今度は「アクセス許可」タブに移動して、バケットポリシーの「編集」をクリックします。

---
![s3_9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/22f831b2-ccac-b0ac-5086-336a28cbc494.jpeg)             
ポリシーに下記のコードをコピペします。Resourceのところは作成したバケット名に変更して「変更の保存」をクリックします。

:::note warn
バケットポリシーに何も記入されていないデフォルトの状態で編集画面に行くと、空欄に見えて半角スペースだけが自動で挿入されています。
コピペの方法によっては最初の`{`の前に半角スペースが混入してしまう可能性があり、そうなるとエラーになって保存できませんので注意しましょう。
:::

```json:ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::ここはS3のバケット名/*"
        }
    ]
}
```

これでS3の設定は完了です。

### S3からページが表示できるか確認してみる
![s3_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/b11ca803-a677-97b0-853c-40f9fcff312d.jpeg)
再び「プロパティ」タブに戻って、「バケットウェブサイトエンドポイント」のURLをクリックしてちゃんと設定ができたか確かめてみましょう。
自分のサイトが表示されていれば問題なしです。

:::note warn
index.html内で読み込んでいるパスにhttpが混入していると、そのhttpで読み込んでいるファイルはサイトに反映されないので注意が必要です。読み込むパスは全てhttpsで書きましょう。
:::

## CloudFrontでディストリビューションを作成する
S3だけではURLが`http`から始まっているので、アドレスバーに「保護されていない通信」と出続けてしまいます。
このままだと第三者に悪用される可能性があるので`https`にするためにCloudFrontを使用します。

CloudFrontには無期限の無料枠があり、それを超えるデータ転送やアクセスが発生しなければずっと無料です。
[Amazon CloudFront の料金](https://aws.amazon.com/jp/cloudfront/pricing/)

無料利用枠
* 1 TB のデータ転送 (アウト)
* 1,000 万件の HTTP または HTTPS リクエスト
* 2,000,000 件の CloudFront Function 呼び出し

![cl_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/09aa6b46-4410-41cf-b616-a5764750b3ae.jpeg)
検索窓に「CloudFront」と入力してCloudFrontのページを表示し、「CloudFrontディストリビューションを作成」をクリックします。

---
![cl_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/ab7a992d-f6dd-c02b-d5a0-f11ee9ea6512.jpeg)
「オリジンドメイン」をクリックするとS3で作成したバケットが出てくるので選択します。
そうすると「名前」の欄も自動で埋まります。

---
![cl_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/9205a037-04ef-cbb5-6862-491bd1da5aa9.jpeg)
「ビューワープロトコルポリシー」は「Redirect HTTP to HTTPS」を選択します。
これで`http`のアクセスも`https`にリダイレクトしてくれます。

---
![cl_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/5da54f57-07d4-6d6d-5015-7b95f717e176.jpeg)
「代替ドメイン名（CNAME）」に取得したドメイン名を入力します。
「カスタムSSL証明書」をクリックすると証明書一覧が出てくるので、先ほど作成した証明書を選択します。
選択すると「レガシークライアントサポート」などの新しい設定項目が表示されますがデフォルトのままで良いです。

---
![cl_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/6225935a-cbab-13c9-c7b5-58ba9ad62f39.jpeg)
「デフォルトルートオブジェクト」にはS3のインデックスドキュメントで設定したのと同じファイル名を入力します。
今回の場合はindex.htmlです。
「ディストリビューションを作成」をクリックして作成します。

### CloudFrontからページが表示できるか確認してみる
![cl_6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/e8290da6-5de8-9060-5944-92f0e9847120.jpeg)
ディストリビューションを作成するとデプロイ状態になり、デプロイには数分〜数十分程度の時間がかかります。
デプロイが完了したら、「最終変更日」がデプロイから日付に変わります。

では、この段階で「ディストリビューションドメイン名」に記載されているURLをアドレスバーに入力してみましょう。
S3にアップロードしたページが表示されていれば完了です。
これでS3とCloudFrontを紐付けることができました。

## Route53でホストゾーンとCloudFrontを紐付ける
![route9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/1846f11a-dad0-4ae3-baf4-e20d21727489.jpeg)
いよいよ最後の仕上げです。
再びRoute53に戻って、最初に作成したホストゾーンのページから「レコードの作成」をクリックします。

---
![route10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/6a39c0a7-643d-89e2-0984-fb90033fba1f.jpeg)
「トラフィックのルーティング先」のトグルスイッチをONにして、CloudFrontを選択し、枠が新しく表示されるので作成したCloudFrontディストリビューションを選択して「レコードを作成」をクリックします。

:::note warn
作成したディストリビューションが選択肢として出てこない場合、単純に反映が遅れているだけか、CloudFrontで「代替ドメイン名（CNAME）」の入力が正しくない可能性があります。
:::

:::note
CloudFrontを使用せず公開したい場合はここでCloudFrontではなくS3のエンドポイントを設定すればOKです。
:::

これで全ての作業が終わりました！
取得したドメインをブラウザで入力するとあなたのサイトが表示されます！
（筆者はレコードの作成からサイト反映まで10分程度かかりました）

## さいごに
AWSは専門用語とカタカナばかりで慣れるまでは頭が痛くなりますね…
各サービスのドキュメントに目を通そうとしても、私たちが普段使っている日本語と同じ言語で書かれているとは到底思えません…

作成したポートフォリオの公開などで参考にしていただけたら嬉しいです。

誤字や脱字、発信した情報に間違い等ございましたらご指摘頂けますと幸いです:bow: