添加serverless-split-stack与provisionedConcurrency后部署失败求助
问题现象
AWS项目因资源数量超出CloudFormation 500栈资源限制,使用serverless-plugin-split-stacks插件拆分栈。未给Lambda函数添加provisionedConcurrency配置时部署正常,添加后部署失败,报错提示CloudFormation模板存在未解析的资源依赖。
报错信息
Stack dm-scratch-v2-test部署失败(1359s)
环境:darwin, node 14.15.4, framework 3.34.0 (本地) 3.34.0v (全局), plugin 6.2.3, SDK 4.3.2
凭证:本地、环境变量CloudFormation模板无效:模板格式错误:模板资源块中存在未解析的资源依赖[AuthorizerFuncLambdaFunctionArnParameter]
serverless.yml 关键配置
service: dm-scratch-v2 frameworkVersion: '3' provider: runtime: python3.8 name: aws logs: restApi: true timeout: 29 ecr: images: appimage: path: ./ httpApi: cors: true authorizers: Authorizer: type: request functionName: authorizerFunc resultTtlInSeconds: 300 identitySource: - $request.header.Authorization deploymentBucket: name: mysvc-v2-deployments serverSideEncryption: AES256 versionFunctions: false stage: dev region: us-west-1 custom: basename: ${self:service}-${self:provider.stage} pythonRequirements: dockerizePip: true slim: true usePipenv: false zip: true splitStacks: nestedStackCount: 20 perFunction: false perType: true perGroupFunction: true functions: authorizerFunc: provisionedConcurrency: 1 image: name: appimage command: - gateway.policy.auth.user_token_authorizer entryPoint: - '/lambda-entrypoint.sh' # 其他函数配置省略... plugins: - serverless-offline - serverless-python-requirements - serverless-plugin-split-stacks
解决方案
该问题根源是serverless-plugin-split-stacks插件将作为授权器的authorizerFunc Lambda函数(及对应的provisionedConcurrency相关资源)拆分到嵌套栈中,但主栈的HTTP API授权器配置依赖该函数的ARN参数,导致CloudFormation无法解析跨栈依赖。
方法1:自定义资源分组规则
在custom.splitStacks中添加规则,将HTTP API授权器相关资源与authorizerFunc函数放在同一栈:
custom: splitStacks: nestedStackCount: 20 perFunction: false perType: true perGroupFunction: true customGrouping: - resources: - HttpApiAuthorizer* - AuthorizerFuncLambdaFunction* - AuthorizerFuncLambdaProvisionedConcurrencyConfig* destination: 'HttpApiAuthorizersStack'
方法2:启用perFunction模式并分组
将perFunction设为true,通过自定义分组逻辑把授权器函数与HTTP API资源归为一组:
custom: splitStacks: nestedStackCount: 20 perFunction: true perType: true perGroupFunction: true groupingFunction: | (resource) => { if (resource.logicalId.includes('AuthorizerFunc') || resource.logicalId.includes('HttpApi')) { return 'HttpApiAndAuthorizers'; } return resource.defaultGroup; }
方法3:升级插件版本
旧版serverless-plugin-split-stacks存在处理provisionedConcurrency与HTTP API授权器依赖的bug,升级到最新版本可直接修复:
npm update serverless-plugin-split-stacks
方法4:临时绕过(非生产环境)
若仅需临时测试,可先移除authorizerFunc的provisionedConcurrency配置完成部署,之后通过AWS控制台或CLI单独配置该函数的预置并发。
内容的提问来源于stack exchange,提问作者skysoft999

