静的サイトをS3に公開 ＆ 独自ドメイン・HTTPS化させる

静的サイトをS3に公開し、独自ドメイン・HTTPS化させる手順を整理します。

# 1. ドメインの設定

まずはドメインの設定です。

## 独自ドメイン取得

独自ドメインを取得します。

## Route53 ドメイン登録 

[Route53 管理画面](https://console.aws.amazon.com/route53/home?region=ap-northeast-1#hosted-zones:)で取得したドメインのホストゾーンを作成します。

自動で生成される「NSレコード」の値を控えます。

```
ns-xxxx.awsdns-xx.co.uk. 
ns-xxxx.awsdns-xx.org. 
ns-xxxx.awsdns-xx.net. 
ns-xxxx.awsdns-xx.com.
```

## ネームサーバ登録

ドメインを購入したサービスの管理画面でネームサーバの設定をします。

*お名前ドットコムの場合は[こちら](https://navi.onamae.com/domain/setting/ns)*

先ほどの「NSレコード」4つをネームサーバに指定します。

# 2. S3セットアップ

続いて、ホスティングサーバとしてS3をセットアップします。

## バケット作成

[S3の管理画面](https://s3.console.aws.amazon.com/s3/home?region=ap-northeast-1#)でバケットを作成します。

「ブロックパブリックアクセス」は静的サイトとして公開するので**全てオフ**にします。

## 静的サイトとして利用

バケット作成後、プロパティタブから「静的ウェブサイトホスティング」を選択して、静的サイトとして使えるようにします。

設定項目は次のとおりです。

* インデックスドキュメント（必須）: `index.html`
* エラードキュメント（必須）: `error.html`

## バケットポリシーの追加

アクセス権限タブから「バケットポリシー」を選択し、次のようにJSONコードでポリシーを追加します。

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

## デプロイ

作成したバケットに `index.html` をアップロードします。

```html
<!DOCTYPE html>
<html>
<head>
  <!-- Standard Meta -->
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

  <!-- Site Properties -->
  <title>YOUR NAME</title>
</head>
<body>
<h1>準備中...</h1>
</body>
</html>
```

アップロードが終われば、`<bucket-name>.s3-website-<AWS-region>.amazonaws.com/index.html` でウェブブラウザからアクセスできます。 

例えば、バケット名が「mybucket」、リージョンが「東京（ap-northeast-1）」の場合は、S3のURLは次のようになります。

```
mybucket.s3-website-ap-northeast-1.amazonaws.com/index.html
```

これでデプロイ自体は完了です。

# 3. 独自ドメイン・HTTPS 対応

最後に、ウェブブラウザから**「独自ドメイン ＆ HTTPS」**でS3にアクセスできるように CloudFront の設定をおこないます。

## AWS Certificate Manager で証明書登録

[AWS Certificate Manager のコンソール](https://console.aws.amazon.com/acm/home?region=us-east-1#/)にて、Route53 に登録したドメインの証明書を取得します。

*（注意）CloudFront で HTTPS 化をする場合、必ず「US EAST」で登録しないといけません。東京リージョンを選ばないように注意しましょう。*

`*.独自ドメイン` と設定すれば、サブドメイン分もまとめて登録できます。

証明書の発行が完了すると、DNS 設定が書かれたCSVファイルをダウンロードできます。

## Route53 に CNAME 追加

ダウンロードした DNS 設定の内容にしたがって、Route53 に CNAME を追加します。

ドメインのホストゾーン画面から「レコード設定の作成」を選択し、次のように設定します。

* 名前: DNS 設定の `Record Name`（例 `_3560a31fe01xxxxxxxxxx`）
* タイプ: `CNAME`
* 値: DNS 設定の `Record Value`（例 `_xxx.acm-validations.aws.`）

## CloudFront の設定

[CloudFront のコンソール](https://console.aws.amazon.com/cloudfront/home?region=ap-northeast-1#)からディストリビューションを追加します。「Web」を選択して、次のように設定していきます。

### Origin Settings

* Origin Domain Name: 本番 S3 バケットを選択
* 以外、デフォルト

### Default Cache Behavior Settings

* Viewer Protocol Policy: Redirect HTTP to HTTPS
* 以外、デフォルト

### Distribution Settings

* Alternate Domain Names (CNAMEs): 本番で利用するドメイン
* SSL Certificat: Custom SSL Certificate（ACM で作った証明書を選択） 
* Default Root Object: `index.html`
* 以外、デフォルト

以上の内容でディストリビューションを作成します。

作成後、CloudFront ディストリビューションの「Domain Name」をコピーします。

## Route53 に CloudFront のエンドポイントを追加

Route53 ホストゾーンの「レコードセットの追加」から、先ほどコピーした「Domain Name」をAレコードとして追加します。

* 名前: 独自ドメイン（もしくはサブドメイン）
* タイプ: A
* 値: CloudFront ディストリビューションの「Domain Name」

ブラウザから独自ドメインを叩いて、S3の静的サイトがHTTPSで表示できればOKです。

## 403, 404エラーに対応

JSコンソールで次のようなエラーが出る場合があります。

```
Failed to load resource: the server responded with a status of 403
```

### 解決方法

CloudFront でエラーページの設定すれば、このエラーを解決できます。

CloudFronnt ディストリビューションの「Error Pages」タブからカスタムエラーレスポンスを作成します。

* HTTP Error Code: 403, 404（2回に分けて作成）
* Customize Error Response: Yes
* Response Page Path: `/`
* HTTP Response Code: 200 OK