Skip to content

Instantly share code, notes, and snippets.

@ueki-kazuki
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ueki-kazuki/4ccce9faddb0455ed089 to your computer and use it in GitHub Desktop.
Save ueki-kazuki/4ccce9faddb0455ed089 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'aws-sdk-v1'
require 'optparse'
def create_ssh_config(region, profile_name = '', ptr_records = {})
AWS.memoize do
region.vpcs.each do |vpc|
# Exist bastion server in VPC?
bastion_exist = false
bastion_host = ""
vpc.instances.each do |i|
if i.tags['Name'] =~ /bastion/i and i.elastic_ip
bastion_exist = true
elastic_ip = i.elastic_ip.ip_address
bastion_host = ptr_records.has_key?(elastic_ip) ? ptr_records[elastic_ip]
: "#{profile_name}_#{i.tags['Name']}"
break
end
end
vpc.instances.each do |i|
ip_address = bastion_exist ? i.private_ip_address
: i.elastic_ip ? i.elastic_ip.ip_address
: i.public_ip_address ? i.public_ip_address
: i.private_ip_address
# lookup dns name
host = "#{profile_name}_#{i.tags['Name']}"
hostname = ip_address
if ptr_records.has_key?(ip_address)
host = hostname = ptr_records[ip_address]
end
puts "# #{profile_name} #{region.name} #{i.id}"
puts "# vpc: #{vpc.id} (#{vpc.tags.Name})"
puts "# eip: #{i.elastic_ip}"
puts "# pub: #{i.public_ip_address}"
puts "# pri: #{i.private_ip_address}"
puts "Host #{host}"
puts " Hostname #{hostname}" unless i.tags['Name'] =~ /bastion/i
puts " Hostname #{bastion_host}" if i.tags['Name'] =~ /bastion/i
puts " User ec2-user"
puts " IdentityFile ~/.ssh/#{i.key_name}.pem"
if bastion_exist
puts " ProxyCommand ssh #{bastion_host} -W %h:%p" unless i.tags['Name'] =~ /bastion/i
end
puts ""
end
end
end
end
def gen_ptr_records
ptr_records = {}
route53 = AWS::Route53.new
route53.hosted_zones.each do |zone|
zone.resource_record_sets.each do |rrset|
next unless rrset.type == "A"
rrset.resource_records.each do |rr|
unless ptr_records.has_key?(rr[:value])
ptr_records[rr[:value]] = rrset.name.sub(/\.$/, "")
end
end
end
end
ptr_records
end
profile_name = ""
region_name = ""
ARGV.options do |opt|
begin
aws_opts = {}
is_debug = false
opt.on('-h', '--help') { puts opt.help; exit 0 }
opt.on('-k', '--access-key ACCESS_KEY') { |v| aws_opts[:access_key_id] = v }
opt.on('-s', '--secret-key SECRET_KEY') { |v| aws_opts[:secret_access_key] = v }
opt.on('-r', '--region REGION') { |v| aws_opts[:region] = v
region_name = v }
opt.on('--debug') { is_debug = true }
opt.on('--profile PROFILE') { |v| profile_name = v
aws_opts[:credential_provider] = AWS::Core::CredentialProviders::SharedCredentialFileProvider.new(profile_name: v) }
opt.parse!
if aws_opts.empty?
puts opt.help
exit 1
end
if is_debug
aws_opts[:logger] = Logger.new($stdout)
aws_opts[:log_level] = :debug
end
AWS.config(aws_opts)
rescue => e
$stderr.puts e
exit 1
end
end
# collect dns reverse record
ptr_records = gen_ptr_records
ec2 = AWS::EC2.new
if region_name.empty?
#全リージョンを対象とする
ec2.regions.each do |region|
create_ssh_config(ec2.regions[region.name], profile_name, ptr_records)
end
else
create_ssh_config(ec2.regions[region_name], profile_name, ptr_records)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment