docs: def wait_for_instance(
          vm_=None,
          data=None,
          ip_address=None,
          display_ssh_output=True,
          call=None,
      ):
      '''
      Wait for an instance upon creation from the EC2 API, to become available
      '''
      if call == 'function':
          # Technically this function may be called other ways too, but it
          # definitely cannot be called with --function.
          raise SaltCloudSystemExit(
              'The wait_for_instance action must be called with -a or --action.'
          )
  
      if vm_ is None:
          vm_ = {}
  
      if data is None:
          data = {}
  
      ssh_gateway_config = vm_.get(
          'gateway', get_ssh_gateway_config(vm_)
      )
  
      __utils__['cloud.fire_event'](
          'event',
          'waiting for ssh',
          'salt/cloud/{0}/waiting_for_ssh'.format(vm_['name']),
          args={'ip_address': ip_address},
          sock_dir=__opts__['sock_dir'],
          transport=__opts__['transport']
      )
  
      ssh_connect_timeout = config.get_cloud_config_value(
          'ssh_connect_timeout', vm_, __opts__, 900   # 15 minutes
      )
      ssh_port = config.get_cloud_config_value(
          'ssh_port', vm_, __opts__, 22
      )
  
      if config.get_cloud_config_value('win_installer', vm_, __opts__):
          username = config.get_cloud_config_value(
              'win_username', vm_, __opts__, default='Administrator'
          )
          win_passwd = config.get_cloud_config_value(
              'win_password', vm_, __opts__, default=''
          )
          win_deploy_auth_retries = config.get_cloud_config_value(
              'win_deploy_auth_retries', vm_, __opts__, default=10
          )
          win_deploy_auth_retry_delay = config.get_cloud_config_value(
              'win_deploy_auth_retry_delay', vm_, __opts__, default=1
          )
          use_winrm = config.get_cloud_config_value(
              'use_winrm', vm_, __opts__, default=False
          )
          winrm_verify_ssl = config.get_cloud_config_value(
              'winrm_verify_ssl', vm_, __opts__, default=True
          )
  
          if win_passwd and win_passwd == 'auto':
              log.debug('Waiting for auto-generated Windows EC2 password')
              while True:
                  password_data = get_password_data(
                      name=vm_['name'],
                      kwargs={
                          'key_file': vm_['private_key'],
                      },
                      call='action',
                  )
                  win_passwd = password_data.get('password', None)
                  if win_passwd is None:
                      log.debug(password_data)
                      # This wait is so high, because the password is unlikely to
                      # be generated for at least 4 minutes
                      time.sleep(60)
                  else:
                      logging_data = password_data
  
                      logging_data['password'] = 'XXX-REDACTED-XXX'
                      logging_data['passwordData'] = 'XXX-REDACTED-XXX'
                      log.debug(logging_data)
  
                      vm_['win_password'] = win_passwd
                      break
  
          # SMB used whether psexec or winrm
          if not salt.utils.cloud.wait_for_port(ip_address,
                                                port=445,
                                                timeout=ssh_connect_timeout):
              raise SaltCloudSystemExit(
                  'Failed to connect to remote windows host'
              )
  
          # If not using winrm keep same psexec behavior
          if not use_winrm:
  
              log.debug('Trying to authenticate via SMB using psexec')
  
              if not salt.utils.cloud.validate_windows_cred(ip_address,
                                                            username,
                                                            win_passwd,
                                                            retries=win_deploy_auth_retries,
                                                            retry_delay=win_deploy_auth_retry_delay):
                  raise SaltCloudSystemExit(
                      'Failed to authenticate against remote windows host (smb)'
                  )
  
          # If using winrm
          else:
  
              # Default HTTPS port can be changed in cloud configuration
              winrm_port = config.get_cloud_config_value(
                  'winrm_port', vm_, __opts__, default=5986
              )
  
              # Wait for winrm port to be available
              if not salt.utils.cloud.wait_for_port(ip_address,
                                                    port=winrm_port,
                                                    timeout=ssh_connect_timeout):
                  raise SaltCloudSystemExit(
                      'Failed to connect to remote windows host (winrm)'
                  )
  
              log.debug('Trying to authenticate via Winrm using pywinrm')
  
              if not salt.utils.cloud.wait_for_winrm(ip_address,
                                                            winrm_port,
                                                            username,
                                                            win_passwd,
                                                            timeout=ssh_connect_timeout,
                                                            verify=winrm_verify_ssl):
                  raise SaltCloudSystemExit(
                      'Failed to authenticate against remote windows host'
                  )
  
      elif salt.utils.cloud.wait_for_port(ip_address,
                                          port=ssh_port,
                                          timeout=ssh_connect_timeout,
                                          gateway=ssh_gateway_config
                                          ):
          # If a known_hosts_file is configured, this instance will not be
          # accessible until it has a host key. Since this is provided on
          # supported instances by cloud-init, and viewable to us only from the
          # console output (which may take several minutes to become available,
          # we have some more waiting to do here.
          known_hosts_file = config.get_cloud_config_value(
              'known_hosts_file', vm_, __opts__, default=None
          )
          if known_hosts_file:
              console = {}
              while 'output_decoded' not in console:
                  console = get_console_output(
                      instance_id=vm_['instance_id'],
                      call='action',
                      location=get_location(vm_)
                  )
                  pprint.pprint(console)
                  time.sleep(5)
              output = salt.utils.stringutils.to_unicode(console['output_decoded'])
              comps = output.split('-----BEGIN SSH HOST KEY KEYS-----')
              if len(comps) < 2:
                  # Fail; there are no host keys
                  return False
  
              comps = comps[1].split('-----END SSH HOST KEY KEYS-----')
              keys = ''
              for line in comps[0].splitlines():
                  if not line:
                      continue
                  keys += '\n{0} {1}'.format(ip_address, line)
  
              with salt.utils.files.fopen(known_hosts_file, 'a') as fp_:
                  fp_.write(salt.utils.stringutils.to_str(keys))
              fp_.close()
  
          for user in vm_['usernames']:
              if salt.utils.cloud.wait_for_passwd(
                  host=ip_address,
                  port=ssh_port,
                  username=user,
                  ssh_timeout=config.get_cloud_config_value(
                      'wait_for_passwd_timeout', vm_, __opts__, default=1 * 60
                  ),
                  key_filename=vm_['key_filename'],
                  display_ssh_output=display_ssh_output,
                  gateway=ssh_gateway_config,
                  maxtries=config.get_cloud_config_value(
                      'wait_for_passwd_maxtries', vm_, __opts__, default=15
                  ),
                  known_hosts_file=config.get_cloud_config_value(
                      'known_hosts_file', vm_, __opts__,
                      default='/dev/null'
                  ),
              ):
                  __opts__['ssh_username'] = user
                  vm_['ssh_username'] = user
                  break
          else:
              raise SaltCloudSystemExit(
                  'Failed to authenticate against remote ssh'
              )
      else:
          raise SaltCloudSystemExit(
              'Failed to connect to remote ssh'
          )
  
      if 'reactor' in vm_ and vm_['reactor'] is True:
          __utils__['cloud.fire_event'](
              'event',
              'ssh is available',
              'salt/cloud/{0}/ssh_ready_reactor'.format(vm_['name']),
              args={'ip_address': ip_address},
              sock_dir=__opts__['sock_dir'],
              transport=__opts__['transport']
          )
  
      return vm_