def create_instances(ec2_resource: ServiceResource, image_id: str, key_name: str, instance_type: str, num_instances: int = 1, security_group_ids: Optional[List] = None, user_data: Optional[Union[str, bytes]] = None, block_device_map: Optional[List[Dict]] = None, instance_profile_arn: Optional[str] = None, placement_az: Optional[str] = None, subnet_id: str = None, tags: Optional[Dict[str, str]] = None) -> List[dict]: """ Replaces create_ondemand_instances. Uses boto3 and returns a list of Boto3 instance dicts. See "create_instances" (returns a list of ec2.Instance objects): https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.ServiceResource.create_instances Not to be confused with "run_instances" (same input args; returns a dictionary): https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.run_instances Tags, if given, are applied to the instances, and all volumes. """ logger.info('Creating %s instance(s) ... ', instance_type) if isinstance(user_data, str): user_data = user_data.encode('utf-8') request = {'ImageId': image_id, 'MinCount': num_instances, 'MaxCount': num_instances, 'KeyName': key_name, 'SecurityGroupIds': security_group_ids, 'InstanceType': instance_type, 'UserData': user_data, 'BlockDeviceMappings': block_device_map, 'SubnetId': subnet_id} if instance_profile_arn: # We could just retry when we get an error because the ARN doesn't # exist, but we might as well wait for it. wait_until_instance_profile_arn_exists(instance_profile_arn) # Add it to the request request['IamInstanceProfile'] = {'Arn': instance_profile_arn} if placement_az: request['Placement'] = {'AvailabilityZone': placement_az} if tags: # Tag everything when we make it. flat_tags = flatten_tags(tags) request['TagSpecifications'] = [{'ResourceType': 'instance', 'Tags': flat_tags}, {'ResourceType': 'volume', 'Tags': flat_tags}] return ec2_resource.create_instances(**prune(request))
def create_instances(ec2: ServiceResource, image_id: str, key_name: str, instance_type: str, instance_profile_arn: Dict, num_instances: int = 1, security_group_ids: Optional[List] = None, user_data: Optional[bytes] = None, block_device_map: Optional[List[Dict]] = None, placement: Optional[Dict] = None, subnet_id: str = None): """ Replaces create_ondemand_instances. Uses boto3. See "create_instances" (returns a list of ec2.Instance objects): https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.ServiceResource.create_instances Not to be confused with "run_instances" (same input args; returns a dictionary): https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.run_instances """ log.info('Creating %s instance(s) ... ', instance_type) wait_until_instance_profile_arn_exists(instance_profile_arn) request = { 'ImageId': image_id, 'MinCount': num_instances, 'MaxCount': num_instances, 'KeyName': key_name, 'SecurityGroupIds': security_group_ids, 'InstanceType': instance_type, 'UserData': user_data, 'Placement': placement, 'BlockDeviceMappings': block_device_map, 'IamInstanceProfile': instance_profile_arn, 'SubnetId': subnet_id } # remove empty args actual_request = dict() for key in request: if request[key]: actual_request[key] = request[key] return ec2.create_instances(**actual_request)