AWS Route53 ゾーン作成とDNSレコード追加コマンドメモ

はじめに
===

Amazon Route 53(以下:Route 53と表記)というAWSが提供するマネージド型DNSサービスがございます。

aws-cli(aws route53コマンド)を使用して、 Route 53に新規ゾーンを作成し、AレコードやCNAMEレコードを追加・削除するコマンドをまとめてみました。

コマンドの例として、Route 53に作成するゾーン名はexample.com、ゾーンに追加するAレコードのIPアドレスは198.51.100.10及び198.51.100.11と表記しております。

環境
===

aws-cliはAWS EC2インスタンス(Amazon Linux)で実行する前提で記載しております。

・AWS EC2インスタンス(Amazon Linux)

使用したaws-cliのバージョンは以下になります。

・aws-cli/1.6.8 Python/2.6.9 Linux/3.14.26-24.46.amzn1.x86_64


参考資料
===

Amazon Route 53の詳細については、以下をご参照下さい。

https://aws.amazon.com/jp/route53/

事前準備
===

## (1) EC2インスタンスのIAMロールにRoute 53へのアクセス権限を設定します。

awscliを実行するEC2インスタンスには、IAMロールでRoute 53ゾーン作成権限やDNSレコード更新権限をつけておきます。

ただ、Route 53の新規ゾーン作成やゾーン削除を可能とする強力な権限の付与が必要となりますので、権限を付与するEC2インスタンスはなるべく限定しておいた方が良いと思われます。

```json:IAMロール設定
{
   "Version": "2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":["route53:CreateHostedZone"],
         "Resource":"*"
      },
      {
         "Effect":"Allow",
         "Action":["route53:DeleteHostedZone"],
         "Resource":"arn:aws:route53:::change/*"
      },
      {
         "Effect":"Allow",
         "Action":["route53:GetChange"],
         "Resource":"arn:aws:route53:::change/*"
      }
   ]
}
```

## (2) EC2インスタンスのjqコマンドをインストールします。

aws route53コマンドはjsonファイルを指定してDNSレコード追加・削除を行うので、jsonファイル構文チェック等の為、EC2インスタンスにjqコマンドをインストールしておきます。

```
$ sudo curl -o /usr/bin/jq http://stedolan.github.io/jq/download/linux64/jq && sudo chmod +x /usr/bin/jq
```

Route 53に新規にゾーンを作成する
===

## (3) Route 53に新規ゾーンを作成します。

内部でしか名前解決しないゾーンならば、Route 53のゾーンTypeをPrivateとしてゾーンを作成した方が良いと思いますが、コマンドの確認を兼ねて、今回の例ではゾーンTypeをPublicとして、新規ゾーンを作成してみます。

以下を実行すると、Route 53に新規にゾーンを作成出来ます。

```
$ R53_ZONE_NAME="example.com"
$ R53_ZONE_COMMENT="exampledomain"
$

$ aws route53 create-hosted-zone --name ${R53_ZONE_NAME} --caller-reference `date +%Y-%m-%d_%H-%M-%S` --hosted-zone-config Comment="${R53_ZONE_COMMENT}"
```

Route 53に新規ゾーンが作成された事を確認する
===

## (4) Route 53のゾーン一覧を表示して、新規ゾーンが作成された事を確認します。

以下を実行すると、Route 53に登録しているゾーン一覧を表示出来ます。

```
$ aws route53 list-hosted-zones
```

以下のように新規に作成したゾーン名が表示されれば、ゾーン作成は成功です。

```
{
    "HostedZones": [
        {
　(途中省略)
        },
        {
            "ResourceRecordSetCount": 2,
            "CallerReference": "2014-12-23_23-47-30",
            "Config": {
                "Comment": "exampledomain",
                "PrivateZone": false
            },
            "Id": "/hostedzone/**************",
            "Name": "example.com."
        }
    ]
}
$
```


Route 53に作成したゾーンのHosted Zone IDを取得する
===

## (5) Route 53に作成したゾーンのHosted Zone IDを取得します。

以下を実行すると、先ほど新規作成したゾーンのHosted Zone IDを取得出来ます。
以下の例では取得したHosted Zone IDはZ*************と表記しています。


```
$ R53_ZONE_ID=`aws route53 list-hosted-zones | jq --arg zone_name "${R53_ZONE_NAME}." -r '.HostedZones[]|select(.Name == $zone_name)|.Id' | sed 's/\/hostedzone\///'`
$
```

```
$ echo ${R53_ZONE_ID}
Z*************
$
```

Route 53のゾーンに対して、追加したいDNSレコードをjsonファイルに記述する
===

## (6) Route 53の新規ゾーンへ追加したいDNSレコードを記載したjsonファイルを作成します。

aws route53コマンドでは、jsonファイルに追加・削除したいDNSレコード(AレコードやCNAMEレコード等)を記述する事で、指定したゾーンに対して、DNSレコードを追加・削除出来ます。

以下を実行すると、Route 53の新規作成ゾーンに追加するDNSレコードを記述したjsonファイルを作成出来ます。

```
cat <<EOT > /tmp/create_dns_recordset.json
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "server-001.example.com.",
        "Type": "A",
        "TTL": 1200,
        "ResourceRecords": [
          {
            "Value": "198.51.100.10"
          }
        ]
      }
    },
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "server-002.example.com.",
        "Type": "A",
        "TTL": 1200,
        "ResourceRecords": [
          {
            "Value": "198.51.100.11"
          }
        ]
      }
    },
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "server-cname.example.com.",
        "Type": "CNAME",
        "TTL": 3600,
        "ResourceRecords": [
          {
            "Value": "server-001.example.com."
          }
        ]
      }
    }
  ]
}
EOT
```

## (7) 作成したjsonファイルの構文チェックを行います。

jqコマンドで作成したjsonファイルの構文をチェックします。
以下のようにエラーメッセージが表示されなければ構文は問題ありません。

```
$ cat /tmp/create_dns_recordset.json | wc -l
43
$ cat /tmp/create_dns_recordset.json | jq . | wc -l
43
$
```

なお、生成したjsonファイルの構文に何らかの誤りがある場合、例えばjsonファイルの1行目を意図的に削除し、構文エラーが起きるようにして、jqでパースすると、以下のようにエラー行が表示されます。

```
$ sed -i -e '1,1d' /tmp/create_dns_recordset.json
$

$ cat /tmp/create_dns_recordset.json | wc -l
42
$ cat /tmp/create_dns_recordset.json | jq . | wc -l
parse error: Expected string key before ':' at line 1, column 12
1
$
```

Route 53に作成したゾーンに対して、DNSレコードを追加する
===

## (8) Route 53に作成したゾーンに対して、DNSレコードを追加します。

以下を実行すると、Route 53に作成したゾーンに対して、DNSレコードを追加出来ます。
先ほど作成したjsonファイル(/tmp/create_dns_recordset.json)に記述したDNSレコードがゾーンに追加されます。

```
$ aws route53 change-resource-record-sets --hosted-zone-id ${R53_ZONE_ID} --change-batch file:///tmp/create_dns_recordset.json
```

以下のように表示されれば、ひとまずコマンド自体は正常終了です。

```
{
    "ChangeInfo": {
        "Status": "PENDING",
        "SubmittedAt": "2014-12-23T15:35:24.690Z",
        "Id": "/change/**************"
    }
}
```

Route 53に作成したゾーンに対して、DNSレコードが追加されたか確認する
===

## (9) Route 53に作成したゾーンに対して、DNSレコードが追加されたか確認します。

以下を実行すると、Route 53のゾーンに登録しているDNSレコード一覧を表示出来ます。

```
$ aws route53 list-resource-record-sets --hosted-zone-id ${R53_ZONE_ID}
```

以下のように追加対象として指定したDNSレコードが表示されていれば、Route 53のゾーンにDNSレコードが追加された事になります。

```
{
    "ResourceRecordSets": [
        {
            "ResourceRecords": [
                {
                    "Value": "ns-617.awsdns-13.net."
                },
                {
                    "Value": "ns-497.awsdns-62.com."
                },
                {
                    "Value": "ns-1868.awsdns-41.co.uk."
                },
                {
                    "Value": "ns-1243.awsdns-27.org."
                }
            ],
            "Type": "NS",
            "Name": "example.com.",
            "TTL": 172800
        },
        {
            "ResourceRecords": [
                {
                    "Value": "ns-617.awsdns-13.net. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
                }
            ],
            "Type": "SOA",
            "Name": "example.com.",
            "TTL": 900
        },
        {
            "ResourceRecords": [
                {
                    "Value": "198.51.100.10"
                }
            ],
            "Type": "A",
            "Name": "server-001.example.com.",
            "TTL": 1200
        },
        {
            "ResourceRecords": [
                {
                    "Value": "198.51.100.11"
                }
            ],
            "Type": "A",
            "Name": "server-002.example.com.",
            "TTL": 1200
        },
        {
            "ResourceRecords": [
                {
                    "Value": "server-001.example.com."
                }
            ],
            "Type": "CNAME",
            "Name": "server-cname.example.com.",
            "TTL": 3600
        }
    ]
}
```

Route 53に追加したDNSレコードの名前解決テスト例
===

## (10) Route 53に追加したDNSレコードを名前解決出来るかテストします。

Route 53にPublicなゾーンを作成した場合は、digコマンドのパラメータで、ゾーンのNSレコードのDNSサーバ(4つのNSレコードのうちのどれか)を指定する事で、名前解決のテストを行えます。

[ns-497.awsdns-62.com]は今回作成したゾーンのDNSサーバ、先の[aws route53 list-resource-record-sets]コマンドで表示されたNSレコードのDNSサーバです。
以下のように追加したDNSレコードの名前解決が出来る事を確認します。

### (10-1) Route 53に追加したAレコードの名前解決テスト。

```
$ dig +noall +ans +norec server-001.example.com. @ns-497.awsdns-62.com
server-001.example.com. 1200 IN    A       198.51.100.10
$
```

```
$ dig +noall +ans +norec server-002.example.com. @ns-497.awsdns-62.com
server-002.example.com. 1200 IN    A       198.51.100.11
$
```

### (10-2) Route 53に追加したCNAMEレコードの名前解決テスト。

```
$ dig +noall +ans +norec server-cname.example.com. @ns-497.awsdns-62.com
server-cname.example.com. 3600 IN  CNAME   server-001.example.com.
server-001.example.com. 1200 IN    A       198.51.100.10
$
```

Route 53に追加したDNSレコードの削除
===

## (11) Route 53に追加したDNSレコードを削除します。

以下を実行すると、先ほどRoute 53のゾーンに追加したDNSレコードを削除出来ます。

```
$ cp /tmp/create_dns_recordset.json /tmp/delete_dns_recordset.json
$ sed -i "s/CREATE/DELETE/g" /tmp/delete_dns_recordset.json
$
```

```
$ cat /tmp/delete_dns_recordset.json | wc -l
43
$ cat /tmp/delete_dns_recordset.json | jq . | wc -l
43
$
```

```
$ aws route53 change-resource-record-sets --hosted-zone-id ${R53_ZONE_ID} --change-batch file:///tmp/delete_dns_recordset.json
{
    "ChangeInfo": {
        "Status": "PENDING",
        "SubmittedAt": "2014-12-23T15:53:55.293Z",
        "Id": "/change/C3BMEQ2NS76GSU"
    }
}
$
```

## (12) Route 53からDNSレコードが削除された事を確認します。

Route 53ゾーンに登録されているDNSレコード一覧から前述のDNSレコードが削除された事を確認します。

```
$ aws route53 list-resource-record-sets --hosted-zone-id ${R53_ZONE_ID}
```

Route 53に作成したゾーンを削除する
===

## (13) Route 53からゾーンを削除します。

以下を実行すると、Route 53に新規作成したゾーンを削除出来ます。

ただし、Route 53には同じ名前のゾーン名を複数作成する事が可能です。複数同じ名前のゾーンを作成されている場合は、AWS Management Console または [aws route53 list-hosted-zones]や[aws route53 list-resource-record-sets]を使って、Route53のどのゾーンを削除したいのか確認の上で、削除対象ゾーンのHosted Zone ID(今回のメモではR53_ZONE_IDという変数で指定しているゾーンID)を指定する必要があります。

```
$ aws route53 delete-hosted-zone --id=${R53_ZONE_ID}
{
    "ChangeInfo": {
        "Status": "PENDING",
        "SubmittedAt": "2014-12-23T16:00:20.320Z",
        "Id": "/change/*************"
    }
}
$
```

## (14) Route 53からゾーンが削除された事を確認します。

Route 53に登録されているゾーン一覧から、削除対象として指定したゾーン名とHosted Zone IDが消えていれば、ゾーン削除は完了です。

```
$ aws route53 list-hosted-zones
```

***

以上になります。