Skip to content

Instantly share code, notes, and snippets.

@mechamogera
Last active July 6, 2022 19:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mechamogera/3973319 to your computer and use it in GitHub Desktop.
Save mechamogera/3973319 to your computer and use it in GitHub Desktop.
Route53のDynamicDNS設定Rubyスクリプト

使用方法

  • 以下のようにしてスクリプトを取得する。もしくは、downloadして解凍。
 $ git clone git://gist.github.com/3973319.git
  • 実行
  • 自マシンでのIPアドレスを取得してRoute53にhoge.example.com.のAレコードを設定する
 $ ruby r53_set_dynamicdns.rb --help
Usage: r53_set_dynamicdns [options]
    -a, --access-key-id=VAL
    -s, --secret-access-key=VAL
    -z, --hosted-zone-name=VAL
    -r, --record-name=VAL
    -v, --record-value=VAL           default:192.168.0.1
    -t, --record-ttl=VAL             default:300
    -k, --record-kind=VAL            default:A
    -c, --timeout-count=VAL          default:10
    -w, --timeout-wait=VAL           default:5

 $ ruby r53_set_dynamicdns.rb -a [access-key-id] -s [secret-access-key] -z example.com. -r hoge.example.com.

EC2での使用方法

$ sudo yum update -y
$ sudo yum install rubygem-aws-sdk git -y

$ git clone git://gist.github.com/3973319.git
$ cd 3973319
$ ruby r53_set_dynamicdns.rb -a [access-key-id] -s [secret-access-key] -z example.com. -r hoge.example.com.
# => 実行を確認

$ echo "ruby /home/ec2-user/3973319/r53_set_dynamicdns.rb -a [access-key-id] -s [secret-access-key] -z example.com. -r hoge.example.com." | sudo tee -a /etc/rc.local
# => 起動時に実行するように設定

EC2でCNAMEで登録する場合

$ ruby -a [access-key-id] -s [secret-access-key] r53_set_dynamicdns.rb -z example.com. -r hoge.example.com. -k CNAME -v `wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname`

参照サイト

#!/bin/env ruby
require 'rubygems'
gem 'aws-sdk'
require 'aws-sdk'
require 'optparse'
access_key_id = nil
secret_access_key = nil
hosted_zone_name = nil
record_name = nil
record_ttl = 300
record_value = `wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'`.chomp
record_kind = "A"
timeout_count = 10
timeout_wait = 5
opt = OptionParser.new
opt.on('-a', '--access-key-id=VAL') { |v| access_key_id = v }
opt.on('-s', '--secret-access-key=VAL') { |v| secret_access_key = v }
opt.on('-z', '--hosted-zone-name=VAL') { |v| hosted_zone_name = v }
opt.on('-r', '--record-name=VAL') { |v| record_name = v }
opt.on('-v', '--record-value=VAL', "default:#{record_value}") { |v| record_value = v }
opt.on('-t', '--record-ttl=VAL', "default:#{record_ttl}") { |v| record_ttl = v }
opt.on('-k', '--record-kind=VAL', "default:#{record_kind}") { |v| record_kind = v }
opt.on('-c', '--timeout-count=VAL', "default:#{timeout_count}") { |v| timeout_count = v.to_i }
opt.on('-w', '--timeout-wait=VAL', "default:#{timeout_wait}") { |v| timeout_wait = v.to_i }
opt.parse!(ARGV)
if hosted_zone_name.nil? || record_name.nil?
raise "option is necessary, use --help option"
end
if record_value.empty?
raise "can't get public ip"
end
r53 = AWS::Route53.new(:access_key_id => access_key_id,
:secret_access_key => secret_access_key,
:proxy_uri => ENV['HTTP_PROXY'] || ENV['http_proxy'])
resp = r53.client.list_hosted_zones
target_id = resp[:hosted_zones].find { |x| x[:name] == hosted_zone_name }[:id]
record_list = r53.client.list_resource_record_sets(:hosted_zone_id => target_id,
:start_record_name => record_name)
target_record = record_list[:resource_record_sets].find { |record| record[:name] == record_name }
if target_record && (target_record[:resource_records].nil? ||
target_record[:resource_records].size != 1 ||
target_record[:type] != record_kind)
raise "record is already exist and can't override"
end
if target_record && (target_record[:resource_records][0][:value] == record_value)
puts "record already exist and setting is unnecessary, you should delete exist record by hand"
exit
end
request = {
:hosted_zone_id => target_id,
:change_batch => {
:changes => [{
:action => "CREATE",
:resource_record_set => {
:name => record_name,
:type => record_kind,
:ttl => record_ttl,
:resource_records => [{
:value => record_value
}]
}
}]
}
}
if target_record
request[:change_batch][:changes].unshift({
:action => "DELETE",
:resource_record_set => target_record
})
end
change_result = r53.client.change_resource_record_sets(request)
change_result[:change_info][:id]
timeout_count.times do
break if change_result[:change_info][:status] == "INSYNC"
sleep timeout_wait
change_result = r53.client.get_change(:id => change_result[:change_info][:id])
end
if change_result[:change_info][:status] != "INSYNC"
raise "timeout to update record, status is #{change_result[:change_info][:status]}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment