def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NetworkInterface""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() subnet_id = params.get(SUBNET_ID) if not subnet_id: targ = \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[SUBNET_ID] = \ subnet_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) groups = params.get(SEC_GROUPS, []) for targ in utils.find_rels_by_node_type(ctx.instance, SEC_GROUP_TYPE): group_id = \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id and group_id not in groups: groups.append(group_id) params[SEC_GROUPS] = groups # Actually create the resource create_response = iface.create(params)['NetworkInterface'] cleaned_create_response = utils.JsonCleanuper(create_response).to_dict() ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(cleaned_create_response).to_dict() eni_id = cleaned_create_response.get(NETWORKINTERFACE_ID, '') iface.update_resource_id(eni_id) utils.update_resource_id(ctx.instance, eni_id) ctx.instance.runtime_properties['device_index'] = \ cleaned_create_response.get( 'Attachment', {}).get( 'DeviceIndex', ctx.instance.runtime_properties.get('device_index')) modify_network_interface_attribute_args = \ _.get('modify_network_interface_attribute_args') if modify_network_interface_attribute_args: modify_network_interface_attribute_args[NETWORKINTERFACE_ID] = \ eni_id iface.modify_network_interface_attribute( modify_network_interface_attribute_args)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Route Table''' params = dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) # If either of these values is missing, # they must be filled from a connected VPC. if not vpc_id: targ = \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = vpc_id or targ.target\ .instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() route_table_id = create_response.get(ROUTETABLE_ID) iface.update_resource_id(route_table_id) utils.update_resource_id(ctx.instance, route_table_id)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NetworkAcl""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) if not vpc_id: targ = \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = \ vpc_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params)['NetworkAcl'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() network_acl_id = create_response.get(NETWORKACL_ID, '') iface.update_resource_id(network_acl_id) utils.update_resource_id(ctx.instance, network_acl_id)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 Vpc Peering""" params = dict() if not resource_config else resource_config.copy() # Accepter and Requester options are not part of create api, so we # Should check them if they are exists and then remove them accepter_vpc_options = params.get(ACCEPTER_VPC_PEERING_CONNECTION) requester_vpc_options = params.get(REQUESTER_VPC_PEERING_CONNECTION) if accepter_vpc_options: del params[ACCEPTER_VPC_PEERING_CONNECTION] if requester_vpc_options: del params[REQUESTER_VPC_PEERING_CONNECTION] # Actually create the resource create_response = iface.create(params)[VPC_PEERING_CONNECTION] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() if create_response: resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, create_response.get(VPC_PEERING_CONNECTION_ID), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) prepare_describe_vpc_peering_filter(resource_config.copy(), iface)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Security Group''' params = \ dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) # Try to get the group_name and if it does not exits then try to # generate new one based on instance_id group_name = params.get(GROUP_NAME) params[GROUP_NAME] = utils.get_ec2_vpc_resource_name(group_name) if not vpc_id: vpc = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) params[VPC_ID] = \ vpc_id or \ vpc.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() group_id = create_response.get(GROUPID, '') iface.update_resource_id(group_id) utils.update_resource_id(ctx.instance, group_id)
def attach(ctx, iface, resource_config, **_): """ Attaches an AWS EC2 EBS Volume TO Instance :param ctx: :param iface: :param resource_config: :param _: :return: """ params = \ dict() if not resource_config else resource_config.copy() # Attach ebs volume to ec2 instance resource create_response = iface.create(params) # Check if the resource attaching done if create_response: ctx.instance.runtime_properties['eps_attach'] =\ utils.JsonCleanuper(create_response).to_dict() # Update the esp_id (volume_id) esp_id = create_response.get(VOLUME_ID, '') utils.update_resource_id(ctx.instance, esp_id) iface.update_resource_id(esp_id) else: raise NonRecoverableError( '{0} ID# "{1}" reported an empty response' .format(RESOURCE_TYPE_VOLUME_ATTACHMENT, iface.resource_id))
def create(ctx, iface, resource_config, **_): '''Creates AWS EC2 Keypairs''' params = \ dict() if not resource_config else resource_config.copy() params[KEYNAME] = utils.get_resource_name(params.get(KEYNAME)) key_name = params[KEYNAME] if PUBLIC_KEY_MATERIAL in params: create_response = \ iface.import_keypair( params, log_response=ctx.node.properties['log_create_response']) else: create_response = iface.create( params, log_response=ctx.node.properties['log_create_response']) # Allow the end user to store the key material in a secret. if ctx.node.properties['create_secret']: try: client = get_rest_client() except KeyError: # No pun intended. raise NonRecoverableError( 'create_secret is only supported with a Cloudify Manager.') # This makes the line too long for flake8 if included in args. secret_name = ctx.node.properties.get('secret_name', key_name) secrets_count = len(client.secrets.list(key=secret_name)) secret_value = create_response.get('KeyMaterial') try: if secrets_count == 0: client.secrets.create( key=secret_name, value=secret_value) elif secrets_count == 1 and \ ctx.node.properties.get( 'update_existing_secret', False) is True: client.secrets.update( key=secret_name, value=secret_value) except CloudifyClientError as e: raise NonRecoverableError(str(e)) cleaned_create_response = \ utils.JsonCleanuper(create_response).to_dict() # Allow the end user to opt-in to storing the key # material in the runtime properties. # Default is false if 'KeyMaterial' in cleaned_create_response and not \ ctx.node.properties['store_in_runtime_properties']: del cleaned_create_response['KeyMaterial'] ctx.instance.runtime_properties['create_response'] = \ cleaned_create_response iface.update_resource_id(cleaned_create_response.get(KEYNAME)) utils.update_resource_id(ctx.instance, key_name)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Route''' params = dict() if not resource_config else resource_config.copy() routetable_id = params.get(ROUTETABLE_ID) gateway_id = params.get(GATEWAY_ID) natgateway_id = params.get(NATGATEWAY_ID) # If this value is missing, # it must be filled from a connected Route Table. if not routetable_id: targ = \ utils.find_rel_by_node_type(ctx.instance, ROUTETABLE_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, ROUTETABLE_TYPE_DEPRECATED) # Attempt to use the Route Table ID from parameters. # Fallback to connected Route Table. params[ROUTETABLE_ID] = \ routetable_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) ctx.instance.runtime_properties['routetable_id'] = params[ROUTETABLE_ID] ctx.instance.runtime_properties['destination_cidr_block'] = \ params[DESTINATION_CIDR_BLOCK] # If this value is missing, # it must be filled from a connected Route Table. if not gateway_id: targ = \ utils.find_rel_by_node_type(ctx.instance, INTERNETGATEWAY_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, INTERNETGATEWAY_TYPE_DEPRECATED) or \ utils.find_rel_by_node_type(ctx.instance, VPNGATEWAY_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, VPNGATEWAY_TYPE_DEPRECATED) # Attempt to use the Route Table ID from parameters. # Fallback to connected Route Table. if gateway_id or targ: params[GATEWAY_ID] = \ gateway_id or targ.target.instance.runtime_properties\ .get(EXTERNAL_RESOURCE_ID) if not natgateway_id: targ = utils.find_rel_by_node_type(ctx.instance, NATGATEWAY_TYPE) # Attempt to use the Route Table ID from parameters. # Fallback to connected Route Table. if natgateway_id or targ: params[NATGATEWAY_ID] = \ natgateway_id or targ.target.instance.runtime_properties\ .get(EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Internet Gateway''' params = dict() if not resource_config else resource_config.copy() create_response = iface.create(params)['InternetGateway'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id(ctx.instance, create_response.get(INTERNETGATEWAY_ID))
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Vpc''' params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() vpc_id = create_response.get(VPC_ID, '') iface.update_resource_id(vpc_id) utils.update_resource_id(ctx.instance, vpc_id)
def wrapper_inner(**kwargs): '''Inner, worker function''' ctx = kwargs['ctx'] _, _, _, operation_name = ctx.operation.name.split('.') resource_type = kwargs.get('resource_type', 'AWS Resource') iface = kwargs['iface'] # Run the operation if this is the first pass if ctx.operation.retry_number == 0: function(**kwargs) # issue 128 and issue 129 # by updating iface object with actual details from the # AWS response assuming that actual state is available # at ctx.instance.runtime_properties['create_response'] # and ctx.instance.runtime_properties[EXT_RES_ID] # correctly updated after creation # At first let's verify was a new AWS resource # really created if iface.resource_id != \ ctx.instance.runtime_properties.get(EXT_RES_ID): # Assuming new resource was really created, # so updating iface object iface.resource_id = \ ctx.instance.runtime_properties.get(EXT_RES_ID) # If sequence of install -> uninstall workflows was # executed, we should remove '__deleted' # flag set in the decorator wait_for_delete below if '__deleted' in ctx.instance.runtime_properties: del ctx.instance.runtime_properties['__deleted'] # Get a resource interface and query for the status status = iface.status ctx.logger.debug('%s ID# "%s" reported status: %s' % (resource_type, iface.resource_id, status)) if status_pending and status in status_pending: raise OperationRetry( '%s ID# "%s" is still in a pending state.' % (resource_type, iface.resource_id)) elif status_good and status in status_good: if operation_name in ['create', 'configure']: ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(iface.properties).to_dict() elif not status and fail_on_missing: raise NonRecoverableError( '%s ID# "%s" no longer exists but "fail_on_missing" set' % (resource_type, iface.resource_id)) elif status_good and status not in status_good and fail_on_missing: raise NonRecoverableError( '%s ID# "%s" reported an unexpected status: "%s"' % (resource_type, iface.resource_id, status))
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 VPN Gateway""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id(ctx.instance, create_response.get(VPNGATEWAY_ID))
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Subnet''' params = dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) cidr_block = params.get(CIDR_BLOCK) ipv6_cidr_block = params.get(IPV6_CIDR_BLOCK) # If either of these values is missing, # they must be filled from a connected VPC. if not vpc_id or not cidr_block: targ = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = \ vpc_id or \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Attempt to use the CIDR Block from parameters. # Fallback to connected VPC. params[CIDR_BLOCK] = \ cidr_block or \ targ.instance.runtime_properties.get( 'resource_config', {}).get(CIDR_BLOCK) # If ipv6 cidr block is provided by user, then we need to make sure that # The subnet size must use a /64 prefix length if ipv6_cidr_block: ipv6_cidr_block = ipv6_cidr_block[:-2] + '64' params[IPV6_CIDR_BLOCK] = ipv6_cidr_block # Actually create the resource create_response = iface.create(params)[SUBNET] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() subnet_id = create_response.get(SUBNET_ID) iface.update_resource_id(subnet_id) utils.update_resource_id(ctx.instance, subnet_id) modify_subnet_attribute_args = \ _.get('modify_subnet_attribute_args') if modify_subnet_attribute_args: modify_subnet_attribute_args[SUBNET_ID] = \ subnet_id iface.modify_subnet_attribute(modify_subnet_attribute_args)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 DhcpOptions""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() dhcp_options_id = create_response.get(DHCPOPTIONS_ID, '') iface.update_resource_id(dhcp_options_id) utils.update_resource_id(ctx.instance, dhcp_options_id)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 VPN Connection Route""" params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(VPN_CONNECTION_ID), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 ElasticIP""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() elasticip_id = create_response.get(ELASTICIP_ID, '') iface.update_resource_id(elasticip_id) utils.update_resource_id(ctx.instance, elasticip_id) ctx.instance.runtime_properties['allocation_id'] = \ create_response.get(ALLOCATION_ID)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Tags''' params = \ dict() if not resource_config else resource_config.copy() resources = params.get('Resources') if not resources: targets = \ utils.find_rels_by_type( ctx.instance, 'cloudify.relationships.depends_on') resources = \ [rel.target.instance.runtime_properties .get(EXTERNAL_RESOURCE_ID) for rel in targets] params['Resources'] = resources # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NAT Gateway""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() subnet_id = params.get(SUBNET_ID) if not subnet_id: subnet_id = \ utils.find_resource_id_by_type( ctx.instance, SUBNET_TYPE) or \ utils.find_resource_id_by_type( ctx.instance, SUBNET_TYPE_DEPRECATED) params.update({SUBNET_ID: subnet_id}) allocation_id = params.get(ALLOCATION_ID) if not allocation_id: targ = \ utils.find_rel_by_node_type( ctx.instance, ELASTICIP_TYPE) or \ utils.find_rel_by_node_type( ctx.instance, ELASTICIP_TYPE_DEPRECATED) if targ: allocation_id = \ targ.target.instance.runtime_properties.get( ALLOCATION_ID_DEPRECATED) params[ALLOCATION_ID] = allocation_id ctx.instance.runtime_properties['allocation_id'] = \ allocation_id # Actually create the resource create_response = iface.create(params)['NatGateway'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id( ctx.instance, create_response.get(NATGATEWAY_ID))
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NetworkAcl Entry""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() network_acl_id = params.get(NETWORKACL_ID) rule_number = params.get(RULE_NUMBER) egress = params.get(EGRESS) if not network_acl_id: targ = \ utils.find_rel_by_node_type(ctx.instance, NETWORKACL_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, NETWORKACL_TYPE_DEPRECATED) # Attempt to use the NETWORKACL ID from parameters. # Fallback to connected NETWORKACL. params[NETWORKACL_ID] = \ network_acl_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) ctx.instance.runtime_properties['network_acl_id'] = params[NETWORKACL_ID] ctx.instance.runtime_properties['rule_number'] = rule_number ctx.instance.runtime_properties['egress'] = egress filters = {NETWORKACL_IDS: [params[NETWORKACL_ID]]} network_acl_entry = iface.get_properties_by_filter(**filters) entry = network_acl_entry.get(ENTRIES)[0] # for rule in entries: if rule_number == entry.get(RULE_NUMBER): return iface.replace(params) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 Customer Gateway""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() public_ip = params.get(PUBLIC_IP) if not public_ip: targ = \ utils.find_rel_by_node_type(ctx.instance, ELASTICIP_TYPE) if targ: public_ip = \ targ.target.instance.runtime_properties \ .get(ELASTICIP_TYPE_DEPRECATED) params.update({PUBLIC_IP: public_ip}) # Actually create the resource create_response = iface.create(params)['CustomerGateway'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id(ctx.instance, create_response.get(CUSTOMERGATEWAY_ID))
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Subnet''' params = dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) cidr_block = params.get(CIDR_BLOCK) # If either of these values is missing, # they must be filled from a connected VPC. if not vpc_id or not cidr_block: targ = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = \ vpc_id or \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Attempt to use the CIDR Block from parameters. # Fallback to connected VPC. params[CIDR_BLOCK] = \ cidr_block or \ targ.instance.runtime_properties.get( 'resource_config', {}).get(CIDR_BLOCK) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() subnet_id = create_response.get(SUBNET_ID) iface.update_resource_id(subnet_id) utils.update_resource_id(ctx.instance, subnet_id)
def create(ctx, iface, resource_config, **_): '''Creates AWS EC2 Instances''' params = \ dict() if not resource_config else resource_config.copy() params['UserData'] = _handle_userdata(params.get('UserData', '')) # Add subnet from relationship if provided. subnet_id = params.get(SUBNET_ID) if not subnet_id: relationship = utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) if relationship: target = relationship if target: params[SUBNET_ID] = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) del subnet_id, target, relationship # Add security groups from relationships if provided. group_ids = params.get(GROUPIDS, []) relationships = utils.find_rels_by_node_type(ctx.instance, GROUP_TYPE) for relationship in relationships: target = relationship if target is not None: group_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id not in group_ids: group_ids.append(group_id) del group_id del target, relationship params[GROUPIDS] = group_ids # Get all nics from relationships. nics_from_rels = [] relationships = utils.find_rels_by_node_type(ctx.instance, NETWORK_INTERFACE_TYPE) for relationship in relationships: target = relationship if target is not None: rel_nic_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) rel_device_index = target.target.instance.runtime_properties.get( 'device_index') rel_nic = {NIC_ID: rel_nic_id, DEVICE_INDEX: rel_device_index} nics_from_rels.append(rel_nic) del target, rel_nic_id, rel_device_index, rel_nic # Get all nics from the resource_config dict. nics_from_params = params.get(NETWORK_INTERFACES, []) # Merge the two lists. merged_nics = [] nics = defaultdict(dict) for nic in (nics_from_rels, nics_from_params): for i in nic: nics[i[NIC_ID]].update(i) merged_nics = nics.values() del nic, nics for counter, nic in enumerate( sorted(merged_nics, key=lambda k: k.get(DEVICE_INDEX))): if not nic[DEVICE_INDEX]: nic[DEVICE_INDEX] = counter params[NETWORK_INTERFACES] = merged_nics create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() try: instance = create_response[INSTANCES][0] except (KeyError, IndexError) as e: raise NonRecoverableError( 'Error {0}: create response has no instances: {1}'.format( e.message, create_response)) instance_id = instance.get(INSTANCE_ID, '') iface.update_resource_id(instance_id) utils.update_resource_id(ctx.instance, instance_id) modify_instance_attribute_args = \ _.get('modify_instance_attribute_args') if modify_instance_attribute_args: modify_instance_attribute_args[INSTANCE_ID] = \ instance_id iface.modify_instance_attribute(modify_instance_attribute_args)