You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在AWS SAM与CloudFormation中为主栈和嵌套栈共用单个API Gateway

解决AWS SAM主栈与嵌套栈共用单个API Gateway的问题

问题原因

你遇到的错误是因为AWS CloudFormation限制:API Gateway的路由、集成等关联资源必须与API Gateway本身在同一个栈中创建。直接将主栈的API ID传递给嵌套栈,并通过嵌套栈中Lambda的Events.Api关联,会触发嵌套栈尝试创建属于该API的资源,这违反了跨栈资源归属的规则。

以下是两种可行的解决方案:


方案1:主栈统一管理所有API路由

将嵌套栈的Lambda函数ARN导出,主栈导入后,在主栈的AWS::Serverless::Api中定义所有路由,关联主栈和嵌套栈的Lambda。

步骤1:嵌套栈导出Lambda ARN

在nestedTemplate.yml中添加输出:

Outputs:
  NestedFunc1Arn:
    Value: !GetAtt NestedFunc1.Arn
    Export:
      Name: !Sub ${AWS::StackName}-NestedFunc1Arn
  NestedFunc2Arn:
    Value: !GetAtt NestedFunc2.Arn
    Export:
      Name: !Sub ${AWS::StackName}-NestedFunc2Arn
  NestedFunc3Arn:
    Value: !GetAtt NestedFunc3.Arn
    Export:
      Name: !Sub ${AWS::StackName}-NestedFunc3Arn

步骤2:主栈导入Lambda ARN并定义完整API

在template.yml中导入嵌套栈的Lambda ARN,然后在API的定义体中配置所有路由:

# 导入嵌套栈的Lambda ARN
ImportedNestedFunc1Arn:
  Fn::ImportValue: !Sub ${NestedStackName}-NestedFunc1Arn
ImportedNestedFunc2Arn:
  Fn::ImportValue: !Sub ${NestedStackName}-NestedFunc2Arn
ImportedNestedFunc3Arn:
  Fn::ImportValue: !Sub ${NestedStackName}-NestedFunc3Arn

# 统一API Gateway定义
UnifiedApi:
  Type: AWS::Serverless::Api
  Properties:
    StageName: prod
    DefinitionBody:
      swagger: '2.0'
      info:
        title: Unified API
      paths:
        # 主栈Lambda路由
        /main-func1:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MainFunc1.Arn}/invocations
              httpMethod: POST
              type: aws_proxy
        /main-func2:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MainFunc2.Arn}/invocations
              httpMethod: POST
              type: aws_proxy
        /main-func3:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MainFunc3.Arn}/invocations
              httpMethod: POST
              type: aws_proxy
        # 嵌套栈Lambda路由
        /nested-func1:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImportedNestedFunc1Arn}/invocations
              httpMethod: POST
              type: aws_proxy
        /nested-func2:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImportedNestedFunc2Arn}/invocations
              httpMethod: POST
              type: aws_proxy
        /nested-func3:
          get:
            x-amazon-apigateway-integration:
              uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImportedNestedFunc3Arn}/invocations
              httpMethod: POST
              type: aws_proxy

方案2:嵌套栈手动创建API关联资源

主栈导出API的RestApiId和RootResourceId,嵌套栈导入后,用原生CloudFormation资源手动创建路由、集成和Lambda权限,替代AWS::Serverless::Function的Events自动关联。

步骤1:主栈导出API核心参数

在template.yml中添加输出:

UnifiedApi:
  Type: AWS::Serverless::Api
  Properties:
    StageName: prod

Outputs:
  ApiRestApiId:
    Value: !Ref UnifiedApi
    Export:
      Name: !Sub ${AWS::StackName}-ApiRestApiId
  ApiRootResourceId:
    Value: !GetAtt UnifiedApi.RootResourceId
    Export:
      Name: !Sub ${AWS::StackName}-ApiRootResourceId

步骤2:嵌套栈导入并创建API资源

在nestedTemplate.yml中导入API参数,手动定义路由、集成和权限:

Parameters:
  ParentStackName:
    Type: String

Resources:
  NestedFunc1:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./nested-func1/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x

  # 创建API子资源
  NestedFunc1Resource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId:
        Fn::ImportValue: !Sub ${ParentStackName}-ApiRootResourceId
      PathPart: nested-func1
      RestApiId:
        Fn::ImportValue: !Sub ${ParentStackName}-ApiRestApiId

  # 创建API方法
  NestedFunc1Method:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${NestedFunc1.Arn}/invocations
      ResourceId: !Ref NestedFunc1Resource
      RestApiId:
        Fn::ImportValue: !Sub ${ParentStackName}-ApiRestApiId

  # 授权API Gateway调用Lambda
  NestedFunc1Permission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref NestedFunc1
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${Fn::ImportValue: !Sub ${ParentStackName}-ApiRestApiId}/*/GET/nested-func1

重复上述资源定义,为嵌套栈的另外2个Lambda函数配置路由。


内容的提问来源于stack exchange,提问作者Justine Dela Rosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:13:10