パラボラアンテナと星の日記

あることないこと

EC2自身が起動時にRoute53の設定を自分で更新するやつ

github.com

EC2立ち上げるたびに手で名前設定するのが面倒なので、EC2自身がRoute53叩いて設定するやつをDockerfileで書いた。

流行りのAWS Lambdaとかは使ってません。

使い方

EC2インスタンス上で、以下のようにdocker runするだけで、 いい感じにCNAMEレコード更新(UPSERT)する。

$ docker run -h $(hostname) --rm hoshinotsuyoshi/r53-from-ec2:2.1.23 ゾーン名(例:example.com.)

事前に、以下の2点が必要。

  • "AmazonRoute53FullAccess" というIAM PolicyインスタンスIAM Roleにアタッチしておくこと
  • ゾーン(例:example.com.)の設定が、既にRoute53にあること

cloud-configでの動かし方

ユーザーデータに、こんな感じで書いておく。

hostname: ホスト名
coreos:
  units:
    - name: r53-from-ec2.service
      command: start
      content: |
        [Unit]
        Description=r53
        After=docker.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        ExecStart=/usr/bin/docker run -h %H --rm hoshinotsuyoshi/r53-from-ec2:2.1.23 ゾーン名(例:example.com.)

これでインスタンス立ち上がった直後に、ホスト名.example.com でアクセスできる。

スクリプトの中身

  • 中途半端だけどOptionParserを使ってる
    • --help とか渡せる
    • --private とか渡すとPrivate DNSの設定更新になる
  • TTL(60秒) とレコードタイプ(CNAME)がベタ書き。
  • ruby使ってて、イメージサイズが大きい(90MB)点はイケてない
def pub_hostname
  open('http://169.254.169.254/2014-11-05/meta-data/public-hostname').read
end

def pri_hostname
  open('http://169.254.169.254/2014-11-05/meta-data/hostname').read
end

opt = OptionParser.new
opt.on('-h', '--help') do
  STDERR.puts "USAGE\n$ docker run -h $(hostname) --rm hoshinotsuyoshi/r53-from-ec2 example.com."
  exit 1
end

opt.on('--private') do
  @hostname = pri_hostname
end

opt.parse!(ARGV)

@hostname ||= pub_hostname

ZONE = ARGV.shift.dup
ZONE.end_with?('.') || ZONE << '.'
HOST = Socket.gethostname
REGION = @hostname.split('.')[1]

c = Aws::Route53::Client.new(region: REGION)
id = c.list_hosted_zones.hosted_zones.find{|z| z.name == ZONE }.tap do |zone|
  zone.nil? && !STDERR.puts("Cannot find zone #{ZONE}") && exit(1)
end.id
c.change_resource_record_sets(
  hosted_zone_id: id,
  change_batch: {
    changes: [
      {
        action: 'UPSERT',
        resource_record_set: {
          name: HOST + '.' + ZONE,
          type: 'CNAME',
          ttl: 60,
          resource_records: [
            { value: @hostname }
          ],
        },
      },
    ],
  },
)

ベタ書きのとこ直して ちゃんとオプションで渡せるようにすれば割りと使えるツールになるかも?