Amazon Route 53のALIASレコード利用のススメ
よく訓練されたアップル信者、都元です。
Amazon Route 53は、AWSが提供するDNSサービスです。通常、ドメインを取得すると、ドメインレジストラからDNSがサービスで提供されることが多いと思います。費用は大抵ドメイン代に含まれていて、追加費用は無いことが多いです。しかしAWSで利用するドメインは、下記のような理由から、ドメインのオマケで付いてくるDNSではなく、Route 53を利用するメリットが大いにあります。
- 無料じゃないとは言え、とにかく安い。Route 53のコストが月10ドル超えるような人気サービスを作れたら勝ち組です。
- プログラマブルである。レコードの定義と書き換えをスクリプトで実行できる。デプロイの自動化に寄与。
- CloudFormationからレコードの定義と書き換えができる。まぁ↑とほぼ同じことを言ってますが。
- SLAは100%(!?)
- ELB, CloudFront, S3等、他のAWSプロダクトとの連携が良い(★)
というわけで、積極的に使っていきましょう、というのが導入部です。今日のお話は(★)で示した、他プロダクトとの連携で利用する「ALIASレコード」についてです。
ALIASレコード
DNSには、A, CNAME, MX, NS等のレコードタイプがあることはご存知だと思います *1。このうち、Route 53でサポートするレコードタイプは、以下のドキュメントに記述があります。代表的なものは大体サポートしていますね。
Supported DNS Resource Record Types
Route 53では、これらの他に独自拡張である「ALIASレコード」という特殊なレコードがあります。まぁ独自拡張とは言え、未知のレコードタイプを増やしても周囲のDNSが理解できなければ意味がありません。ALIASレコードは、Route 53の内部で扱う特殊なタイプで、外から見たら単なるAレコードに見えます。
ではALIASレコードとは一体何でしょうか。一言で言ってしまえば「各AWSプロダクトで利用するDNS名専用の、CNAMEレコード風の挙動を実現するレコード」です。一言で言いすぎてわけがわからなくなりましたorz
CNAMEレコード vs ALIASレコード
例えば、ELBにはmyLB-1234567890.us-east-1.elb.amazonaws.comのようなDNS前が付いています。通常www.example.comへのアクセスをこのELBに向けたい場合は、example.comの権威DNSに対して、wwwのCNAMEレコードにmyLB-1234567890.us-east-1.elb.amazonaws.comを設定、といったことをします。Route 53でもこの設定はもちろん可能です。
しかし、ここでALIASレコードを利用することも可能です。つまりwwwのALIASレコードにmyLB-1234567890.us-east-1.elb.amazonaws.com (Z3DZXE0Q79N41H)を設定するのです。末尾のカッコ内の文字列は後で説明しますね。下記のexample1はCNAMEで設定したもの、example2はALIASで設定したものです。結局は同じELBにつながっています。
それぞれをdigしてみましょう。
$ dig example1.*** (略) ;; ANSWER SECTION: example1.***. 300 IN CNAME awseb-***-1110552124.ap-southeast-2.elb.amazonaws.com. awseb-***-1110552124.ap-southeast-2.elb.amazonaws.com. 60 IN A **.**.**.183
$ dig example2.*** (略) ;; ANSWER SECTION: example2.cm.xet.jp. 60 IN A **.**.**.183
前者はCNAMEレコードを介したAレコードで...183というIPアドレスに解決されています。一方後者は、直接Aレコードで同じIPアドレス...183に解決されています。というわけで、ALIASレコードを用いて、CNAMEと同じ挙動が実現されています。
同じことができるなら、標準的なCNAMEで良いじゃないか、と思うかもしれません。しかし、ALIASレコードにはいくつか重要なメリットがあります。
パフォーマンスが良い
CNAMEレコードを利用した場合、まずexample1.をDNSに問い合わせるとawseb--1110552124.ap-southeast-2.elb.amazonaws.comが返り、これをさらにDNSに問い合わせた結果として..**.183を得ます。つまり、DNSクエリが2回発生します。
一方、ALIASレコードを利用した場合は、example1.*から直接...183を得ますので、DNSクエリが1回で済みます。50%削減です。
ALIASレコードではなく、..**.183のAレコードを直接定義すればいいと考えるかもしれません。しかし、ELBのDNS名に対するIPアドレスは動的に変化する可能性があるため、そうすることはできません。
ちなみに、AWS Trusted Advisorでは、ALIASレコードが使える場面でCNAMEを利用していると、下記のチェック項目において警告を出してくれます。
zone apexに対するマッピングに対応
まず「zone」とは。DNSがドメインを管理する範囲です。例えば、example.comドメインを取得した場合、自分のDNSではexample.com及び.example.comに対するレコードを管理できます。この範囲がゾーンです。ちなみにこのDNSでfoobar.example.comを、NSレコードで別のDNSに委譲した場合、foobar.example.com及び.foobar.example.comは、zoneから外れます。別ゾーンになるわけですね。下記のページの図がわかりやすかったです。
この「zone」のうち、Route 53に登録されたゾーンのことを「Hosted Zone」と呼び、これらにはそれぞれIDが付いています。同じドメイン名で複数の Hosted Zone を登録することもできるため、DNS名とは別の識別子が必要なんですね。同じドメイン名の Hosted Zone のうち、どれが権威DNSとなるかは、上位ゾーンのNSレコード指定次第です。ちなみに先ほど出てきた「末尾のカッコ内の文字列」が Hosted Zone ID です。
次に「apex」とは。辞書を紐解くと「頂上」という意味ですね。つまり、example.comゾーンにおけるexample.comがzone apexです。
DNSの仕様上、zone apexに対してCNAMEレコードを設定してはいけません。正確には、CNAMEを設定してもいいですが、CNAMEを設定した名前には他のレコードを共存させてはいけません *2。zone apexにCNAMEを設定してしまうと、他のレコードを置けなくなってしまうので、結果的に大抵の場合zone apexにCNAMEを設定することはできなくなります。
しかし、ALIASレコードの実体はAレコードですのでこの制約はありません。
以前、本ブログでも「Amazon Route 53とELBでAlias Resource Record Setを設定してZone Apexを実現」でご紹介しています。
指定できるものに限りがある
CNAMEレコードはどこに対する別名指定も可能ですが、ALIASレコードはAWS内で利用する限られたDNS名に対してのみ指定可能です。具体的には、CloudFront distribution, ELB, static website設定をしたS3バケット, 他のRoute 53リソースレコードセット の何れかです。
個人的に、Elastic Beanstalkが利用しているホスト名に、早いとこ対応して欲しいと思っています…。
その他
他にもいくつか違いがあります。詳細は下記ページ内の表を御覧ください。
Creating Alias Resource Record Sets
ALIASレコードの記述方法
CNAMEレコードは、そのポイント先となる別のDNS名を文字列として指定するだけでした。CNAMEとして帰ってきたDNS名に対してさらに解決を試みるのはクライアントの役目なので、ポイント先のDNS名を文字列で返すだけで問題ありません。
一方ALIASレコードは、そのポイント先となるDNS名の他に「Hosted Zone ID」が必要です。前述の通り、同じDNS名のHosted Zoneは複数あり得るので、それを1つに特定するために、このIDが必要となります。1つに特定できなければ、返すべきIPアドレスも特定できませんので。
この「DNS名とHosted Zone IDの組み合わせ」のことをAliasTargetと呼びます。CNAMEレコードで言うDNS名の代わりに、ALIASレコードではAliasTargetを指定するわけです。なので前述の例では、末尾にHoted Zone IDを補足してあるのです。
まとめ
CNAMEではなくてALIASが使えるところでは、必ずALIASを使うべし。この一言に尽きます。
脚注
- よくよく調べてみたら、数えきれない程の見たことのないレコードタイプがいっぱいありました。。。 ↩
- RFC 1912 の 2.4 参照。 ↩