如何让CloudFormation嵌套栈共用同一个API Gateway URL?
问题修复方案
报错根因
该报错是SAM框架的内置校验规则导致的:AWS::Serverless::Function资源的Api事件仅允许引用当前模板内定义的AWS::Serverless::Api资源,跨栈传递的API ID无法通过该校验。
修复步骤
1. 根栈侧配置共享API及传递参数
根栈内显式定义共享的AWS::Serverless::Api资源,调用嵌套栈时传递3个核心参数:API ID、API根资源ID、API部署阶段:
# 根栈 template.yaml 示例 Resources: # 全局共享API Gateway SharedRestApi: Type: AWS::Serverless::Api Properties: StageName: prod Name: BusinessSharedApi # 嵌套栈引用 BusinessNestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: ./nested/function-stack.yaml Parameters: # 传递共享API的核心参数 SharedApiId: !Ref SharedRestApi SharedApiRootResourceId: !GetAtt SharedRestApi.RootResourceId SharedApiDeployStage: !Ref SharedRestApi.Stage
2. 嵌套栈侧声明入参
嵌套栈顶部先声明接收根栈传入的3个参数:
# 嵌套栈 function-stack.yaml 示例 Parameters: SharedApiId: Type: String Description: 根栈共享API的ID SharedApiRootResourceId: Type: String Description: 根栈共享API的根资源ID SharedApiDeployStage: Type: String Description: 根栈共享API的部署阶段名
3. 嵌套栈内弃用SAM Api事件,改用原生资源关联
删除嵌套栈内Lambda函数的Events字段下的Api类型事件,手动创建AWS::Lambda::Permission、AWS::ApiGateway::Resource、AWS::ApiGateway::Method资源完成关联:
# 嵌套栈内Lambda函数定义(移除Api事件) DemoFunction: Type: AWS::Serverless::Function Properties: CodeUri: demo/ Handler: app.lambda_handler Runtime: python3.9 # 1. 配置API Gateway调用Lambda的权限 DemoFunctionInvokePermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref DemoFunction Principal: apigateway.amazonaws.com SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SharedApiId}/*/*/* # 2. 定义API路径资源(示例为 /demo 路径,多级路径可嵌套创建Resource) DemoApiPath: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref SharedApiId ParentId: !Ref SharedApiRootResourceId PathPart: demo # 3. 定义API Method并绑定Lambda DemoApiMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref SharedApiId ResourceId: !Ref DemoApiPath HttpMethod: GET AuthorizationType: NONE Integration: Type: AWS_PROXY IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DemoFunction.Arn}/invocations
4. 配置API自动部署触发
为了避免嵌套栈更新API资源后根栈未重新部署导致配置不生效,可在根栈的API部署资源中添加对所有嵌套栈的依赖,或者新增一个可变参数(比如时间戳)每次部署时传入,触发API重新部署。
后续自定义域名绑定
直接在根栈中配置AWS::ApiGateway::DomainName和AWS::ApiGateway::BasePathMapping资源即可,所有嵌套栈中新增的API接口都会自动挂载到该域名下,无需修改嵌套栈配置。
内容的提问来源于stack exchange,提问作者PeakGen
相关产品推荐
相关产品推荐

