Serverless 2.35以上版本CloudFormation模板变量替换异常问题
我之前遇到过完全一样的问题,升级Serverless框架后,其他资源的变量替换都正常,唯独ApiGateway的Cognito授权器抛出了ARN无效的错误。这是因为Serverless在2.35版本之后,对AWS::ApiGateway::Authorizer的ProviderARNs字段的变量处理逻辑做了调整,之前的嵌套变量写法在这里不再被正确解析。
核心问题原因
Serverless后续版本优化了部分CloudFormation资源的前置合法性校验,对于ProviderARNs这种要求严格ARN格式的字段,框架会优先检查格式,但嵌套变量(比如${${self:custom.config}:REGION})的解析优先级滞后于格式校验,导致未替换的占位符直接传给了CloudFormation。而CloudFormation无法识别Serverless的${}变量语法,最终触发BadRequestException。
修复方案
这里有两种可靠的解决方式,你可以根据项目结构选择:
方案1:提前在custom块中生成完整ARN
把需要的ARN提前组装好,直接在授权器中引用预定义的变量,避免嵌套解析的问题:
custom: # 先加载配置文件 config: ${file(./src/config/dev.json)} # 提前组装Cognito用户池的完整ARN cognitoUserPoolArn: "arn:aws:cognito-idp:${self:custom.config.REGION}:${self:custom.config.AWS_ACCOUNT}:userpool/${self:custom.config.COGNITO_POOL_ID}" resources: Resources: ApiGatewayCognitoAuthorizer: DependsOn: - ApiGatewayRestApi Type: AWS::ApiGateway::Authorizer Properties: Name: cognito-authorizer IdentitySource: method.request.header.Authorization ProviderARNs: # 直接引用预定义的ARN - ${self:custom.cognitoUserPoolArn} RestApiId: Ref: ApiGatewayRestApi Type: COGNITO_USER_POOLS
方案2:使用CloudFormation的Fn::Sub处理变量
利用CloudFormation的!Sub函数来替换变量,让变量解析由CloudFormation在部署时完成,绕开Serverless的前置校验:
resources: # 定义CloudFormation参数,加载配置文件中的值 Parameters: REGION: Type: String Default: ${file(./src/config/dev.json):REGION} AWS_ACCOUNT: Type: String Default: ${file(./src/config/dev.json):AWS_ACCOUNT} COGNITO_POOL_ID: Type: String Default: ${file(./src/config/dev.json):COGNITO_POOL_ID} Resources: ApiGatewayCognitoAuthorizer: DependsOn: - ApiGatewayRestApi Type: AWS::ApiGateway::Authorizer Properties: Name: cognito-authorizer IdentitySource: method.request.header.Authorization ProviderARNs: # 使用!Sub让CloudFormation替换参数 - !Sub "arn:aws:cognito-idp:${REGION}:${AWS_ACCOUNT}:userpool/${COGNITO_POOL_ID}" RestApiId: Ref: ApiGatewayRestApi Type: COGNITO_USER_POOLS
验证方法
部署前可以运行serverless print命令,查看生成的CloudFormation模板,确认ProviderARNs字段是否已经被替换成实际的ARN值,提前规避部署报错。
内容的提问来源于stack exchange,提问作者hector.mateos
相关产品推荐
相关产品推荐

