[JAWS-UG CLI] Route53:#3 静的Webホスティングに独自ドメインを割り当てる

AWS CLIを利用して、静的Webホスティングに独自ドメインを割り当ててみます。


前提条件
========


Route53への権限
---------------

Route53に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

* AWS CLI 1.10.38

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.10.38 Python/2.7.11 Darwin/15.5.0 botocore/1.4.28
```


0. 準備
=======


0.1. Route53へのドメイン委任
----------------------------

あらかじめ、Route53にドメインを委任しておく必要があります。

* 独自ドメインをRoute53に委任する:
  http://qiita.com/tcsh/items/830de9f0ea5618431e7b

```bash:変数の設定(例):
R53_ZONE_NAME='example.jp'
```

hosted zoneのIDを取得します。

```bash:コマンド:
R53_ZONE_ID=$( \
        aws route53 list-hosted-zones \
          --query "HostedZones[?Name == \`${R53_ZONE_NAME}.\`].Id" \
          --output text \
        | sed 's/\/hostedzone\///' \
) && echo ${R53_ZONE_ID}
```

```text:結果(例):
Zxxxxxxxxxxxx
```


0.2. コンテンツバケット(独自ドメイン用)の作成
---------------------------------------------

あらかじめ、S3にコンテンツ公開用のバケットを作成しておく必要があります。

* S3バケットの作成 (独自ドメイン)用:http://qiita.com/tcsh/items/1f707443e667b6b3c8cf

```bash:変数の設定
S3_BUCKET_NAME='<コンテンツバケット名>'
```

```bash:変数の設定
S3_BUCKET_LOCATION=$( \
        aws s3api get-bucket-location \
          --bucket ${S3_BUCKET_NAME} \
          --output text \
) && echo ${S3_BUCKET_LOCATION}
```


0.3. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:コマンド:
aws configure list
```

```text:結果(例)
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile         administrator-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                         ap-northeast-1  env    AWS_DEFAULT_REGION
```

AssumeRoleを利用している場合はprofileが '<not set>'と表示されます。 それ以外のときにprofileが '<not set>' と表示される場合は、以下を実行してください。

```text:変数の設定:
export AWS_DEFAULT_PROFILE=<IAMユーザ名>
```


1. 事前作業
===========


1.1. S3 WebsiteホスティングのHostedZoneId確定
---------------------------------------------

S3のWebsiteホスティングは、リージョン別に固有のHostedZoneIdを持っているので、S3 Web Endpointsの一覧を確認して確定させる必要があります。

S3 Website Endpoints:http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

```bash:コマンド(ap-northeast-1の場合):
S3_HOSTED_ZONE_ID='Z2M4EHUR26P7ZW'
```

```bash:コマンド(us-west-2の場合):
S3_HOSTED_ZONE_ID='Z3BJ6K6RIION7M'
```


1.2. レコードセットの作成
-------------------------

Aliasリソースレコードセットの定義をJSON形式で記述します。

```bash:変数の設定:
R53_RRSET_NAME="www.${R53_ZONE_NAME}"
R53_ACTION=CREATE
R53_RRSET_TYPE=A
FILE_INPUT="${R53_ZONE_NAME}-s3-alias.json"
```

```bash:変数の確認:
cat << ETX

        S3_BUCKET_LOCATION: ${S3_BUCKET_LOCATION}
        R53_ZONE_NAME:      ${R53_ZONE_NAME}
        R53_RRSET_NAME:     ${R53_RRSET_NAME}
        R53_ACTION:         ${R53_ACTION}
        R53_RRSET_TYPE:     ${R53_RRSET_TYPE}
        FILE_INPUT:         ${FILE_INPUT}

ETX
```

```bash:コマンド:
cat << EOF > ${FILE_INPUT}
{
        "Changes": [
          {
            "Action": "${R53_ACTION}",
            "ResourceRecordSet": {
              "Name": "${R53_RRSET_NAME}.",
              "Type": "${R53_RRSET_TYPE}",
              "AliasTarget": {
                "HostedZoneId": "${S3_HOSTED_ZONE_ID}",
                "DNSName": "s3-website-${S3_BUCKET_LOCATION}.amazonaws.com.",
                "EvaluateTargetHealth": false
              }
            }
          }
        ]
}
EOF

cat ${FILE_INPUT}
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
jsonlint -q ${FILE_INPUT}
```

エラーが出力されなければOKです。


2. Route53エイリアスレコードの作成
==================================

Route53エイリアスレコードを作成します。

```bash:変数の確認:
cat << ETX

        R53_ZONE_ID: ${R53_ZONE_ID}
        FILE_INPUT:  ${FILE_INPUT}

ETX
```

```bash:コマンド:
aws route53 change-resource-record-sets \
        --hosted-zone-id ${R53_ZONE_ID} \
        --change-batch file://${FILE_INPUT}
```

```json:結果(例):
      {
          "ChangeInfo": {
              "Status": "PENDING", 
              "SubmittedAt": "2014-05-27T07:56:56.970Z", 
              "Id": "/change/CXXXXXXXXXXXXX"
          }
      }
```


3. 事後作業
===========


3.1. Route53エイリアスレコードの確認
------------------------------------

Route53エイリアスレコードが作成されたことを確認します。

```bash:コマンド:
aws route53 list-resource-record-sets \
        --hosted-zone-id /hostedzone/${R53_ZONE_ID}
```

```json:結果(例):
      {
         "ResourceRecordSets": [
           {
             "AliasTarget": {
                 "HostedZoneId": "Zxxxxxxxxxxxxx",
                 "EvaluateTargetHealth": false,
                 "DNSName": "s3-website-ap-northeast-1.amazonaws.com."
             },
             "Type": "A",
             "Name": "www.example.jp."
           },
           {
             "ResourceRecords": [
                 {
                     "Value": "ns-xxx.awsdns-xx.co.uk."
                 },
                 {
                     "Value": "ns-xxx.awsdns-xx.com."
                 },
                 {
                     "Value": "ns-xxx.awsdns-xx.net."
                 },
                 {
                     "Value": "ns-xxx.awsdns-xx.org."
                 }
             ],
             "Type": "NS",
             "Name": "example.jp.",
             "TTL": 172800
           },
           {
             "ResourceRecords": [
                 {
                     "Value": "ns-xxx.awsdns-xx.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
                 }
             ],
             "Type": "SOA",
             "Name": "example.jp.",
             "TTL": 900
           }
         ]
       }
```

今回作成したRoute53エイリアスレコードの登録内容は、"AliasTarget"ブロックに反映されています。


3.2. Route53上の登録確認
------------------------

Route53にレコードが登録されていることを確認します。

Route53に指定された4つのNSのうち、どれかに問い合わせることで、登録されていることを確認できます。

```bash:コマンド:
R53_NS='<Route53に指定された4つのNSのうちどれかのホスト名>'
```

登録したAレコードが存在するか問い合わせます。

```bash:コマンド:
dig @${R53_NS} a ${R53_RRSET_NAME} | grep ${R53_RRSET_NAME}
```

Aレコードの逆引きを確認すると、S3の名前が引けるはずです。

```bash:コマンド:
dig -x <Aレコードのアドレス>
```


3.3. インターネット上での名前解決確認
-------------------------------------

インターネットに接続されたホストで、登録したRoute53エイリアスレコードが名前解決できることを確認します。

```bash:コマンド:
dig ${R53_RRSET_NAME} |grep ^${R53_RRSET_NAME}
```

```text:結果(例):
      www.example.jp.               60      IN      A       xxx.xxx.xxx.xxx
```


3.4. コンテンツへのアクセス確認
-------------------------------

```bash:コマンド:
echo "http://${R53_RRSET_NAME}/"
```

```text:結果(例):
      http://www.example.jp/
```

ブラウザで上記URLにコンテンツにアクセスできることを確認しましょう。


完了
====

この設定以降は、S3バケットでのコンテンツ更新(s3 syncコマンドなど)だけで静的ウェブサイトの運営が可能になります。