Route 53でローカルDNSを構築する

## 概要
Route 53を使ってローカルDNSを構築します。
この記事では最終的に作成されたRDSのエンドポイントに任意の名前で接続出来るようにします。

## 前提条件
この記事の内容を実践する為に必要な前提条件です。

- 利用可能なVPCが存在する事
- RDSのインスタンスが作成されている事

## Privet Hosted Zoneを作成する

マネジメントコンソール → Route 53 → Hosted zones → Create Hosted Zone より作成を行います。

ドメイン名は任意で構いません。
この記事では ```test.local``` という名前で作成します。

Type: "Private Hosted Zone for Amazon VPC" を選択
Domain Name: test.local
Comment: 任意のコメント
VPC ID: 予め準備してあるVPCを指定します

![private-domain-1.png](https://qiita-image-store.s3.amazonaws.com/0/71899/f65a986a-1d3a-b892-5e0c-40b00f57a3c9.png)

## Privet Hosted ZoneにCNAMEレコードを追加する

CNAMEレコードとは既存のドメインに対して別名を付ける為のものです。

[こちらの記事](http://qiita.com/PharaohKJ/items/b6a933b7f79afe8a32e1) に詳しく解説してくれている方がいますので、参考にすると良いかもしれません。
※この記事の中ではAレコードの解説も載っています。

AWSに割り振られたFQDNに対して、以下のように別名を付けます。

| 元のFQDN | 与える別名 | 役割 |
|:-:|:-:|:-:|
| dev-account-db.cluster-aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com  | account-db-master.test.local  | 書き込み用DB  |
| dev-account-db-ap-northeast-1c.aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com  | account-db-slave.test.local  | 読み取り用DB  |

「Create Record Set」よりレコードを作成します。

Name: "account-db-master" を入力
Type: "CNAME - Canonical name" を選択
Alias: "No"を選択
TTL: デフォルトのまま（300）
Value: 対象のRDSのエンドポイント ```dev-account-db.cluster-aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com``` を入力

![private-domain-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/71899/f318ef5e-2a42-a37f-f4bf-f52fef7f8292.png)

同じ要領で ```account-db-master.test.local``` のほうも作成します。

## DHCPオプションセットを作成する

接続元のサーバ（EC2）からDNSサーバを参照するように設定が必要です。
ローカルDNSのIPは [公式ドキュメント](http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) にあるように、

>VPC ネットワークの範囲に 2 をプラスした値です。例えば、10.0.0.0/16 ネットワークの DNS サーバーの位置は 10.0.0.2 となります。

となっています。
本件で扱うVPCは ```192.0.0.0/16``` なので ```192.0.0.2``` がローカルDNSのIPアドレスになります。

```/etc/resolv.conf``` に情報を書き込む事で名前解決が可能になりますが、DHCPオプションを設定する方法が便利なのでこちらを利用します。

マネジメントコンソール → VPC → DHCPオプションセット → DHCPオプションセットの作成 より開始します。

情報は以下の通りに入力して下さい。

ネームタグ: dev
ドメイン名: "ap-northeast-1.compute.internal test.local"
ドメイン・ネームサーバ: "AmazonProvidedDNS"

入力した情報について説明します。

- ネームタグ
任意の分かりやすい名前をつけて下さい。
私は環境を表す"dev"を付けました。

- ドメイン名
2つのドメイン名を半角スペース繋ぎで記載します。
1つ目のドメインはリージョン固有のドメイン（今回は東京リージョンなので ```ap-northeast-1.compute.internal```）
2つ目のドメインは今回作成したローカルドメイン ```test.local``` です。

- ドメインネームサーバ
"AmazonProvidedDNS"を指定することでresolv.confのnameserverにRoute 53での名前解決用IPが記載されます。

![private-domain-3.png](https://qiita-image-store.s3.amazonaws.com/0/71899/93089f25-60f3-41b5-b006-662ee48baade.png)

このあたりの詳しい説明は [公式ドキュメント](http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html#DHCPOptionSets) にも記載があります。

## VPCにDHCPオプションセットを設定する

マネジメントコンソール → VPC → アクション より DHCPオプションセットを設定します。
それぞれの項目を下記のように設定します。

![private-domain-4.png](https://qiita-image-store.s3.amazonaws.com/0/71899/bc10ee44-a982-1ae3-e326-470695a2f7d3.png)

<img width="443" alt="private-domain-5.png" src="https://qiita-image-store.s3.amazonaws.com/0/71899/455bcd37-3c1f-ffb2-941f-e63779ca6d0a.png">

<img width="443" alt="private-domain-6.png" src="https://qiita-image-store.s3.amazonaws.com/0/71899/e296c494-bfb8-9628-73fd-30b5578b95e0.png">

## 動作確認

接続元のEC2インスタンスにログインを行い以下のコマンドを実行します。

```bash:DHCP設定を再取得（rootで実行）
dhclient eth0
```

※インスタンスの再起動を行う事でもDHCP設定の再取得は出来ます。

```bash:DNS設定前のnslookupの結果
nslookup account-db-master.test.local
Server:		192.0.0.2
Address:	192.0.0.2#53

** server can't find account-db-master.test.local: NXDOMAIN
```

```bash:DNS設定後のnslookupの結果
nslookup account-db-master.test.local

Server:		192.0.0.2
Address:	192.0.0.2#53

Non-authoritative answer:
account-db-master.test.local	canonical name = dev-account-db.cluster-aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com.
dev-account-db.cluster-aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com	canonical name = dev-account-db.aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com.
Name:	dev-account-db.aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com
Address: 192.0.20.68
```

設定した名前で名前解決が出来ている事が確認出来ます。

念のため設定したホスト名でmysql接続が出来る事を確認します。

```bash:設定したドメイン名で接続
mysql -u test_user -h account-db-master.test.local -p
```
接続の確認が出来ました。

```text
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5885
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

別名をつけただけなので、もちろん元々のFQDNでも接続が可能です。

```bash:元々のFQDNでも接続出来る事を確認
mysql -u test_user -h dev-account-db.cluster-aaaaabbbbcc1.ap-northeast-1.rds.amazonaws.com -p
```

同じように接続が出来ました。

```text
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5884
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

## 別名を付ける事によるメリット

この設定を行う事で下記のようなメリットが考えられます。

1. 任意の名前を付けられる事でAWSから提供される長いFQDNを覚えなくても良くなります
1. 例えばDBサーバを丸ごと入れ替えたとしても変更するのはRoute 53のCNAMEレコードのみなので移行が簡単になる

特に2のメリットは大きいと考えます。
Route 53なら簡単に設定が可能なので設定しておく事をオススメします。

この記事の内容は以上になります。
最後まで読んで頂きありがとうございました。