class Ec2ex::Core
Public Class Methods
new()
click to toggle source
# File lib/ec2ex/core.rb, line 11 def initialize ENV['AWS_REGION'] = ENV['AWS_REGION'] || get_document['region'] @ec2 = Aws::EC2::Client.new @elb = Aws::ElasticLoadBalancing::Client.new @logger = Logger.new(STDOUT); end
Public Instance Methods
allocate_address_vpc()
click to toggle source
# File lib/ec2ex/core.rb, line 334 def allocate_address_vpc @ec2.allocate_address(domain: 'vpc').data end
associate_address(instance_id, public_ip_address)
click to toggle source
# File lib/ec2ex/core.rb, line 250 def associate_address(instance_id, public_ip_address) unless public_ip_address.nil? allocation_id = get_allocation(public_ip_address).allocation_id resp = @ec2.associate_address(instance_id: instance_id, allocation_id: allocation_id) end end
client()
click to toggle source
# File lib/ec2ex/core.rb, line 18 def client @ec2 end
create_image_with_instance(instance, region = nil)
click to toggle source
# File lib/ec2ex/core.rb, line 146 def create_image_with_instance(instance, region = nil) tags = get_tag_hash(instance.tags) @logger.info "#{tags['Name']} image creating..." image_name = tags['Name'] + ".#{Time.now.strftime('%Y%m%d%H%M%S')}" image_response = @ec2.create_image( instance_id: instance.instance_id, name: image_name, no_reboot: true ) sleep 10 @ec2.wait_until(:image_available, image_ids: [image_response.image_id]) do |w| w.interval = 15 w.max_attempts = 1440 end @logger.info "image create complete #{tags['Name']}! image_id => [#{image_response.image_id}]" ami_tag = format_tag(get_ami_tag_hash(instance, tags)) @ec2.create_tags(resources: [image_response.image_id], tags: ami_tag) if region @logger.info "copying another region... [#{ENV['AWS_REGION']}] => [#{region}]" dest_ec2 = Aws::EC2::Client.new(region: region) copy_image_response = dest_ec2.copy_image( source_region: ENV['AWS_REGION'], source_image_id: image_response.image_id, name: image_name ) dest_ec2.create_tags(resources: [copy_image_response.image_id], tags: ami_tag) end image_response.image_id end
elb_client()
click to toggle source
# File lib/ec2ex/core.rb, line 43 def elb_client @elb end
extract_fields(data, fields)
click to toggle source
# File lib/ec2ex/core.rb, line 47 def extract_fields(data, fields) results = [] data.each do |row| row = Hashie::Mash.new(row) if row.class == Hash result = {} fields.map { |key| result[key] = eval("row.#{key}") } results << result end results end
format_tag(tag, preset_tag_hash = {})
click to toggle source
# File lib/ec2ex/core.rb, line 64 def format_tag(tag, preset_tag_hash = {}) tags = [] tag.each do |k, v| value = v ? ERB.new(v.gsub(/\$\{([^}]+)\}/, "<%=preset_tag_hash['" + '\1' + "'] %>")).result(binding) : '' tags << { key: k, value: value } end tags end
get_allocation(public_ip_address)
click to toggle source
# File lib/ec2ex/core.rb, line 211 def get_allocation(public_ip_address) @ec2.describe_addresses(public_ips: [public_ip_address]).addresses.first end
get_ami_tag_hash(instance, tags)
click to toggle source
# File lib/ec2ex/core.rb, line 124 def get_ami_tag_hash(instance, tags) ami_tag_hash = { 'created' => Time.now.strftime('%Y%m%d%H%M%S'), 'tags' => instance.tags.map(&:to_hash).to_json, 'Name' => tags['Name'] } ami_tag_hash['security_groups'] = instance.security_groups.map(&:group_id).to_json ami_tag_hash['private_ip_address'] = instance.private_ip_address unless instance.public_ip_address.nil? ami_tag_hash['public_ip_address'] = instance.public_ip_address end ami_tag_hash['instance_type'] = instance.instance_type ami_tag_hash['placement'] = instance.placement.to_hash.to_json unless instance.iam_instance_profile.nil? ami_tag_hash['iam_instance_profile'] = instance.iam_instance_profile.arn.split('/').last end unless instance.key_name.nil? ami_tag_hash['key_name'] = instance.key_name end ami_tag_hash end
get_document()
click to toggle source
# File lib/ec2ex/core.rb, line 26 def get_document JSON.parse(get_metadata('/latest/dynamic/instance-identity/document/')) end
get_metadata(path)
click to toggle source
# File lib/ec2ex/core.rb, line 30 def get_metadata(path) begin result = {} ::Timeout.timeout(TIME_OUT) { body = open('http://169.254.169.254' + path).read return body } return result rescue TimeoutError => e raise "not EC2 instance" end end
get_old_images(name, num = 10)
click to toggle source
# File lib/ec2ex/core.rb, line 266 def get_old_images(name, num = 10) result = search_image_with_name(name) return [] if result.empty? map = Hash.new{|h,k| h[k] = []} result = result.each{ |image| tag_hash = get_tag_hash(image[:tags]) next if tag_hash['Name'].nil? || tag_hash['created'].nil? map[tag_hash['Name']] << image } old_images = [] map.each do |name, images| sorted_images = images.sort_by{ |image| tag_hash = get_tag_hash(image[:tags]) Time.parse(tag_hash['created']) } newly_images = sorted_images.last(num) old_images = old_images + (sorted_images - newly_images) end old_images end
get_subnet(private_ip_address)
click to toggle source
# File lib/ec2ex/core.rb, line 215 def get_subnet(private_ip_address) subnets = @ec2.describe_subnets.subnets.select{ |subnet| ip = IPAddress(subnet.cidr_block) ip.to_a.map { |ipv4| ipv4.address }.include?(private_ip_address) } subnets.first end
get_tag_hash(tags)
click to toggle source
# File lib/ec2ex/core.rb, line 73 def get_tag_hash(tags) result = {} tags.each {|hash| result[hash['key'] || hash[:key]] = hash['value'] || hash[:value] } Hashie::Mash.new(result) end
get_tag_hash_from_id(instance_id)
click to toggle source
# File lib/ec2ex/core.rb, line 81 def get_tag_hash_from_id(instance_id) preset_tag = {} @ec2.describe_tags(filters: [{ name: 'resource-id', values: [instance_id] }]).tags.each do |tag| preset_tag[tag.key] = tag.value end preset_tag end
group_count(list)
click to toggle source
# File lib/ec2ex/core.rb, line 60 def group_count(list) Hash[list.group_by { |e| e }.map { |k, v| [k, v.length] }] end
images(name)
click to toggle source
# File lib/ec2ex/core.rb, line 287 def images(name) filter = [{ name: 'is-public', values: ['false'] }] filter << { name: 'name', values: [name] } @ec2.describe_images( filters: filter ).data.to_h[:images] end
instances_hash(condition, running_only = true)
click to toggle source
# File lib/ec2ex/core.rb, line 89 def instances_hash(condition, running_only = true) filter = [] condition.each do |key, value| filter << { name: "tag:#{key}", values: ["#{value}"] } end if running_only filter << { name: 'instance-state-name', values: ['running'] } else filter << { name: 'instance-state-name', values: %w(running stopped) } end @ec2.describe_instances( filters: filter ).data.to_h[:reservations].map { |instance| Hashie::Mash.new(instance[:instances].first) } end
instances_hash_first_result(condition, running_only = true)
click to toggle source
# File lib/ec2ex/core.rb, line 104 def instances_hash_first_result(condition, running_only = true) results = instances_hash(condition, running_only) instance = results.first unless instance @logger.warn("not match instance => #{condition}") exit 1 end instance end
instances_hash_with_id(instance_id)
click to toggle source
# File lib/ec2ex/core.rb, line 114 def instances_hash_with_id(instance_id) @ec2.describe_instances( instance_ids: [instance_id] ).data.to_h[:reservations].map { |instance| Hashie::Mash.new(instance[:instances].first) }.first end
latest_image_with_name(name)
click to toggle source
# File lib/ec2ex/core.rb, line 257 def latest_image_with_name(name) result = search_image_with_name(name) result = result.sort_by{ |image| tag_hash = get_tag_hash(image[:tags]) tag_hash['created'].nil? ? '' : tag_hash['created'] } result.empty? ? {} : result.last end
logger()
click to toggle source
# File lib/ec2ex/core.rb, line 22 def logger @logger end
own_tag()
click to toggle source
# File lib/ec2ex/core.rb, line 120 def own_tag get_tag_hash(instances_hash_with_id(get_metadata('/latest/meta-data/instance-id')).tags) end
ping?(private_ip_address)
click to toggle source
# File lib/ec2ex/core.rb, line 323 def ping?(private_ip_address) if private_ip_address pinger = Net::Ping::External.new(private_ip_address) if pinger.ping? @logger.info "already exists private_ip_address => #{private_ip_address}" return true end end return false end
search_image_with_name(name)
click to toggle source
# File lib/ec2ex/core.rb, line 295 def search_image_with_name(name) filter = [{ name: 'is-public', values: ['false'] }] filter << { name: 'tag:Name', values: [name] } @ec2.describe_images( filters: filter ).data.to_h[:images] end
set_delete_on_termination(instance)
click to toggle source
# File lib/ec2ex/core.rb, line 200 def set_delete_on_termination(instance) block_device_mappings = instance.block_device_mappings.map{ |block_device_mapping| ebs = block_device_mapping.ebs { device_name: block_device_mapping.device_name, ebs: { volume_id: block_device_mapping.ebs.volume_id, delete_on_termination: true } } } @ec2.modify_instance_attribute({instance_id: instance.instance_id, block_device_mappings: block_device_mappings}) end
start_instance(instance_id)
click to toggle source
# File lib/ec2ex/core.rb, line 233 def start_instance(instance_id) @logger.info 'starting...' @ec2.start_instances( instance_ids: [instance_id] ) @ec2.wait_until(:instance_running, instance_ids: [instance_id]) @logger.info "start instance complete! instance_id => [#{instance_id}]" end
stop_instance(instance_id)
click to toggle source
# File lib/ec2ex/core.rb, line 223 def stop_instance(instance_id) @logger.info 'stopping...' @ec2.stop_instances( instance_ids: [instance_id], force: true ) @ec2.wait_until(:instance_stopped, instance_ids: [instance_id]) @logger.info "stop instance complete! instance_id => [#{instance_id}]" end
terminate_instance(instance)
click to toggle source
# File lib/ec2ex/core.rb, line 242 def terminate_instance(instance) instance_id = instance.instance_id @logger.info 'terminating...' @ec2.terminate_instances(instance_ids: [instance_id]) @ec2.wait_until(:instance_terminated, instance_ids: [instance_id]) @logger.info "terminate instance complete! instance_id => [#{instance_id}]" end
wait_spot_running(spot_instance_request_id)
click to toggle source
# File lib/ec2ex/core.rb, line 180 def wait_spot_running(spot_instance_request_id) @logger.info 'spot instance creating...' instance_id = nil while true spot_instance_request = @ec2.describe_spot_instance_requests(spot_instance_request_ids: [spot_instance_request_id]).spot_instance_requests.first if spot_instance_request.state == 'active' instance_id = spot_instance_request.instance_id break elsif spot_instance_request.state == 'failed' @logger.info spot_instance_request.fault.code @ec2.cancel_spot_instance_requests({ spot_instance_request_ids: [spot_instance_request_id] }) raise spot_instance_request.fault.message end sleep 10 end @ec2.wait_until(:instance_running, instance_ids: [instance_id]) @logger.info "spot instance create complete! instance_id => [#{instance_id}]" instance_id end