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;
}