in syndicate/core/resources/ec2_resource.py [0:0]
def _create_ec2_from_meta(self, name, meta):
from syndicate.core import CONF_PATH
# checking required parameters
image_id = meta['image_id']
image_data = self.ec2_conn.describe_image(image_id=image_id)
if not image_data:
raise AssertionError(f'Image id {image_id} is invalid')
instance_type = meta.get('instance_type')
if not instance_type:
raise AssertionError('Instance type must be specified')
if instance_type not in InstanceTypes.from_botocore():
raise AssertionError(f'Not available instance type: {instance_type}')
key_name = meta.get('key_name')
if not self.ec2_conn.if_key_pair_exists(key_name):
raise AssertionError(f'There is no key pair with name: {key_name}')
availability_zone = meta.get('availability_zone')
subnet = meta.get('subnet_id')
if availability_zone:
subnet_filter = {
'Name': 'availabilityZone',
'Values': [availability_zone]
}
subnet_list = self.ec2_conn.list_subnets(filters=[subnet_filter])
if subnet and subnet not in \
[subnet_ids['SubnetId'] for subnet_ids in subnet_list]:
raise AssertionError(
f'There is no available Subnets with name {subnet} in '
f'Availability Zone {availability_zone}.'
)
if availability_zone not in self.ec2_conn.get_azs():
raise AssertionError(
f'There is no Availability Zone with name: {availability_zone}'
)
security_groups_names = meta.get('security_group_names')
if security_groups_names:
sg_meta = self.ec2_conn.describe_security_groups(
security_groups_names)
described_sec_groups_names = [security_group['GroupName']
for security_group in sg_meta]
for security_group_name in security_groups_names:
if security_group_name not in described_sec_groups_names:
raise AssertionError(
f'Security group {security_group_name} does not exist'
)
# checking optional parameters
user_data_file_name = meta.get('userdata_file')
user_data_content = None
if user_data_file_name:
user_data_location = os.path.join(CONF_PATH, user_data_file_name)
if not os.path.isfile(user_data_location):
_LOG.warning(
f'There is no user data {user_data_file_name} found by path'
f' {CONF_PATH}'
)
else:
with open(user_data_location, 'r') as userdata_file:
user_data_content = userdata_file.read()
# describing instance profile by iam role name
iam_role_name = meta.get('iam_role')
iam_instance_profile_object = None
if iam_role_name:
instance_profiles = self.iam_conn.get_instance_profiles_for_role(
role_name=iam_role_name)
if instance_profiles:
iam_profile_meta = instance_profiles[0]
iam_instance_profile_arn = iam_profile_meta['Arn']
iam_instance_profile_object = {'Arn': iam_instance_profile_arn}
# launching instance
response = self.ec2_conn.launch_instance(
name=name,
image_id=image_id,
instance_type=instance_type,
key_name=key_name,
tags=meta.get('tags'),
security_groups_names=meta.get('security_group_names'),
security_group_ids=meta.get('security_group_ids'),
user_data=user_data_content,
iam_instance_profile=iam_instance_profile_object,
subnet_id=meta.get('subnet_id'),
availability_zone=availability_zone
)
if meta.get('disableApiTermination'):
disable_api_termination = meta.get('disableApiTermination')
_LOG.debug(
f'Found disableApiTermination property: '
f'{disable_api_termination}'
)
if str(disable_api_termination).lower() == 'true':
self.ec2_conn.modify_instance_attribute(
InstanceId=response['InstanceId'],
DisableApiTermination={'Value': True},
)
_LOG.info(
f'Created EC2 instance {name}. Waiting for instance network '
f'interfaces configuring.'
)
sleep(30) # time for vm to become running
return self.describe_ec2(name, meta, response)