serverless部署AWS PRIVATE API网关报资源策略缺失错误
核心报错原因
部署时CloudFormation触发Private REST API doesn't have a resource policy attached to it错误,本质是API网关部署动作执行时,资源策略还未成功挂载到API实例上,或者框架根本没有正确识别你写的resourcePolicy配置,按以下顺序排查即可解决:
排查项1:修正配置缩进错误
你当前的配置将plugins字段错误缩进在了provider块内部。plugins是serverless.yml的顶级配置项,必须和provider字段保持同级缩进,缩进错误会导致框架加载配置逻辑异常,部分provider配置(包括资源策略)无法被正确解析。排查项2:清理无效转义字符
配置中出现的"是HTML转义的双引号字符,YAML解析时会给对应值额外包裹一层无效引号,导致IAM策略语法失效。所有字符串值直接填写即可,不需要加这类转义符。排查项3:修复资源创建顺序问题(最高发诱因)
绝大多数该报错都是这个问题导致:2.60.0版本之前的Serverless框架生成的CloudFormation模板中,没有给AWS::ApiGateway::Deployment资源配置对RestApi实例的强依赖,CloudFormation会在资源策略还没挂载完成时就提前执行部署动作,直接触发400错误。
对应解决方法二选一即可:- 直接将Serverless框架升级到2.60.0及以上版本,官方已经在该版本修复了私有API部署的依赖顺序bug
- 无法升级框架时,在配置中追加CloudFormation扩展规则,强制部署动作等待API网关实例配置完成后再执行,配置片段如下:
resources: extensions: ApiGatewayDeployment: DependsOn: - ApiGatewayRestApi
排查项4:校验资源策略合法性
确认资源策略中填写的VPC ID、VPC端点ID和你实际环境的资源ID一致,私有API的资源策略必须至少包含一条对应VPC/VPCE的放行规则,否则策略本身会被判定为无效。
修正后的参考配置
service: your-service-name provider: name: aws endpointType: PRIVATE vpcEndpointIds: - vpce-xxxx # 替换为实际VPC端点ID region: ap-southeast-2 apiKeys: - ${self:custom.actualStage}-xxxxxx2 resourcePolicy: - Effect: Allow Principal: '*' Action: execute-api:Invoke Resource: - execute-api:/*/*/* Condition: StringEquals: aws:SourceVpc: - vpc-xxxxx # 替换为实际VPC ID iamRoleStatements: - Effect: Allow Action: - lambda:InvokeFunction Resource: "*" # 注意plugins是顶级配置,和provider平级 plugins: - serverless-plugin-warmup # 低版本框架保留以下配置,高版本可省略 resources: extensions: ApiGatewayDeployment: DependsOn: - ApiGatewayRestApi
部署前校验
配置修改完成后先执行sls print命令,查看框架解析后的完整输出,确认resourcePolicy字段被正确加载,没有解析异常。如果之前有部署失败的残留CloudFormation栈,先删除残留栈后再执行部署即可。
内容的提问来源于stack exchange,提问作者apark

