在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
相关产品推荐
相关产品推荐

