ども、cloudpackかっぱ (@inokara) です。

はじめに

Amazon Route53 に登録されているレコード情報を Excel のようなシートで管理しなければいけないシチュエーションがあった場合にレコード情報をコピペしていたら辛いなあと思ったので AWS SDK for Ruby を叩いてレコード情報を引っこ抜いて GoogleSpreadsheet に書き込む流れを試してみたメモです。

本当にタダのメモです。


参考

Amazon Route53 を GoogleSpreadsheet を管理する方法として Google Apps Script を利用する方法をコメントで @hnakamur さんに教えて頂きました。有難うございます!

上記だと Spreadsheet に入力した内容を Route53 に反映するアプローチも取れるのでイイ感じですね!

まずは pry で…

AWS SDK for Ruby を使ってAmazon Route53 を Google Spreadsheet で管理する: pryを使い動作の想定

こんな感じでレコードの情報が取得出来ますね。
簡単です。


さあ、Spreadsheet に書き込みましょう

とりあえずこんな感じ

スクリプトは以下のように書きました。

#!/usr/bin/env ruby

require 'aws-sdk'
require "google_drive"

session = GoogleDrive.login('xxxxxxx@gmail.com', 'xxxxxxxxxxxxxxxx')
ws = session.spreadsheet_by_key('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx').worksheets[0]

HOSTED_ZONE="/hostedzone/XXXXXXXXXXXXXXXX"

AWS.config.credentials
r53 = AWS::Route53.new(region: "ap-northeast-1").client

r53.list_resource_record_sets(:hosted_zone_id=>"#{HOSTED_ZONE}")[:resource_record_sets].each do |resource|
  ws.update_cells(1, 1, [resource.keys])
  ws.save

  rr = ""
  resource.each do |k , v|
    if k == (:resource_records)
      v.each do |value|
        rr << value[:value] + "n"
      end
    end
  end

  resource[:resource_records] = rr

  begin
    timeout(5) do
      ws.list.push(
        resource
      )
      ws.save
    end
  rescue Timeout::Error
    puts "Google SpreadSheet-- Timed out while attempting to send"
  end
end

ホントに簡単なスクリプトです。

ハードル

上図の pry で実行した画面を見て頂くと判りますが SDK のレスポンスでハードルとなったのが、キーが :resource_records の値が複数のハッシュが配列となって格納されています。これを解決するには :resource_records の値を展開して連結してゴニョゴニョする必要がありましたので、以下のように解決してみました。

  rr = ""
  resource.each do |k , v|
    if k == (:resource_records)
      v.each do |value|
        rr << value[:value] + "n"
      end
    end
  end

  resource[:resource_records] = rr

スプレッドシートへの書き込み

スプレッドシートへの書き込みは ws.list.push にハッシュの resource を食わせた後に ws.save で保存します。

  begin
    timeout(5) do
      ws.list.push(
        resource
      )
      ws.save
    end
  rescue Timeout::Error
    puts "Google SpreadSheet-- Timed out while attempting to send"
  end

とても簡単です。

ちなみに resource は以下のような内容となっています。

{:resource_records=>"ns-1403.awsdns-47.org.nns-757.awsdns-30.net.nns-1545.awsdns-01.co.uk.nns-456.awsdns-57.com.n", :name=>"test.inokara.com.", :type=>"NS", :ttl=>172800}

書き込んでみた図

スクリプトを実行すると以下のように記録されます。
AWS SDK for Ruby を使ってAmazon Route53 を Google Spreadsheet で管理する: 動作確認 - 書き込んでみた図

おお。

Route53 の図

ついでに引っこ抜いてきた Route53 の画面を見てみましょう。
AWS SDK for Ruby を使ってAmazon Route53 を Google Spreadsheet で管理する: 動作確認 - Amazon Route53の図

列の並びこそ違いますがちゃんと Spreadsheet に登録した内容と相違が無いようです。

最後に

ハマったところ

正直申し上げてほんの数行のスクリプトですが :resource_records の値に複数の値が登録されているというのがかなりの鬼門で解決するのに半日を要しました…が、解決方法は実はとても簡単で複数の値を取り出すのは each メソッドで値を取り出して配列に突っ込んだ後で、その配列を元のハッシュのキーを指定して値を変更して上げれば良いだけのことでした。(以下のような感じです)

  rr = ""
  resource.each do |k , v|
    if k == (:resource_records)
      v.each do |value|
        rr << value[:value] + "n"
      end
    end
  end

  resource[:resource_records] = rr

ドメイン名

今回はドメイン(/hostedzone/XXXXXXXXXXXXXXXX)は決め打ちでレコード情報だけを取得していますが、以下のようにホストの情報も取得することが可能ですので複数のドメインでシート分けて管理することが出来そうですね。

require 'aws-sdk'
AWS.config.credentials
r53 = AWS::Route53.new(region: "ap-northeast-1").client
p r53.list_hosted_zonesst_hosted_zones

そう言えば…

今回は Route53 に登録したレコード情報を引っこ抜いて Google Spreadsheet という王道(割りと)を試してみましたが、逆に Spreadsheet に登録した内容を Route53 に登録するということも出来そうです。

todo

  • 複数のドメインが Route53 に登録されている場合にはドメイン名毎にシートを分ける
  • Spreadsheet への列の書き込み順序を Route53 が表示されている順番と同じにする

SDK や CLI はホント楽しいですなあ。

元記事はこちらです。
ニーズがあるか判りませんが… AWS SDK for Ruby を使って Route53 に登録されている情報を Google Spreadsheet で管理するメモ