class Provisionator::Ec2Launcher

Public Class Methods

launch(options={}) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 8
def self.launch options={}
  new(options).launch
end
new(options={}) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 12
def initialize options={}
  %w{ AWS_REGION AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY}.each do |env_var|
    raise "ENV['#{env_var}'] is required to be set"            unless ENV[env_var]
  end

  @options = options
  @options[:instance_type] ||= ENV['P_INSTANCE_TYPE'] || 'm1.small'
  @options[:no_release] ||= ENV['P_NO_RELEASE']
  @options[:ami_id] ||= ENV['P_AMI_ID'] || ami_id
  @options[:ebs_volumes] ||= []
  @options[:key_name] ||= ENV['P_KEY_NAME']
  @options[:security_groups] ||= ENV['P_SECURITY_GROUPS'].try(:split, ',')
  @options[:availability_zones] ||= ENV['P_AVAILABILITY_ZONES'].try(:split, ',') || ec2.availability_zones.map(&:name)
  @options[:instance_count] ||= ENV['P_INSTANCE_COUNT'].try(:to_i) || 1
  @options[:load_balancer_name] ||= ENV['P_LOAD_BALANCER_NAME']

  [:app_name, :chef_node, :ami_id, :key_name, :security_groups].each do |option|
    raise "option ':#{option}' is required" if options[option].nil?
  end
end

Public Instance Methods

launch() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 33
def launch     
  puts "Launching #{@options[:instance_count]} #{@options[:instance_type]} instance/s..." 

  instances = launch_instances
  wait_for_instances instances          
  register_with_load_balancer instances
  assign_elastic_ip instances.first

  instances.each do |instance|
    puts "Launched instance #{instance.id}, status: #{instance.status}, public dns: #{instance.dns_name}, public ip: #{instance.ip_address}"
  end
end

Private Instance Methods

ami_id() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 48
def ami_id
  case ENV['AWS_REGION']
  when 'us-east-1'
    'ami-bbf799d2'
  when 'ap-southeast-2'
    'ami-b792008d'
  else
    raise "no ami-id defined for region '#{ENV['AWS_REGION']}'"
  end
end
assign_elastic_ip(instance) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 59
def assign_elastic_ip instance
  return unless @options[:elastic_ip]
  puts "Assigning #{@options[:elastic_ip]} to #{instance.id}"
  ec2.client.associate_address instance_id: instance.id, public_ip: @options[:elastic_ip]
end
block_device_mappings() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 113
def block_device_mappings
  @block_device_mappings ||= begin
    available_device_mappings = ("/dev/sdf".."/dev/sdp").to_a
    @options[:ebs_volumes].inject({}) do |mappings, ebs_volume|
      mappings[available_device_mappings.shift] = { 
        volume_size: ebs_volume[:size],
        delete_on_termination: ebs_volume[:delete_on_termination]
      }
      mappings
    end
  end
end
ec2() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 101
def ec2
  @ec2 ||= AWS::EC2.new
end
elb() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 105
def elb
  @elb ||= AWS::ELB::Client.new
end
launch_instances() click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 80
def launch_instances
  (1..@options[:instance_count]).map do
    availability_zone = @options[:availability_zones].rotate!.first
    instance_options = {
      image_id: @options[:ami_id],
      availability_zone: availability_zone,
      key_name: @options[:key_name],
      security_groups: @options[:security_groups],
      instance_type: @options[:instance_type],
      user_data: user_data,
      count: 1
    }
    instance_options.merge!(block_device_mappings: block_device_mappings) if block_device_mappings.keys.any?
    instance = ec2.instances.create(instance_options)

    instance.tags['Name'] = "#{@options[:app_name]}-#{@options[:chef_node]}-#{availability_zone.split('').last}-#{instance.id}"
    puts "Launching instance '#{instance.id}' in availability_zone '#{availability_zone}...'"
    instance
  end
end
register_with_load_balancer(instances) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 65
def register_with_load_balancer instances
  if @options[:load_balancer_name]
    puts "Registering with load balancer..."
    elb.register_instances_with_load_balancer(
      load_balancer_name: @options[:load_balancer_name],
      instances: instances.map{|i| {instance_id: i.id}}
    )
  end
end
user_data(attributes={}) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 109
def user_data attributes={}
  @user_data ||= Provisionator::Ec2Userdata.new(@options).render
end
wait_for_instances(instances) click to toggle source
# File lib/provisionator/ec2_launcher.rb, line 75
def wait_for_instances instances
  puts "Waiting for instances to boot..."
  sleep 1 until instances.all?{|instance| instance.status != :pending}
end