[JAWS-UG CLI] Route53:#6 Hosted Zone作成 (CloudFormation)

http://jawsug-cli.doorkeeper.jp/events/14614 でのハンズオン資料です。

CloudFormationを利用して、Route53上に独自ドメインを構築、運用します。

今回は、リソースレコードセットのない、ピュアなHosted Zoneを作成します。
ドメイン取得直後(もしくは新しいサブドメインの作成)の作業として行なうことを想定しています。

注意
======

Route53には無料使用枠がないので、下記の料金がかかります。

* http://aws.amazon.com/jp/route53/pricing/
* 作成から 12 時間以内に削除されたホストゾーンについては無料。


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

* Route53へのフルアクセス権限
* 以下のどちらか。
  * 独自ドメインを保有しており、レジストラに対してWhois情報変更の依頼権限を持っている。
  * 独自ドメインを運用しており、サブドメインの作成ができる。


0. 事前作業
=============

0.1. ドメインの決定
-------------------

Route53に登録するドメインを決めます。

```bash:コマンド:
$ R53_ZONE_NAME=example.com
```

0.2. 変数の定義
------------------

```bash:コマンド:
$ CF_STACK_NAME="route53-`echo ${R53_ZONE_NAME}|sed 's/\./-/g'`-hostedzone"; echo ${CF_STACK_NAME}
$ FILE_CF_TEMPLATE="${CF_STACK_NAME}.template"; echo ${FILE_CF_TEMPLATE}
```

0.3. リージョンの決定
----------------------

CloudFormationスタックが稼動するリージョンをAWS_DEFAULT_REGIONとして設定します。

```bash:コマンド(東京リージョンの例):
$ export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.4. リポジトリの作成
----------------------

ここでは、mercurialでバージョン管理する例を例示します。

```bash:コマンド:
$ mkdir -p ~/_work/aws/project-01
$ cd ~/_work/aws/project-01
$ hg init
$ touch ${FILE_CF_TEMPLATE}
$ hg add ${FILE_CF_TEMPLATE}
$ hg commit -m 'created repository'
```


1. テンプレートの作成
=======================

CloudFormationテンプレートを作成します。 最初はHosted Zoneをレコードセットなしで作成します。

```bash:コマンド:
$ cat << EOF > ${FILE_CF_TEMPLATE}
{
  "AWSTemplateFormatVersion": "2010-09-09",

  "Description": "hosted zone ${R53_ZONE_NAME}",

  "Resources": {
    "DnsZone": {
      "Type": "AWS::Route53::HostedZone",
      "Properties": {
        "Name": "${R53_ZONE_NAME}"
      }
    }
  }
}
EOF
```

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

```bash:コマンド:
$ cat ${FILE_CF_TEMPLATE} | json_verify
```

```text:結果:
JSON is valid
```

invalidとエラーが表示された場合は、jsonlintでどこが壊れているか調べます。

```bash:コマンド:
$ cat ${FILE_CF_TEMPLATE} | jsonlint
```

validate-templateサブコマンドで、簡単な検証ができます。

```bash:コマンド:
$ aws cloudformation validate-template --template-body file://${FILE_CF_TEMPLATE}
```


2. hosted zone作成
===================

2.1. 作成
-----------

実際に、Route53上でhosted zoneを作成します。

```bash:コマンド:
$ aws cloudformation create-stack --stack-name ${CF_STACK_NAME} --template-body file://${FILE_CF_TEMPLATE}
```

```json:結果:
{
  "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/route53-example-com-hostedzone/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
```

2.2. スタックの状況確認
------------------------

```bash:コマンド:
$  aws cloudformation list-stacks \
   | jq -r --arg stackname ${CF_STACK_NAME} '.StackSummaries[] | select(.StackName == $stackname) | .StackStatus'
```

```text:結果:
CREATE_COMPLETE
```

StackStatusが’CREATE_COMPLETE’になっていれば作成は完了です。 (30秒から1分程度かかるようです。)

それ以外が表示されている場合は、下記コマンドでFailedの文字が出ている前後を見て原因を調べます。

```bash:コマンド:
$ aws cloudformation describe-stack-events --stack-name ${CF_STACK_NAME}
```

2.3. スタックの内容確認
------------------------

作成されたスタックの内容を確認します。

```bash:コマンド:
$ aws cloudformation get-template --stack-name ${CF_STACK_NAME}
```

```json:結果:
{
  "TemplateBody": {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Description": "hosted zone example.com",
      "Resources": {
          "DnsZone": {
              "Type": "AWS::Route53::HostedZone",
              "Properties": {
                  "Name": "example.com"
              }
          }
      }
  }
}
```

2.4. コミット
---------------

問題無くHosted Zoneの作成が完了していれば、ここで一旦テンプレートをコミットしておきましょう。

```bash:コマンド:
$ hg commit -m "created hosted zone data (${R53_ZONE_NAME})."
```


3. NSレコードの確認
===================== 

作成したhosted zoneに割り当てられたNSレコードを確認します。

3.1. Hosted Zone IDの取得
---------------------------

```bash:コマンド:
$ R53_ZONE_ID=`aws route53 list-hosted-zones | jq --arg zone_name ${R53_ZONE_NAME} -r '.HostedZones[]|select(.Name |contains($zone_name))|.Id' | sed 's/\/hostedzone\///'` && echo ${R53_ZONE_ID}
```

3.2. NSレコードの取得
----------------------

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

```bash:コマンド:
$ aws route53 get-hosted-zone --id /hostedzone/${R53_ZONE_ID} --query DelegationSet.NameServers --output table
```

```text:結果(例):
-----------------------------
|       GetHostedZone       |
+---------------------------+
|  ns-XXX.awsdns-XX.net     |
|  ns-XXXX.awsdns-XX.co.uk  |
|  ns-XXXX.awsdns-XX.org    |
|  ns-XX.awsdns-XX.com      |
+---------------------------+
```


3.3. BINDへの登録データの作成 (サブドメインの場合)
-------------------------------------------------

BINDのゾーンファイルに登録するNSレコードをコマンドで生成するには、以下のようにします。

```bash:コマンド:
$ for i in `aws route53 get-hosted-zone --id /hostedzone/${R53_ZONE_ID} --query DelegationSet.NameServers --output text`; do echo "${R53_ZONE_NAME}. IN NS ${i}."; done
```


4. whois変更 (独自ドメインの場合)
================================

4.1. whois変更
---------------

Route53に割り当てられたNSレコードのホスト名を、自分のドメインのWhois情報にName Serverとして登録します。

ドメインの管理を委託しているレジストラの管理画面などを利用します。

4.2. whois確認
----------------

自分のドメインのWhois情報にName Server情報が反映されたか確認します。

```bash:コマンド:
$ whois ${R53_ZONE_NAME} | grep 'Name Server'
```

```text:結果(.org):
Name Server:NS-XXXX.AWSDNS-XX.ORG
Name Server:NS-XX.AWSDNS-XX.COM
Name Server:NS-XXX.AWSDNS-XX.NET
Name Server:NS-XXXX.AWSDNS-XX.CO.UK
Name Server:
Name Server:
Name Server:
Name Server:
Name Server:
Name Server:
Name Server:
Name Server:
Name Server:
```

```text:結果(.jp):
[Name Server]                   NS-XXXX.AWSDNS-XX.ORG
[Name Server]                   NS-XX.AWSDNS-XX.COM
[Name Server]                   NS-XXX.AWSDNS-XX.NET
[Name Server]                   NS-XXXX.AWSDNS-XX.CO.UK
```


5. NSレコードの確認
=====================

自分のドメインのNSレコードが、Route53の登録情報と同じであることを確認します。

```bash:コマンド:
$ dig ns ${R53_ZONE_NAME} | grep ${R53_ZONE_NAME}
```

```text:結果:
;example.jp.                  IN      NS
example.jp.           152631  IN      NS      ns-xxxx.awsdns-xx.org.
example.jp.           152631  IN      NS      ns-xxxx.awsdns-xx.co.uk.
example.jp.           152631  IN      NS      ns-xx.awsdns-xx.com.
example.jp.           152631  IN      NS      ns-xxx.awsdns-xx.net.
```


完了
=====

これ以降は、CloudFormationスタックとバージョン管理システムでドメインを管理します。

次の手順として、CloudFormationを利用して、S3上に静的ウェブホスティング(独自ドメイン)用のバケットを構築します。 http://qiita.com/tcsh/items/de8676d836ffe611cc58