docs: def create(vm_):
      '''
      Create a single VM from a data dict
      '''
      try:
          # Check for required profile parameters before sending any API calls.
          if vm_['profile'] and config.is_profile_configured(__opts__,
                                                             __active_provider_name__ or 'nova',
                                                             vm_['profile'],
                                                             vm_=vm_) is False:
              return False
      except AttributeError:
          pass
  
      deploy = config.get_cloud_config_value('deploy', vm_, __opts__)
      key_filename = config.get_cloud_config_value(
          'ssh_key_file', vm_, __opts__, search_global=False, default=None
      )
      if key_filename is not None and not os.path.isfile(key_filename):
          raise SaltCloudConfigError(
              'The defined ssh_key_file \'{0}\' does not exist'.format(
                  key_filename
              )
          )
  
      vm_['key_filename'] = key_filename
  
      __utils__['cloud.fire_event'](
          'event',
          'starting create',
          'salt/cloud/{0}/creating'.format(vm_['name']),
          args=__utils__['cloud.filter_event']('creating', vm_, ['name', 'profile', 'provider', 'driver']),
          sock_dir=__opts__['sock_dir'],
          transport=__opts__['transport']
      )
      conn = get_conn()
  
      if 'instance_id' in vm_:
          # This was probably created via another process, and doesn't have
          # things like salt keys created yet, so let's create them now.
          if 'pub_key' not in vm_ and 'priv_key' not in vm_:
              log.debug('Generating minion keys for \'%s\'', vm_['name'])
              vm_['priv_key'], vm_['pub_key'] = salt.utils.cloud.gen_keys(
                  salt.config.get_cloud_config_value(
                      'keysize',
                      vm_,
                      __opts__
                  )
              )
          data = conn.server_show_libcloud(vm_['instance_id'])
          if vm_['key_filename'] is None and 'change_password' in __opts__ and __opts__['change_password'] is True:
              vm_['password'] = salt.utils.pycrypto.secure_password()
              conn.root_password(vm_['instance_id'], vm_['password'])
      else:
          # Put together all of the information required to request the instance,
          # and then fire off the request for it
          data, vm_ = request_instance(vm_)
  
          # Pull the instance ID, valid for both spot and normal instances
          vm_['instance_id'] = data.id
  
      try:
          data = salt.utils.cloud.wait_for_ip(
              _query_node_data,
              update_args=(vm_, data, conn),
              timeout=config.get_cloud_config_value(
                  'wait_for_ip_timeout', vm_, __opts__, default=10 * 60),
              interval=config.get_cloud_config_value(
                  'wait_for_ip_interval', vm_, __opts__, default=10),
          )
      except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
          try:
              # It might be already up, let's destroy it!
              destroy(vm_['name'])
          except SaltCloudSystemExit:
              pass
          finally:
              raise SaltCloudSystemExit(six.text_type(exc))
  
      log.debug('VM is now running')
  
      if ssh_interface(vm_) == 'private_ips':
          ip_address = preferred_ip(vm_, data.private_ips)
      elif ssh_interface(vm_) == 'fixed_ips':
          ip_address = preferred_ip(vm_, data.fixed_ips)
      elif ssh_interface(vm_) == 'floating_ips':
          ip_address = preferred_ip(vm_, data.floating_ips)
      else:
          ip_address = preferred_ip(vm_, data.public_ips)
      log.debug('Using IP address %s', ip_address)
  
      if salt.utils.cloud.get_salt_interface(vm_, __opts__) == 'private_ips':
          salt_ip_address = preferred_ip(vm_, data.private_ips)
          log.info('Salt interface set to: %s', salt_ip_address)
      elif salt.utils.cloud.get_salt_interface(vm_, __opts__) == 'fixed_ips':
          salt_ip_address = preferred_ip(vm_, data.fixed_ips)
          log.info('Salt interface set to: %s', salt_ip_address)
      elif salt.utils.cloud.get_salt_interface(vm_, __opts__) == 'floating_ips':
          salt_ip_address = preferred_ip(vm_, data.floating_ips)
          log.info('Salt interface set to: %s', salt_ip_address)
      else:
          salt_ip_address = preferred_ip(vm_, data.public_ips)
          log.debug('Salt interface set to: %s', salt_ip_address)
  
      if not ip_address:
          raise SaltCloudSystemExit('A valid IP address was not found')
  
      vm_['ssh_host'] = ip_address
      vm_['salt_host'] = salt_ip_address
  
      ret = __utils__['cloud.bootstrap'](vm_, __opts__)
  
      ret.update(data.__dict__)
  
      if 'password' in ret['extra']:
          del ret['extra']['password']
  
      log.info('Created Cloud VM \'%s\'', vm_['name'])
      log.debug(
          '\'%s\' VM creation details:\n%s',
          vm_['name'], pprint.pformat(data.__dict__)
      )
  
      event_data = {
          'name': vm_['name'],
          'profile': vm_['profile'],
          'provider': vm_['driver'],
          'instance_id': vm_['instance_id'],
          'floating_ips': data.floating_ips,
          'fixed_ips': data.fixed_ips,
          'private_ips': data.private_ips,
          'public_ips': data.public_ips
      }
  
      __utils__['cloud.fire_event'](
          'event',
          'created instance',
          'salt/cloud/{0}/created'.format(vm_['name']),
          args=__utils__['cloud.filter_event']('created', event_data, list(event_data)),
          sock_dir=__opts__['sock_dir'],
          transport=__opts__['transport']
      )
      __utils__['cloud.cachedir_index_add'](vm_['name'], vm_['profile'], 'nova', vm_['driver'])
      return ret