EC2内部用DNS: PowerDNSのPipeBackendを使って、タグ`Name'から内部IPを引けるようにする

4/6 追記
ツイッターから流れてくるかたのために補足しておくと、↓の方法は負荷が高すぎて、あまり実用的ではなかったです。某社では使ってないっす。規模にもよりますがゾーンファイルを更新するようにした方がいいとおもいます。たぶん


backendスクリプトがこんな感じ。要amazon-ec2。

#!/usr/local/bin/ruby
require "rubygems"
require "AWS"
require "syslog"

$ec2 = AWS::EC2::Base.new(
  :access_key_id     => "XXXXX",
  :secret_access_key => "YYYYY",
  :server            => "ec2.ap-southeast-1.amazonaws.com"
)

def lookup(hostname)
  ip_list = []

  $ec2.describe_instances.reservationSet.item.each do |reservationSet|
    instancesSet = reservationSet.instancesSet.item.first
    tagSet = {}
    instancesSet.tagSet.item.each {|i| tagSet[i["key"]] = i["value"] }

    if tagSet["Name"] == hostname
      ip_list << instancesSet.privateIpAddress
    end
  end

  return ip_list
end

$stdout.sync = true
$syslog = Syslog.open(__FILE__)
END { $syslog.close }

line = gets
line.strip!

unless line == "HELO\t1"
  puts "FAIL"
  $syslog.err "Recevied '#{line}'"
  gets
  exit
end

puts "OK\tEC2 backend firing up"

while gets
  $syslog.info "#{$$} Received: #{$_}"
  $_.strip!
  arr = $_.split(/\t/)

  if (arr.length < 6)
    puts "LOG\tPowerDNS sent unparseable line"
    puts "FAIL"
    next
  end

  type, qname, qclass, qtype, id, ip = arr

  if ["A", "ANY"].any? {|i| qtype == i }
    $syslog.info "#{$$} Sent A records"

    lookup(qname).each do |ip|
      puts ["DATA", qname, qclass, "A", 3600, -1, ip].join("\t")
    end
  end

  $syslog.info "#{$$} End of data"
  puts "END"
end

実行結果はこんな感じ。


shell> dig @localhost my-server-foo

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> @localhost my-server-foo
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57471
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;my-server-foo. IN A

;; ANSWER SECTION:
my-server-foo. 3600 IN A 10.130.XXX.XXX

;; Query time: 265 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Dec 18 03:05:30 2010
;; MSG SIZE rcvd: 47

shell> dig @localhost my-server-bar


; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> @localhost my-server-bar
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64230
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;my-server-bar. IN A

;; ANSWER SECTION:
my-server-bar. 3600 IN A 10.130.YYY.YYY

;; Query time: 356 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Dec 18 03:06:19 2010
;; MSG SIZE rcvd: 47