AWS S3で独自ドメインの静的Webサイトを公開してみた

独自ドメインを無料で取得して、AWSで静的Webサイトを公開してみました。
使用したドメイン名は「s3-route53-test.ga」[^1]として話を進めます。

「http\://s3-route53-test.ga」「http\://<span>www</span>.s3-route53-test.ga」にアクセスすると、応答を返すようにします。

[^1]: 実際のドメインではなく例です

# ネットワーク構成
DNSの名前解決は下記のような構成にします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/8cf722b4-9f2b-7fd8-6d0f-7542e47c12cb.png" width=80%>


# 手順
1. 使用可能なドメインを確認
2. Route 53でHosted Zone作成
3. Freenomでドメイン取得
4. S3でバケット作成
5. Route 53でドメインをS3にマッピング
6. 動作確認
7. 撤収

下記サイトを参考にさせていただきました。
確認はしていませんが、1→3→2の順でも可能なようです。
また、ドメイン取得以外は、AWS公式の手順通りに行えば実現可能です。

**[参考資料]**
[例: 独自ドメインを使用して静的ウェブサイトをセットアップする - Amazon Simple Storage Service](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html)
[無料ドメイン(.tk)とRoute53を利用して0円でHTTPS環境を設定してみた ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/mesoko-r53-cdn/)
[無料のドメインを取得する - Qiita](https://qiita.com/teekay/items/135dc67e39f24997019e)
[S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/s3-block-public-access/)
[Dot TKで取得した無料ドメインをRoute 53でホストする - Qiita](https://qiita.com/Ichiro_Tsuji/items/8471fe0b3d4d17cde146)

## 1. 使用可能なドメインを確認
[Freenom](http://www.freenom.com/ja/index.html?lang=ja)を使用しました。
入力欄にドメイン名を入力すると、無料で使えると表示されました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/901d07ca-f7cb-2c82-d2d6-52a3f0ef7b73.png" width=80%>

AWSのRoute 53でもドメインが取得可能ですが、有料なので無料でドメイン取得できるFreenomを使用しました。
Route 53でドメイン取得すると全てをAWSでクローズできてラクなので、いずれはRoute 53で取得する予定です。

## 2. Route 53でHosted Zone作成
取得するドメインのDNSサーバとしてRoute 53を使用します。
3.ドメイン取得よりも先にRoute 53の設定を行う理由は、ドメイン取得の際に使用するDNSサーバを入力することになるからです。
[この記事](https://qiita.com/teekay/items/135dc67e39f24997019e)のように適当なフォワード先を設定するか、デフォルトのDNSサーバを設定しておいて後から修正することも可能なようでした。

#### 2.1. Hosted Zone作成
Route 53から[Create Hosted Zone]を押すと、入力画面が表示されます。
Domain Nameに取得予定のドメイン名を入力して作成します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/897dea1a-372b-a91d-37bc-c2b7146d6cf9.png" width=50%>

- Domain Name：取得予定のドメイン名
- Comment："静的Webサイト公開用" (何でも構わないです)
- Type:Public Hosted Zone

#### 2.2. NSレコードを控える
作成したHosted Zoneを確認すると、NSレコードが4つ登録されています。
登録されているのは、DNSサーバのURLです。
このURLをドメイン取得時に使用します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/f91dd733-0b98-20b5-333f-a6bf0a55b132.png"  width=80%>

## 3. Freenomでドメイン取得

Freenomに戻ってドメイン名を再度入力します。
取得したいドメインを選択し[チェックアウト]を押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/4a217369-4dd9-2ca3-6787-4ec0c0b50853.png" width=80%>

以下の画面で、Route 53で控えたNSレコードのうち2つを入力します。
この画面では2つまでしか入力できませんので、残りの２つは後で設定します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/a91a1269-1b57-395b-c74b-f0a632e50e50.png" width=80%>

ドメイン取得にはユーザー登録が必要です。
Google・FacebookアカウントのOAuthも可能です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/1a8927cd-17ff-a947-d3bc-cf6864b97bf4.png" width=80%>

ドメインが取得できたら、残り2つのDNSサーバを追加します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/84c386b5-f5eb-6ab8-7c0d-13ca230358ad.png" width=80%>


## 4. S3でバケット作成

#### 4.1. バケット作成
Amazon S3より[バケットを作成する]を選択します。
バケット名は3.で取得したドメイン名と同じ「s3-route53-test.ga」にします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/d1bfb7fc-f866-9b4f-57e0-2c6b172cfa80.png" width=80%>

同様の手順で「www.s3-route53-test.ga」バケットも作成します。
「www.s3-route53-test.ga」バケットは、全てのリクエストを「s3-route53-test.ga」にリダイレクトするようにします。なので、4.2, 4.3, 4.4は実施不要です。

#### 4.2. ファイルのアップロード
Webサイト用のファイルをアップロードします。
今回は「index.html」のみをアップロードしました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/9f64f467-ea5b-c04d-b421-93d333f845bf.png" width=80%>

#### 4.3. パブリックアクセス設定の変更
デフォルトの設定では、S3に追加したWebサイトを公開できません。
設定を変更しNo.1以外のチェックを外します。
**セキュリティを保持するための設定なのでチェックを外すときは充分注意してください。**
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/f6dd5561-bfed-e5c3-458b-9e5482463062.png" width=80%>

|No.| 項目             | 変更の理由             |
|:--|:-----------------|:----------------------|
| 1 |新規のパブリック ACL と、パブリックオブジェクトのアップロードをブロックする | ファイルアップロードを先に行えば変更不要 |
| 2 |パブリック ACL を通じて付与されたパブリックアクセスを削除する| Webサイト用のファイルを公開設定にしても非公開になるため |
| 3 | 新規のパブリックバケットポリシーをブロックする | バケット全体を全世界から読取可能に設定しても拒否されるため |
| 4 | バケットにパブリックポリシーがある場合、パブリックアクセスとクロスアカウントアクセスをブロックする | バケットを全世界から読取可能にしても非公開になるため |

#### 4.4. バケットポリシーの変更
Webサイトを全世界から閲覧できるように、バケット全体に全ユーザーの読取可能を設定します。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3-route53-test.ga/*"
        }
    ]
}
```

#### 4.5. 静的ウェブホスティングの設定
「s3-route53-test.ga」バケットの静的ウェブサイトホスティングを有効化します。
エンドポイントのURLにアクセスすると、インデックスドキュメントに設定したコンテンツを表示できるようになります。
インデックスドキュメント欄には先程アップロードした「index.html」を入力します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/7f42bcf6-9a38-efff-71f5-786dbe4b9367.png" width=50%>

試しにエンドポイントのURLにアクセスすると、アップロードしたコンテンツが表示されます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/c3f90ee8-20ad-bb8b-29b6-ab38254706b2.png" width=80%>

「www.s3-route53-test.ga」の静的ウェブサイトホスティングも有効化します。
こちらは、全てのリクエストを「s3-route53-test.ga」にリダイレクトするように設定します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/4a630f08-1331-4e86-a597-a06b1728e05c.png" width=50%>

## 5. Route 53でドメインをS3にマッピング
「s3-route53-test.ga」へのアクセスをS3の「s3-route53-test.ga」バケットへマッピングします。
先程作成したHosted Zoneを開き、[Create Record Set]を押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/22aa97b9-c404-5b0a-5b90-9d595db0d8f2.png" width=50%>

- Name：空欄のまま
- Type：A – IPv4 Address
- Alias Target：S3「s3-route53-test.ga」バケットのエンドポイント
- Routing Policy：Simple

同様に「www.s3-route53-test.ga」用のレコードを追加します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/c61a4c51-01d0-af72-c787-0cd42e58d37d.png" width=50%>

- Name：www
- Type：A – IPv4 Address
- Alias Target：S3「www.s3-route53-test.ga」バケットのエンドポイント
- Routing Policy：Simple

## 6. 動作確認
ブラウザから「http\://s3-route53-test.ga」にアクセスしてアップロードしたコンテンツが表示されることを確認します。
同様に「http\://<span>www</span>.s3-route53-test.ga」にもアクセスして確認します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/345798/d046da97-b143-4352-3045-81ef0fec6916.png" width=80%>

## 7. 撤収
Route 53のHosted Zone、S3にアップロードしたコンテンツはそのままにしておくと課金されるので、今回は削除しました。
2019/01/26時点では、下記料金でした。

- Hosted Zone：0.50 USD/月 (12時間以内に削除すれば無料)
- S3：0.025USD/GB (最初の50TB/月、アジアパシフィック (東京))

[料金 - Amazon Route 53 | AWS](https://aws.amazon.com/jp/route53/pricing/)
[料金 - Amazon S3（クラウドストレージ）｜AWS](https://aws.amazon.com/jp/s3/pricing/)