Skip to content

Instantly share code, notes, and snippets.

@kntyskw
Last active December 20, 2015 22:58
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 kntyskw/6208497 to your computer and use it in GitHub Desktop.
Save kntyskw/6208497 to your computer and use it in GitHub Desktop.
Assign EIPs given from the standard input to ENIs assigned to the instance
#!/bin/env ruby
require 'rubygems'
require 'aws-sdk'
@ec2 = AWS::EC2.new({:region => ENV['AWS_DEFAULT_REGION']})
@eips_to_assign = ARGV # [EIP1 EIP2 EIP3 EIP4 ...]
DEBUG=false
def self.main
instance = @ec2.instances[`curl http://169.254.169.254/latest/meta-data/instance-id`]
puts "Instance #{instance.id} exists" if instance.exists? && DEBUG
puts "Instance #{instance.id} is in a VPC " if instance.vpc? && DEBUG
puts "Instance #{instance.id} has #{instance.network_interfaces.length} ENIs " if DEBUG
#raise "# of EIPs needs to be factor of # of network interfaces" if @eips_to_assign.length % instance.network_interfaces.length
naddr_assign_per_interface = (@eips_to_assign.length.to_f / instance.network_interfaces.length).ceil
puts "# of EIPs to assign per ENI = #{naddr_assign_per_interface}" if DEBUG
instance.network_interfaces.each do |interface|
if interface.private_ip_addresses.length < naddr_assign_per_interface
@ec2.client.assign_private_ip_addresses({
:network_interface_id => interface.id,
:secondary_private_ip_address_count => naddr_assign_per_interface - interface.private_ip_addresses.length
})
end
i = 0
while i < naddr_assign_per_interface do
eip = get_next_eip_to_assign
if eip == nil
break
end
if eip.associated?
if eip.network_interface.id == interface.id
puts "#{eip.public_ip} is already associated to #{interface.id}" if DEBUG
i = i + 1
next
elsif has_network_interface?(instance, eip.network_interface)
puts "#{eip.public_ip} is already associated to instace #{instance.id}" if DEBUG
next
else
eip.disassociate
end
end
success = associate_addr_to_instance(instance, interface, eip)
if success
i = i + 1
else
puts "ERROR: Failed to associate address #{eip.public_ip}" if DEBUG
end
end
end
puts output_private_ipaddresses instance
end
def self.get_next_eip_to_assign
while @eips_to_assign.empty? == false
ipaddr = @eips_to_assign.shift
eip = @ec2.elastic_ips[ipaddr]
if eip != nil
return eip
end
puts "#{ipaddr} is not an valid EIP or not associated with the account. Will skip." if DEBUG
end
return nil
end
def self.has_network_interface? (instance, target_interface)
instance.network_interfaces.each do |interface|
return true if interface == target_interface
end
return false
end
def self.associate_addr_to_instance(instance, target_interface, eip)
puts "associating #{eip.public_ip} to interface #{target_interface.id}" if DEBUG
return true if self.associate_addr(target_interface, eip)
instance.network_interfaces.each do |interface|
if target_interface.id != interface.id
return true if self.associate_addr(interface, eip)
end
end
return false
end
def self.associate_addr(interface, eip)
interface.private_ip_addresses.each do |private_ip|
begin
@ec2.client.associate_address({
:private_ip_address => private_ip[:private_ip_address],
:network_interface_id => interface.id,
:allocation_id => eip.allocation_id,
:allow_reassociation => true
})
puts "#{eip.public_ip} is associated to #{interface.id}" if DEBUG
return true
rescue
puts $! if DEBUG
end
end
return false
end
def self.output_private_ipaddresses(instance)
ipaddrs = []
instance.network_interfaces.each do |interface|
interface.private_ip_addresses.each do |private_ip|
ipaddrs.push private_ip[:private_ip_address]
end
end
ipaddrs.join(',')
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment