Launch ec2 test instances inside a VPC

This commit is contained in:
Anders Ingemann 2015-04-08 21:23:21 +02:00
parent 7f4d46a330
commit e47d67bc4f
2 changed files with 76 additions and 29 deletions

View file

@ -5,31 +5,34 @@ log = logging.getLogger(__name__)
def initialize_image(manifest, credentials, bootstrap_info):
from boto.ec2 import connect_to_region
connection = connect_to_region(bootstrap_info._ec2['region'],
aws_access_key_id=credentials['access-key'],
aws_secret_access_key=credentials['secret-key'])
image = AmazonMachineImage(manifest, bootstrap_info._ec2['image'], connection)
image = AmazonMachineImage(manifest, bootstrap_info._ec2['image'],
bootstrap_info._ec2['region'], credentials)
return image
class AmazonMachineImage(Image):
def __init__(self, manifest, image_id, connection):
def __init__(self, manifest, image_id, region, credentials):
super(AmazonMachineImage, self).__init__(manifest)
self.ami = connection.get_image(image_id)
self.connection = connection
from boto.ec2 import connect_to_region as ec2_connect
self.ec2_connection = ec2_connect(region, aws_access_key_id=credentials['access-key'],
aws_secret_access_key=credentials['secret-key'])
from boto.vpc import connect_to_region as vpc_connect
self.vpc_connection = vpc_connect(region, aws_access_key_id=credentials['access-key'],
aws_secret_access_key=credentials['secret-key'])
self.ami = self.ec2_connection.get_image(image_id)
def destroy(self):
log.debug('Deleting AMI')
self.ami.deregister()
for device, block_device_type in self.ami.block_device_mapping.items():
self.connection.delete_snapshot(block_device_type.snapshot_id)
self.ec2_connection.delete_snapshot(block_device_type.snapshot_id)
del self.ami
@contextmanager
def get_instance(self, instance_type):
from ..instances.ec2 import boot_image
name = 'bootstrap-vz test instance'
with boot_image(name, self.ami, instance_type) as instance:
with boot_image(self.ami, instance_type, self.ec2_connection, self.vpc_connection) as instance:
yield instance

View file

@ -5,27 +5,71 @@ log = logging.getLogger(__name__)
@contextmanager
def boot_image(name, image, instance_type):
instance = None
try:
log.debug('Booting ec2 instance')
reservation = image.run(instance_type=instance_type)
[instance] = reservation.instances
instance.add_tag('Name', name)
def boot_image(image, instance_type, ec2_connection, vpc_connection):
def instance_running():
instance.update()
return instance.state == 'running'
if not waituntil(instance_running, timeout=120, interval=3):
raise EC2InstanceStartupException('Timeout while booting instance')
with create_env(ec2_connection, vpc_connection) as boot_env:
if not waituntil(lambda: instance.get_console_output().output is not None, timeout=600, interval=3):
raise EC2InstanceStartupException('Timeout while fetching console output')
def waituntil_instance_is(state):
def instance_has_state():
instance.update()
return instance.state == state
return waituntil(instance_has_state, timeout=600, interval=3)
yield instance
finally:
if instance is not None:
instance.terminate()
instance = None
try:
log.debug('Booting ec2 instance')
reservation = image.run(instance_type=instance_type,
subnet_id=boot_env['subnet_id'])
[instance] = reservation.instances
instance.add_tag('Name', 'bootstrap-vz test instance')
if not waituntil_instance_is('running'):
raise EC2InstanceStartupException('Timeout while booting instance')
if not waituntil(lambda: instance.get_console_output().output is not None, timeout=600, interval=3):
raise EC2InstanceStartupException('Timeout while fetching console output')
yield instance
finally:
if instance is not None:
log.debug('Terminating ec2 instance')
instance.terminate()
if not waituntil_instance_is('terminated'):
raise EC2InstanceStartupException('Timeout while terminating instance')
# wait a little longer, aws can be a little slow sometimes and think the instance is still running
import time
time.sleep(15)
@contextmanager
def create_env(ec2_connection, vpc_connection):
vpc_cidr = '10.0.0.0/28'
subnet_cidr = '10.0.0.0/28'
@contextmanager
def vpc():
log.debug('Creating VPC')
vpc = vpc_connection.create_vpc(vpc_cidr)
try:
yield vpc
finally:
log.debug('Deleting VPC')
vpc_connection.delete_vpc(vpc.id)
@contextmanager
def subnet(vpc):
log.debug('Creating subnet')
subnet = vpc_connection.create_subnet(vpc.id, subnet_cidr)
try:
yield subnet
finally:
log.debug('Deleting subnet')
vpc_connection.delete_subnet(subnet.id)
with vpc() as _vpc:
with subnet(_vpc) as _subnet:
yield {'subnet_id': _subnet.id}
class EC2InstanceStartupException(Exception):