I'm trying to automatically create a new provisioning artifact (or version) for my product in the Service Catalog whenever there's an update.
I checked up the documentation and this seems to be the method I'm looking for. I try it via the AWS CloudShell and it works :
[cloudshell-user@ip-10-0-150-18 ~]$ aws servicecatalog search-products-as-admin
{
"ProductViewDetails": [
{
"ProductViewSummary": {
"Id": "prodview-xxxxxx",
"ProductId": "prod-xxxxxx",
"Name": "9ce35033-b4ed-4354-b1f6-ee0f651f7280",
"Owner": "me@mail.com",
"Type": "CLOUD_FORMATION_TEMPLATE",
"HasDefaultPath": false
},
"Status": "CREATED",
"ProductARN": "arn:aws:catalog:xxxxxx:xxxxxx:product/prod-xxxxxx",
"CreatedTime": "2021-10-22T10:33:02+00:00"
}
]
}
[cloudshell-user@ip-10-0-150-18 ~]$ aws servicecatalog create-provisioning-artifact --product-id prod-xxxxxx --parameters Name=new-version,Info={LoadTemplateFromURL=https://s3.amazonaws.com/xxxxxx-xxxxxx-xxxxxx-output/v53/cloud-formation-template.json},Type=CLOUD_FORMATION_TEMPLATE
{
"ProvisioningArtifactDetail": {
"Id": "pa-xxxxxx",
"Name": "new-version",
"Type": "CLOUD_FORMATION_TEMPLATE",
"CreatedTime": "2021-10-22T12:35:57+00:00",
"Active": true,
"Guidance": "DEFAULT"
},
"Info": {
"TemplateUrl": "https://s3.amazonaws.com/xxxxxx-xxxxxx-xxxxxx-output/v53/cloud-formation-template.json"
},
"Status": "CREATING"
}
However, when I use the AWS SDK for JavaScript from my Lambda, and the createProvisioningArtifact
method, this is what happens :
const updateParams = {
IdempotencyToken: uuid_1.v4(),
Parameters: {
Name: `v${technicalAsset.version}`,
Info: { LoadTemplateFromURL: outputS3Url },
Type: "CLOUD_FORMATION_TEMPLATE",
},
ProductId: existingProductId,
}
console.log('updateParams', updateParams);
const serviceCatalogResponse = await serviceCatalog
.createProvisioningArtifact(updateParams, (err, data) => {
if (err) {
console.log(err, err.stack);
serviceCatalogDeploymentStatus = utils_1.AssetServiceCatalogDeploymentStatus.FAILED;
}
else {
console.log("Successful response from service catalog" + data);
serviceCatalogDeploymentStatus = utils_1.AssetServiceCatalogDeploymentStatus.SUCCESSFUL;
}
})
.promise();
InvalidParametersException: Invalid templateBody. Please make sure that your template is valid
at Request.extractError (/opt/nodejs/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/opt/nodejs/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'InvalidParametersException',
time: 2021-10-22T10:39:44.319Z,
requestId: 'bcd23b38-ed62-4684-a392-b9a0ee46f333',
statusCode: 400,
retryable: false,
retryDelay: 51.827093801169944
}
And in case you think that the updateParams
is the problem, this what it looks like :
{
IdempotencyToken: 'b099ca57-47dd-4889-ae71-95d44cc1aae9',
Parameters: {
Name: 'v53',
Info: {
LoadTemplateFromURL: 'https://s3.amazonaws.com/xxxxxx-xxxxxx-output/v53/cloud-formation-template.json'
},
Type: 'CLOUD_FORMATION_TEMPLATE'
},
ProductId: 'prod-xxxxxx'
}
It's a really strange behavior and I'm curious to find out what's behind it... Thanks in advance!
AWS at its finest.
As @jarnod was saying, it was necessary to add the
cloudFormation:validateTemplate
role to your Lambda execution role if you're using the createProvisioningArtifact
method.