AWS Service Catalog同一API调用时SDK与CLI执行结果不一致问题
问题成因
- Lambda执行角色权限不足
CloudShell调用接口时使用的是你当前登录的账号权限,该账号具备目标S3模板文件的读取权限;而Lambda的执行角色默认没有对应S3路径的访问权限,Service Catalog拉取模板时会收到403响应,返回的错误内容不是合法CloudFormation模板,因此触发模板无效报错。 - SDK调用方式冲突
你的代码中同时使用了回调函数和.promise()两种异步调用模式,AWS JS SDK v2不支持这种混合用法,会导致参数序列化异常,Info字段内容未被正确传递到服务端,服务端未检测到合法的模板URL,因此尝试读取不存在的TemplateBody参数触发报错。
解决方案
- 第一步:修正SDK调用方式,移除回调函数,统一使用async/await+promise的写法,参考代码如下:
const updateParams = { IdempotencyToken: uuid_1.v4(), Parameters: { Name: `v${technicalAsset.version}`, Info: { LoadTemplateFromURL: outputS3Url }, Type: "CLOUD_FORMATION_TEMPLATE", }, ProductId: existingProductId, } console.log('updateParams', updateParams); try { const serviceCatalogResponse = await serviceCatalog.createProvisioningArtifact(updateParams).promise(); console.log("Successful response from service catalog", serviceCatalogResponse); serviceCatalogDeploymentStatus = utils_1.AssetServiceCatalogDeploymentStatus.SUCCESSFUL; } catch (err) { console.log(err, err.stack); serviceCatalogDeploymentStatus = utils_1.AssetServiceCatalogDeploymentStatus.FAILED; }
- 第二步:给Lambda执行角色添加S3读取权限,在角色的IAM策略中添加如下权限项,替换桶名和前缀为你的实际值:
{ "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::xxxxxx-xxxxxx-output/*" }
- 第三步:如果你的S3桶启用了KMS服务器端加密,还需要给Lambda执行角色授予对应KMS密钥的
kms:Decrypt权限。 - 可选验证:你可以在Lambda代码中先调用S3的getObject接口尝试读取该模板,确认可以正常获取内容后再调用Service Catalog接口,可快速排除S3访问类问题。
内容的提问来源于stack exchange,提问作者Fares
相关产品推荐
相关产品推荐

