async function init()

in packages/amplify-provider-awscloudformation/src/amplify-service-manager.js [14:205]


async function init(amplifyServiceParams) {
  const { context, awsConfigInfo, projectName, envName, stackName } = amplifyServiceParams;

  let amplifyAppId;
  let verifiedStackName = stackName;
  let deploymentBucketName = `${stackName}-deployment`;

  const amplifyClient = await getConfiguredAmplifyClient(context, awsConfigInfo);
  if (!amplifyClient) {
    // This happens when the Amplify service is not available in the region
    return {
      amplifyAppId,
      verifiedStackName,
      deploymentBucketName,
    };
  }

  const hasPermission = await checkAmplifyServiceIAMPermission(context, amplifyClient);
  if (!hasPermission) {
    return {
      amplifyAppId,
      verifiedStackName,
      deploymentBucketName,
    };
  }

  if (context.exeInfo && context.exeInfo.inputParams && context.exeInfo.inputParams.amplify && context.exeInfo.inputParams.amplify.appId) {
    const inputAmplifyAppId = context.exeInfo.inputParams.amplify.appId;
    const log = logger('init.amplifyClient.getApp', [
      {
        appId: inputAmplifyAppId,
      },
    ]);

    try {
      log();
      const getAppResult = await amplifyClient
        .getApp({
          appId: inputAmplifyAppId,
        })
        .promise();
      context.print.info(`Amplify AppID found: ${inputAmplifyAppId}. Amplify App name is: ${getAppResult.app.name}`);
      amplifyAppId = inputAmplifyAppId;
    } catch (e) {
      log(e);
      context.print.error(
        `Amplify AppID: ${inputAmplifyAppId} not found. Please ensure your local profile matches the AWS account or region in which the Amplify app exists.`,
      );
      context.print.info(e);
      throw e;
    }
  }

  if (!amplifyAppId) {
    // in the "amplify env add" workflow, there might be other envs, new env can be added to existing appId
    if (stateManager.teamProviderInfoExists()) {
      const teamProviderInfo = stateManager.getTeamProviderInfo();
      const envList = Object.keys(teamProviderInfo);

      let appIdsInTheSameLocalProjectAndRegion = [];
      for (let env of envList) {
        if (
          env !== envName &&
          teamProviderInfo[env][ProviderName].Region === awsConfigInfo.region &&
          teamProviderInfo[env][ProviderName][AmplifyAppIdLabel] &&
          !appIdsInTheSameLocalProjectAndRegion.includes(teamProviderInfo[env][ProviderName][AmplifyAppIdLabel])
        ) {
          appIdsInTheSameLocalProjectAndRegion.push(teamProviderInfo[env][ProviderName][AmplifyAppIdLabel]);
        }
      }

      if (appIdsInTheSameLocalProjectAndRegion.length > 0) {
        let apps = [];
        let listAppsResponse = {};

        do {
          logger('init.amplifyClient.listApps', [
            {
              nextToken: listAppsResponse.nextToken,
              maxResults: 25,
            },
          ])();
          listAppsResponse = await amplifyClient
            .listApps({
              nextToken: listAppsResponse.nextToken,
              maxResults: 25,
            })
            .promise();
          apps = apps.concat(listAppsResponse.apps);
        } while (listAppsResponse.nextToken);

        const verifiedAppIds = apps.map(app => app.appId);
        appIdsInTheSameLocalProjectAndRegion = appIdsInTheSameLocalProjectAndRegion.filter(appId => verifiedAppIds.includes(appId));

        if (appIdsInTheSameLocalProjectAndRegion.length === 1) {
          amplifyAppId = appIdsInTheSameLocalProjectAndRegion[0]; // eslint-disable-line
        } else if (appIdsInTheSameLocalProjectAndRegion.length > 1) {
          context.print.info(`Your project is associated with multiple Amplify Service Apps in the region ${awsConfigInfo.region}`);
          amplifyAppId = await SelectFromExistingAppId(context, appIdsInTheSameLocalProjectAndRegion);
        }
      }
    }
  }

  if (!amplifyAppId) {
    const createAppParams = {
      name: projectName,
      environmentVariables: { _LIVE_PACKAGE_UPDATES: '[{"pkg":"@aws-amplify/cli","type":"npm","version":"latest"}]' },
    };
    const log = logger('init.amplifyClient.createApp', [createAppParams]);

    try {
      if (amplifyAppCreationEnabled()) {
        log();
        const createAppResponse = await amplifyClient.createApp(createAppParams).promise();
        amplifyAppId = createAppResponse.app.appId;
      }
    } catch (e) {
      log(e);
      if (e.code === 'LimitExceededException') {
        // Do nothing
      } else if (
        e.code === 'BadRequestException' &&
        e.message.includes('Rate exceeded while calling CreateApp, please slow down or try again later.')
      ) {
        // Do nothing
      } else {
        throw e;
      }
    }
  }

  if (!amplifyAppId) {
    return {
      amplifyAppId,
      verifiedStackName,
      deploymentBucketName,
    };
  }

  let needToCreateNewBackendEnv = false;
  const log = logger('init.amplifyClient.getBackendEnvironment', [
    {
      appId: amplifyAppId,
      environmentName: envName,
    },
  ]);

  try {
    log();
    const { backendEnvironment } = await amplifyClient
      .getBackendEnvironment({
        appId: amplifyAppId,
        environmentName: envName,
      })
      .promise();

    if (backendEnvironment) {
      verifiedStackName = backendEnvironment.stackName;
      deploymentBucketName = backendEnvironment.deploymentArtifacts;
    } else {
      needToCreateNewBackendEnv = true;
    }
  } catch (e) {
    log(e);
    needToCreateNewBackendEnv = true;
  }

  if (needToCreateNewBackendEnv) {
    context.print.info(`Adding backend environment ${envName} to AWS Amplify app: ${amplifyAppId}`);
    const createEnvParams = {
      appId: amplifyAppId,
      environmentName: envName,
      stackName,
      deploymentArtifacts: deploymentBucketName,
    };
    const log = logger('init.amplifyClient.getBackendEnvironment', [createEnvParams]);
    try {
      log();
      await amplifyClient.createBackendEnvironment(createEnvParams).promise();
    } catch (ex) {
      log(ex);
      throw ex;
    }
  }

  return {
    amplifyAppId,
    verifiedStackName,
    deploymentBucketName,
  };
}