Amazon Route 53+ELBでホスト名なし(zone apex)の運用もOKになったので試してみた

先日、Amazon Route 53のベータがとれて正式版になったのと同時に、ELBと協調動作するための機能(Alias Resource Record Set)も追加されました。

以前に書いた「Amazon ELBでホスト名なしのhttp://example.comを運用すると発生するいくつかの弊害」もこれで解消できそうだったのでちょっと試してみました。

Alias Resource Record Set

ELBとの協調動作にはRoute 53で「Alias Resource Record Set」というレコードを設定します。

Alias Resource Record SetはDNS的にはAレコードなのですが、そのIPアドレスはAliasTarget/DNSNameで指定した名前(ELBのDNS Nameです)を解決したIPアドレスになります。そしてELBのDNS Nameが指すIPアドレスが変わった場合は、Route 53がそれに追従して当該Aレコードの更新してくれるようです。

$ dig -t a +noall +answer example.com @ns-XXX.awsdns-XX.com
example.com.              60      IN      A       175.41.XXX.XXX

これを使えばホスト名なしの名前(AWSのドキュメントでは「zone apex」と呼んでいます)にAレコードを振りつつ、ELBも使えるので、以前指摘した「Amazon ELBでホスト名なしのhttp://example.comを運用すると発生するいくつかの弊害」のような問題もありません。もちろん、zone apex以外でもAliasは使えるので、http://example.comhttp://api.example.comの両方をRoute53+ELBで運用することもできます。

Alias の設定でつまずいたところ

Aliasの設定には

  <Change>
     <Action>CREATE</Action>
        <ResourceRecordSet>
           <Name>example.com.</Name>
           <Type>A</Type>
           <AliasTarget>
              <HostedZoneId>Z123456789</HostedZoneId>
              <DNSName>MyLoadBalancer-2111276808.us-east-1.elb.amazonaws.com.</DNSName>
           </AliasTarget>
        </ResourceRecordSet>
  </Change>

のようなXMLを送信するのですが、の中ので指定するELBのhosted zone IDです。当該ドメインのhosted zone IDを指定しててエラーが返ってきてしばらく悩みました。。。(ELBのhosted zone IDはWebのAWS Management Consoleで確認できます)

TTL

Alias Resource Record Setで作ったAレコードのTTLは60秒になるようです。

クエリ数で課金されるのでTTLが短い(クエリ回数が多くなる)のはちょっと気になりますね。

あと、DNSのコンテンツサーバは4つRoute 53から払い出されるんですが、手元のネットワークからだとcomとco.ukのは割りと近く(ping RTTが小さい)、次いでorg、netのは結構遠い感じでした。TTLが短いとコンテンツサーバへの問い合わせ機会が増えるわけで、応答が遅いとタイムアウトまではいかないにせよ、体感速度が落ちる危険性もあるのでちょっと心配ですね。

Alias Resource Record Set は必要か?

前述の通り、AliasはAレコードのIPアドレスがELBのDNS Nameが指すIPアドレスになるように保ちつづけるものなので、そういった機構を自前で実装すればAliasは要らず、Route 53ではなく自前のDNSサーバでもzone apexでELBを運用することもできるでしょう。

たいていの言語ならリゾルバのライブラリやモジュールはあるでしょうし、自前DNSコンテンツサーバもMySQLなどをバックエンドにできるPowerDNSを使えば更新も簡単なので、比較的簡単に実装できるのではないかと思います。

はじめての Route 53

今回初めてRoute 53を使ったのですがつまずいた点などをいくつか。

dnscurl.plのaccess keyファイル

Amazon提供のRoute 53のCUI tool、dnscurl.pl が使うaccess keyファイルは、ファイル名は「.aws-secrets」固定で、dnscurl.plがあるディレクトリもしくは実行するユーザのホームディレクトリ直下にある必要があります。また、dnscurl.plのオプション--keynameに渡す名前は、.aws-secretsのハッシュ%awsSecretAccessKeysのキーになります。dnscurl.plはcurlコマンドのラッパーのようなPerlスクリプトなので、気に入らなければ好きなように変更するのは容易でしょう。

設定ツール

いちいちXMLを手で書いてdnscurl.plで流し込むのは大変なので設定ツールを使った方がいいでしょう。

最初、Google Docs スプレッドシートでゾーン情報が管理できるAmazonRoute53AppsScriptを試したのですが、まだAlias Resource Record Setに対応していないらしく、Aliasを設定したゾーンをsyncしたらエラーになってしまいました。

なので早々とAliasに対応したR53 Foxを使いました。

複数のMXが設定できない?

R53 Foxで二つ目のMXを追加しようとしたら、「Tried to create resource record set example.com., type MX but it already exists」といわれてエラーになってしまいました。

MXなのになんで複数設定できないの。。。と思ったのですが、XMLの場合、複数のに分けるのではなく、ひとつのの中で複数のを列挙する形式のようで、

  <Change>
    <Action>CREATE</Action>
    <ResourceRecordSet>
      <Name>example.com.</Name>
      <Type>MX</Type>
      <TTL>86400</TTL>
      <ResourceRecords>
        <ResourceRecord><Value>10 smtp1.example.com.</Value></ResourceRecord>
        <ResourceRecord><Value>10 smtp2.example.com.</Value></ResourceRecord>
      </ResourceRecords>
    </ResourceRecordSet>
  </Change>

R53 FoxではValueの項に

10 smtp1.example.com.
10 smtp2.example.com.

と複数行書いて設定すればOKでした。

djbdns(tinydns)からの移行

djbdnsのtinydns用のcdbファイルを読んでRoute 53用のXMLに書き出してくれるスクリプトがあったのですが、APIバージョンが古かったのでちょっと修正して使いました。githubに置いておきますのでどうぞお使いください。

R53 Foxでゾーンを作って、cdbtoroute53.plでcdbからXMLを生成、それをdnscurl.plで流し込んで、細かい修正はR53 Foxで行うのがいいんじゃないかと思います。

DNSサーバの引っ越しには

http://www.e-ontap.com/dns/propagation/ を読みましょう :D