部署引用跨栈Lambda的AWS API Gateway授权器时遇409错误
尝试通过AWS CDK部署API Gateway授权器资源,该授权器引用另一栈中部署并导出的Lambda,但资源创建失败,每次部署都会触发以下错误,重试无法解决。已排查确认无同名资源,需解决思路。
报错信息:
Resource handler returned message: "Unable to complete operation due to concurrent modification. Please try again later. (Service: ApiGateway, Status Code: 409, Request ID: fae3043f-7328-4d91-91e2-ea18f654b6e4)" (RequestToken: ad9e3a2f-54ea-86ce-e87b-278b997d351f, HandlerErrorCode: AlreadyExists)
相关代码:
//This lambda is exported from another stack deployed to the same environment const authLambdaArn = cdk.Fn.importValue(`arn-of-auth-lambda`) const eHApi = new apigateway.RestApi(this, `${stackName}-Api`, { deployOptions: { stageName: 'dev' }, endpointConfiguration: { types: [apigateway.EndpointType.REGIONAL] }, minimumCompressionSize: 1000, }) const eHAuthorizer = new CfnAuthorizer(this, 'EhAuthorizer', { restApiId: `${stackName}-Api`, type: 'TOKEN', name: `${stackName}-Authorizer`, authorizerUri: `arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${authLambdaArn}/invocations`, identitySource: "method.request.header.Cookie", authorizerCredentials: eHApiAuthorizerCredentials, authorizerResultTtlInSeconds: 0 })
修正RestApi ID引用:代码中直接用
${stackName}-Api作为restApiId是错误的,CDK生成的实际RestApi资源ID不等于构造函数中指定的名称。应改用eHApi.restApiId获取正确的资源ID,否则API Gateway无法定位目标RestApi,会引发资源冲突类错误。显式配置权限与依赖:API Gateway需要具备调用授权Lambda的权限,同时要明确授权器与RestApi、Lambda的依赖关系,避免并发修改冲突。添加以下代码:
// 从ARN导入Lambda函数 const authLambda = lambda.Function.fromFunctionArn(this, 'AuthLambda', authLambdaArn); // 授予API Gateway调用Lambda的权限 const invokePermission = new lambda.CfnPermission(this, 'ApiGatewayInvokeAuthLambda', { action: 'lambda:InvokeFunction', functionName: authLambda.functionName, principal: 'apigateway.amazonaws.com', // 限制仅当前API Gateway可调用 sourceArn: `arn:aws:execute-api:${region}:${cdk.Aws.ACCOUNT_ID}:${eHApi.restApiId}/*/*` }); // 让授权器依赖于权限配置,确保权限先创建完成 eHAuthorizer.addDependency(invokePermission);优先使用高阶构造(推荐):避免直接使用底层的
CfnAuthorizer,改用CDK提供的apigateway.TokenAuthorizer高阶构造,它会自动处理权限、依赖等配置,减少手动错误:const authLambda = lambda.Function.fromFunctionArn(this, 'AuthLambda', authLambdaArn); const eHAuthorizer = new apigateway.TokenAuthorizer(this, 'EhAuthorizer', { handler: authLambda, identitySource: 'method.request.header.Cookie', resultsCacheTtl: cdk.Duration.seconds(0), credentialsRole: eHApiAuthorizerCredentials });确认栈部署顺序:虽然
Fn.importValue会自动处理跨栈依赖,但如果存在隐式依赖未被识别,可手动添加栈间依赖,确保导出Lambda的栈先完成部署:// 替换为实际的授权Lambda所在栈名称 const authStack = cdk.Stack.fromStackName(this, 'AuthStack', 'auth-stack-name'); this.addDependency(authStack);
内容的提问来源于stack exchange,提问作者user881667

