async getProvisioningArtifactParams()

in addons/addon-environment-sc-api/packages/environment-type-mgmt-services/lib/environment-type/env-type-service.js [172:253]


  async getProvisioningArtifactParams(requestContext, productId, provisioningArtifactId) {
    const [aws] = await this.service(['aws']);
    const roleArn = this.settings.get(settingKeys.envMgmtRoleArn);
    const serviceCatalogClient = await getServiceCatalogClient(aws, roleArn);

    // Make sure there is only one and only one launch path for the product being imported
    const result = await retry(() =>
      // wrap with retry with exponential backoff in case of throttling errors
      serviceCatalogClient
        .listLaunchPaths({ ProductId: productId })
        .promise()
        .catch(emptyObjectIfDoesNotExist),
    );
    // expecting the product to be available to the platform via exactly
    // one portfolio i.e., it needs to have exactly one launch path
    if (_.isEmpty(result.LaunchPathSummaries)) {
      throw this.boom.internalError(
        `The product ${productId} is not shared with the ${roleArn} role. Please add the role "${roleArn}" to the AWS Service Catalog Portfolio and try again.`,
        true,
      );
    }
    if (result.LaunchPathSummaries.length > 1) {
      throw this.boom.internalError(
        `The product ${productId} is shared via multiple portfolios, do not know which portfolio to launch from. Please make sure the product is shared to "${roleArn}" via only one AWS Service Catalog Portfolio.`,
        true,
      );
    }

    const launchPathId = result.LaunchPathSummaries[0].Id;

    const provisioningParams = await retry(() =>
      // wrap with retry with exponential backoff in case of throttling errors
      serviceCatalogClient
        .describeProvisioningParameters({
          ProductId: productId,
          ProvisioningArtifactId: provisioningArtifactId,
          PathId: launchPathId,
        })
        .promise()
        .catch(emptyObjectIfDoesNotExist),
    );

    if (_.isEmpty(provisioningParams)) {
      throw this.boom.internalError(
        `Could not read provisioning information for product "${productId}" and provisioning artifact "${provisioningArtifactId}".` +
          `Please add the role "${roleArn}" to the AWS Service Catalog Portfolio and try again.`,
      );
    }

    const constraints = provisioningParams.ConstraintSummaries || [];
    const launchConstraint = _.find(constraints, { Type: 'LAUNCH' });
    if (_.isEmpty(launchConstraint)) {
      throw this.boom.internalError(
        `The product "${productId}" does not have any launch constraint role specified in AWS Service Catalog Portfolio. Please specify a local role name as launch constraint in the AWS Service Catalog Portfolio and try again.`,
        true,
      );
    }

    // Make sure the launch constraint role's name matches the configured prefix.
    // The IAM permissions required to replicate this role in the workspace environments are all locked down based on that prefix
    // So if the role name prefix does not match the "replicate-launch-constraint-in-target-acc" step of the "provision-environment-sc"
    // workflow would fail later when launching environments of this environment type

    // Find launch constraint role arn from UsageInstructions array. The UsageInstructions array has shape [{Type,Value}].
    // One of the usage instructions in this array is about launch constraint role with Type = 'launchAsRole'
    const usageInstructions = _.get(provisioningParams, 'UsageInstructions', []);
    const launchConstraintRoleArn = (_.find(usageInstructions, { Type: 'launchAsRole' }) || {}).Value;
    const launchConstraintRolePrefix = this.settings.get(settingKeys.launchConstraintRolePrefix);
    if (launchConstraintRoleArn && launchConstraintRolePrefix !== '*') {
      // if launchConstraintRolePrefix is not a wild-card then make sure the specified launch constraint role name matches the specified prefix
      const arnParts = _.split(launchConstraintRoleArn, '/');
      const launchConstraintRoleName = arnParts[arnParts.length - 1];
      if (!matchRuleExpl(launchConstraintRoleName, launchConstraintRolePrefix)) {
        throw this.boom.internalError(
          `The launch constraint role specified for "${productId}" in AWS Service Catalog Portfolio does not match the configured launch constraint role name prefix "${launchConstraintRolePrefix}". Please specify launch constraint role in the AWS Service Catalog with name matching the prefix "${launchConstraintRolePrefix}". The prefix is configured via setting named "${settingKeys.launchConstraintRolePrefix}".`,
          true,
        );
      }
    }

    return provisioningParams.ProvisioningArtifactParameters;
  }