Skip to content

Commit

Permalink
Add ability to request spot instance pricing
Browse files Browse the repository at this point in the history
  • Loading branch information
sethvargo committed Aug 14, 2014
2 parents a18c88a + 736170b commit 7801b0b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ The EC2 IAM profile name to use.

The default is `nil`.

### <a name="config-spot-instance"></a> price

The price you bid in order to submit a spot request. An additionnal step will be required during the spot request process submission. If no price is set, it will use an on-demand instance.

The default is `nil`.

## <a name="example"></a> Example

The following could be used in a `.kitchen.yml` or in a `.kitchen.local.yml`
Expand Down
47 changes: 45 additions & 2 deletions lib/kitchen/driver/ec2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Ec2 < Kitchen::Driver::SSHBase
default_config :security_group_ids, ['default']
default_config :tags, { 'created-by' => 'test-kitchen' }
default_config :iam_profile_name, nil
default_config :price, nil
default_config :aws_access_key_id do |driver|
ENV['AWS_ACCESS_KEY'] || ENV['AWS_ACCESS_KEY_ID']
end
Expand Down Expand Up @@ -73,9 +74,15 @@ class Ec2 < Kitchen::Driver::SSHBase

def create(state)
return if state[:server_id]
server = create_server
state[:server_id] = server.id
if config[:price]
# Spot instance when a price is set
server = submit_spot
else
# On-demand instance
server = create_server
end

state[:server_id] = server.id
info("EC2 instance <#{state[:server_id]}> created.")
server.wait_for do
print '.'
Expand Down Expand Up @@ -153,6 +160,24 @@ def create_server
)
end

def request_spot
debug_server_config

connection.spot_requests.create(
:availability_zone => config[:availability_zone],
:security_group_ids => config[:security_group_ids],
:tags => config[:tags],
:flavor_id => config[:flavor_id],
:ebs_optimized => config[:ebs_optimized],
:image_id => config[:image_id],
:key_name => config[:aws_ssh_key_id],
:subnet_id => config[:subnet_id],
:iam_instance_profile_name => config[:iam_profile_name],
:price => config[:price],
:instance_count => config[:instance_count]
)
end

def debug_server_config
debug("ec2:region '#{config[:region]}'")
debug("ec2:availability_zone '#{config[:availability_zone]}'")
Expand All @@ -167,6 +192,7 @@ def debug_server_config
debug("ec2:associate_public_ip '#{config[:associate_public_ip]}'")
debug("ec2:ssh_timeout '#{config[:ssh_timeout]}'")
debug("ec2:ssh_retries '#{config[:ssh_retries]}'")
debug("ec2:spot_price'#{config[:price]}'")
end

def amis
Expand Down Expand Up @@ -195,6 +221,23 @@ def hostname(server)
server.dns_name || server.public_ip_address || server.private_ip_address
end
end

def submit_spot
spot = request_spot
info("Spot instance <#{spot.id}> requested.")
info("Spot price is <#{spot.price}>.")
spot.wait_for { print '.'; spot.state == 'active' }
print '(spot active)'

# tag assignation on the instance.
if config[:tags]
connection.create_tags(
spot.instance_id,
spot.tags
)
end
connection.servers.get(spot.instance_id)
end
end
end
end

0 comments on commit 7801b0b

Please sign in to comment.