自定义资源函数抛错未导致CDK堆栈创建失败的问题排查
问题原因与解决方案
核心原因
你遇到的问题源于Lambda Invoke API的默认行为:当调用Lambda函数时,即使函数内部抛出错误,Invoke API本身仍会返回HTTP 200的成功响应,只是在返回结果中包含FunctionError字段和函数的错误输出。而AwsCustomResource仅会在API调用本身失败(如权限不足、函数不存在)时才会标记自定义资源部署失败,它不会自动解析Lambda函数的执行结果来判断是否出错。
解决方案
方案1:通过parseResponse手动检查Lambda执行结果
修改AwsCustomResource的配置,添加parseResponse回调函数,解析Invoke API的返回结果,检查是否存在FunctionError或函数返回的错误信息,主动抛出错误让CDK识别。
修改后的代码示例:
import * as cdk from 'aws-cdk-lib'; import { custom_resources as cr } from "aws-cdk-lib"; import { aws_iam as iam } from "aws-cdk-lib"; export class Test extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const crRole = new iam.Role(this, 'MyRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole') ] }); const myCustomResource = new cr.AwsCustomResource(this, 'MyCustomResource', { onUpdate: { service: 'Lambda', action: 'invoke', parameters: { FunctionName: 'ARN_TO_THE_FUNCTION', Payload: JSON.stringify({ account: this.account }) }, physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()), // 添加parseResponse处理Lambda执行结果 parseResponse: (response) => { // 检查是否存在FunctionError if (response.FunctionError) { // 解析Base64编码的Payload内容 const errorPayload = JSON.parse(Buffer.from(response.Payload as string, 'base64').toString()); throw new Error(`Lambda执行失败: ${errorPayload.errorMessage}`); } return response; } }, role: crRole, }); } }
方案2:改用原生CustomResource(更灵活)
如果需要更精细的控制,建议直接使用CDK的CustomResource构造,而不是AwsCustomResource。你需要编写一个自定义资源处理Lambda函数,在其中调用目标Lambda并处理错误,当目标Lambda出错时,向CloudFormation返回失败信号。
核心思路:
- 创建自定义资源处理Lambda,在内部调用目标Lambda函数。
- 捕获目标Lambda的执行错误,调用CloudFormation的
sendFailure接口返回失败状态。 - 在堆栈中使用
CustomResource关联这个处理Lambda,实现错误触发堆栈部署失败的逻辑。
补充说明
- Lambda Invoke返回的
Payload是Base64编码字符串,必须解码后才能读取函数的输出内容。 parseResponse函数中抛出的错误会被CDK捕获,直接标记自定义资源部署失败,进而导致整个堆栈部署流程终止。
内容的提问来源于stack exchange,提问作者SecretIndividual
相关产品推荐
相关产品推荐

