📡

Route53 resolver でちょっとハマった

2022/05/09に公開

他愛もない話。

AWSで Aurora for PostgreSQL を使うけど、オンプレからの移行期間中にはオンプレからも Aurora にアクセスする...という設定です。
Auroraはメンテナンスや障害の影響でリードレプリカとライターが入れ替わるから、IPアドレスも入れ変わる可能性がありますので、オンプレからAurora使う場合にはIPアドレス固定でアクセスするわけにはいかないです。

たとえばこんな感じ。この絵だと、更新系クエリはライターである ap-northeast-1a のAuroraインスタンスに投げられます。

でももし、メンテとか障害でライターとリードレプリカが交代した時、オンプレ側でライターのアドレスを固定していると

となってしまい、書き込むことができない。

AWSのVPC内のインスタンスではややタイムラグはあるものの、基本的には新しいライターに追従する形でIPアドレスも変わるので問題ないです。
なので、なんとかしてオンプレ側にも新しいライターのIPアドレスを伝えてやらないといけない。

さて、そこで登場するのが Route53 Resolver。
Route53 Resolverにはインバウンドとアウトバウンドがあるけど、今回はインバウンド。
Route53 Resolverの設定自体は簡単です。コンソールでぽちぽちやってもいいし、terraformなら

route53_resolver.tf
// Route53 Inbound
resource "aws_security_group" "route53_resolver_sg" {
  name   = "route53_resolver_sg"
  vpc_id = "VPCのid"
}

resource "aws_security_group_rule" "inbound_udp_route53_resolver" {
  type      = "ingress"
  from_port = 53
  to_port   = 53
  protocol  = "udp"
  cidr_blocks = [
    "オンプレのCIDR"
  ]
  security_group_id = aws_security_group.route53_resolver_sg.id
}

resource "aws_security_group_rule" "inbound_tcp_route53_resolver" {
  type      = "ingress"
  from_port = 53
  to_port   = 53
  protocol  = "tcp"
  cidr_blocks = [
    "オンプレのCIDR"
  ]
  security_group_id = aws_security_group.route53_resolver_sg.id
}

resource "aws_route53_resolver_endpoint" "my_inbound" {
  name      = "my_inbound"
  direction = "INBOUND"
  security_group_ids = [
    aws_security_group.route53_resolver_sg.id
  ]

  ip_address {
    subnet_id = "サブネット1のid"
    ip        = "10.0.0.12"
  }

  ip_address {
    subnet_id = "サブネット2のid"
    ip        = "10.0.1.12"
  }
}

て感じになると思う。
上記の設定だと、 10.0.0.1210.0.1.12 で53番ポートへのDNSクエリを受け付けるようになり、VPC内にあるインスタンスと同様に名前解決ができるようになります。
ちなみに Route53 Resolver では最低2つのネットワークインターフェースを設定してやらないといけません。

で、あとはオンプレ側のDNSキャッシュサーバーで、AWSのローカルDNSに転送したい名前空間を設定してやる。

たとえば unbound であれば

/etc/unbound/unbound.conf
forward-zone:
      name: "amazonaws.com"
      forward-addr: 10.0.0.12
      forward-addr: 10.0.1.12

あるいは bind であれば

/etc/bind/named.conf
zone "amazonaws.com" {
        type forward;
        forward only;
        forwarders {
          10.0.0.12;
          10.0.1.12;
        };
};

これで、 xxx.amazonaws.com の名前解決はローカルキャッシュサーバーからRoute53 Resolverに転送されるので、あとはよしなに解決されます。Auroraのライターのアドレスが変わっても、追従して変わった後のアドレスを返してくれるようになります。

例えば先の例だと、正常時はこうなります。

で、メンテや障害でライターのアドレスが変わっても、 xxx.amazonaws.com の名前解決は Route53 Resolver に転送するので、IPアドレスの変化に追従してくれるわけです。

ま、これはいいんですが。

ハマったところ

私、VPC内のホストやAuroraに関しては Route53 のエイリアスやCNAMEを使って独自のローカルレコードを設定していまして。
仮にそれが my-vpc.com だとすると、Auroraに関しては aurora-writer.my-vpc.com てな感じでライターのアドレスを取得できるようにしていました。
なので、ローカルキャッシュサーバーの設定も

/etc/unbound/unbound.conf
forward-zone:
      name: "my-vpc.com"
      forward-addr: 10.0.0.12
      forward-addr: 10.0.1.12

のようにしてましたが、これで

$ nslookup aurora-writer.my-vpc.com

のようにしても、タイムアウトしてIPアドレスが返ってきませんでした。
かと思ったら、5分ぐらい経つと返ってくるようになったりして何でだろうなーと思ってましたが、Auroraに関してはCNAME使ってるので、Route53 Resolver が返すのは、CNAMEで解決された後のドメイン名。
なので、そのドメイン名( amazonaws.com )も設定してやらないと解決できないのでした。

正しくは

/etc/unbound/unbound.conf
forward-zone:
      name: "my-vpc.com"
      forward-addr: 10.0.0.12
      forward-addr: 10.0.1.12

forward-zone:
      name: "amazonaws.com"
      forward-addr: 10.0.0.12
      forward-addr: 10.0.1.12

上記のようにすれば、

  1. Route53 Resolverから、aurora-writer.my-vpc.com のCNAMEを解決した 'rdb-cluster-instance-1-ap-northeast-1c.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com' が帰ってくる。
  2. 'rdb-cluster-instance-1-ap-northeast-1c.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com' について再度、Route53 Resolver に問い合わせる。
  3. ライターのIPアドレスが得られる。

となって解決したのでした。
最初に書いた通り、わかってみれば他愛もない話でした。

Discussion