Skip to content

Instantly share code, notes, and snippets.

@iconara
Created November 2, 2012 14:47
Show Gist options
  • Save iconara/4001792 to your computer and use it in GitHub Desktop.
Save iconara/4001792 to your computer and use it in GitHub Desktop.
Start spot instances
require 'aws'
require 'pry'
require 'open-uri'
require 'base64'
class Starter
def initialize(ec2)
@ec2 = ec2
end
def start!
request_ids = request_instances
instance_ids = wait_for_instances(request_ids)
instances = instance_ids.map { |iid| @ec2.instances[iid] }
tag_instances(instances)
wait_for_haproxy(instances)
instances
end
private
def request_instances
$stderr.puts('Requesting instances')
zones = %w(eu-west-1a eu-west-1b eu-west-1c)
responses = zones.map do |zone|
@ec2.client.request_spot_instances(spot_request_spec(zone))
end
responses.flat_map { |r| r[:spot_instance_request_set].map { |rr| rr[:spot_instance_request_id] } }
end
def spot_request_spec(zone)
{
spot_price: '0.3',
instance_count: 1,
launch_specification: {
image_id: AMI_WITH_HA_PROXY,
key_name: FILL_THIS_IN,
instance_type: 'c1.xlarge',
iam_instance_profile: {
arn: 'arn:aws:iam::99999999999:instance-profile/THE_NAME_GOES_HERE'
},
placement: {
availability_zone: zone
},
user_data: user_data
}
}
end
def user_data
@user_data ||= Base64.encode64(File.read(File.expand_path(PATH_TO_CLOUD_INIT_FILE, __FILE__)))
end
def wait_for_instances(request_ids)
$stderr.puts('Waiting for instances')
loop do
response = @ec2.client.describe_spot_instance_requests(:spot_instance_request_ids => request_ids)
statuses = response[:spot_instance_request_set].map { |rr| rr[:state] }
if statuses.all? { |s| s == 'active' }
$stderr.puts('Instances active')
return response[:spot_instance_request_set].map { |rr| rr[:instance_id] }
end
$stderr.puts("Statuses: #{statuses.join(', ')}")
sleep(5)
end
end
def tag_instances(instances)
instances.each do |instance|
zone = instance.availability_zone.split('-').last
instance.tag('Name', value: "testlb-#{zone}")
instance.tag('HAProxy', value: 'lb')
instance.tag('Role', value: 'lb')
instance.tag('Environment', value: 'test')
end
$stderr.puts('Instances tagged')
end
def wait_for_haproxy(instances)
$stderr.puts('Waiting for HAProxy')
dns_names = Hash[instances.map { |i| [i.tags['Name'], i.public_dns_name] }]
dns_names.each do |name, dns_name|
$stderr.puts("#{name} #{dns_name}")
end
loop do
break if dns_names.all? do |name, dns_name|
begin
open("http://#{dns_name}/").read
$stderr.puts("HAProxy on #{name} started")
true
rescue => e
false
end
end
end
$stderr.puts('HAProxy started on all instances')
end
end
ec2 = AWS::EC2.new(ec2_endpoint: 'ec2.eu-west-1.amazonaws.com')
Starter.new(ec2).start!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment