def run_on_demand_instance()

in scripts/autoscaling/aws/nodeup.py [0:0]


def run_on_demand_instance(ec2, aws_region, ins_img, ins_key, ins_type, ins_hdd,
                           kms_encyr_key_id, run_id, pool_id, user_data_script, num_rep, time_rep, swap_size,
                           kube_client, instance_additional_spec, availability_zone, security_groups, subnet,
                           network_interface, is_dedicated, performance_network, input_tags):
    pipe_log('Creating on demand instance')
    allowed_networks = get_networks_config(ec2, aws_region, ins_type)
    additional_args = instance_additional_spec if instance_additional_spec else {}

    subnet_id = None
    az_name = None
    if subnet:
        subnet_id = get_specified_subnet(subnet, availability_zone)
    elif allowed_networks and len(allowed_networks) > 0:
        if availability_zone:
            pipe_log('- Desired availability zone {} was specified, trying to use it'.format(availability_zone))
            for az_name, az_subnet_id in allowed_networks.iteritems():
                if az_name == availability_zone:
                    az_name = availability_zone
                    subnet_id = az_subnet_id
                    break
        if subnet_id is None:
            az_num = randint(0, len(allowed_networks)-1)
            az_name = allowed_networks.items()[az_num][0]
            subnet_id = allowed_networks.items()[az_num][1]
        pipe_log('- Networks list found, subnet {} in AZ {} will be used'.format(subnet_id, az_name))


    if network_interface:
        if subnet_id:
            pipe_log('- Network interface specified. Desired subnet id {} and performance network config will be ignored.'.format(subnet_id))
        network_interface, subnet_id, az_name = fetch_network_interface_info(ec2, network_interface, availability_zone, allowed_networks)
        additional_args.update({
            "NetworkInterfaces": [
                {
                    "DeviceIndex": 0,
                    "NetworkInterfaceId": network_interface
                }
            ]
        })
    elif performance_network:
        pipe_log('- Performance network requested.')
        if not subnet or not subnet_id:
            pipe_log('- Subnet is not specified, trying to get a random one...')
            subnet_id = get_random_subnet(ec2)
            pipe_log('- Subnet: {} will be used.'.format(subnet_id))

        if subnet_id:
            additional_args.update({
                "NetworkInterfaces": [
                    {
                        'DeleteOnTermination': True,
                        'DeviceIndex': 0,
                        'SubnetId': subnet_id,
                        'Groups': get_security_groups(aws_region, security_groups),
                        'InterfaceType': 'efa'
                    }
                ]
            })
        else:
            pipe_log('- Cannot define subnet to be launched in, will skip performance network setup and continue with default options...')
            pipe_log('- Default subnet in random AZ will be used')
            additional_args.update({'SecurityGroupIds': get_security_groups(aws_region, security_groups)})

    elif subnet_id:
        additional_args.update({
            'SubnetId': subnet_id,
            'SecurityGroupIds': get_security_groups(aws_region, security_groups)
        })
    else:
        pipe_log('- Networks list NOT found, default subnet in random AZ will be used')
        additional_args.update({'SecurityGroupIds': get_security_groups(aws_region, security_groups)})

    if is_dedicated:
        additional_args.update({
            "Placement": {
                'Tenancy': "dedicated"
            }
        })
    if 'MetadataOptions' not in additional_args:
        additional_args.update({'MetadataOptions': {
            'HttpTokens': 'optional',
            'HttpPutResponseHopLimit': 2,
            'HttpEndpoint': 'enabled'
        }})
    response = {}
    try:
        response = ec2.run_instances(
            ImageId=ins_img,
            MinCount=1,
            MaxCount=1,
            KeyName=ins_key,
            InstanceType=ins_type,
            UserData=user_data_script,
            BlockDeviceMappings=get_block_devices(ec2, ins_img, ins_type, ins_hdd, kms_encyr_key_id, swap_size),
            TagSpecifications=[
                {
                    'ResourceType': 'instance',
                    "Tags": get_tags(run_id, aws_region, pool_id, input_tags)
                }
            ],
            **additional_args
        )
    except ClientError as client_error:
        if 'InstanceLimitExceeded' in client_error.message:
            pipe_log_warn(LIMIT_EXCEEDED_ERROR_MASSAGE)
            sys.exit(LIMIT_EXCEEDED_EXIT_CODE)
        elif 'InsufficientInstanceCapacity' in client_error.message:
            pipe_log_warn(INSUFFICIENT_CAPACITY_ERROR_MASSAGE)
            sys.exit(INSUFFICIENT_CAPACITY_EXIT_CODE)
        else:
            raise client_error

    ins_id = response['Instances'][0]['InstanceId']
    ins_ip = response['Instances'][0]['PrivateIpAddress']

    pipe_log('- Instance created. ID: {}, IP: {}'.format(ins_id, ins_ip))

    status_code = get_current_status(ec2, ins_id)

    rep = 0
    while status_code != RUNNING:
        pipe_log('- Waiting for status checks completion...')
        sleep(time_rep)
        status_code = get_current_status(ec2, ins_id)
        rep = increment_or_fail(num_rep,
                                rep,
                                'Exceeded retry count ({}) for instance ({}) status check'.format(num_rep, ins_id),
                                ec2_client=ec2,
                                kill_instance_id_on_fail=ins_id,
                                kube_client=kube_client)
    pipe_log('Instance created. ID: {}, IP: {}\n-'.format(ins_id, ins_ip))

    ebs_tags = resource_tags(aws_region)
    if input_tags:
        ebs_tags.extend(input_tags)
    if ebs_tags:
        instance_description = ec2.describe_instances(InstanceIds=[ins_id])['Reservations'][0]['Instances'][0]
        volumes = instance_description['BlockDeviceMappings']
        for volume in volumes:
            ec2.create_tags(
                Resources=[volume['Ebs']['VolumeId']],
                Tags=ebs_tags)

    return ins_id, ins_ip