如何解决SAM文档中的循环依赖,同时将API端点放在lambda函数的环境变量中

人气:814 发布:2022-10-16 标签: amazon-web-services amazon-cloudformation aws-sam

问题描述

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: hello
Resources:
  ApiGatewayApi:
  Type: AWS::Serverless::Api
  Properties:
    StageName: stage
    TracingEnabled: true
  FunctionA:
    ...
    Environment:
      Variables:
        TEST: !Ref ApiGatewayApi
    Events:
      GetUsers:
        Type: Api
        Properties:
          Path: /account
          Method: get
          RestApiId:
            Ref: ApiGatewayApi
  FunctionB:
    ...
    Environment:
      Variables:
        API_URL: !GetAtt ApiGatewayApi.RootResourceId
    Events:
      OrderEvent:
        Type: SQS
        Properties:
          Queue: !GetAtt OrderServiceQueue.Arn

这会导致循环依赖。如果我这样做了!ref在一个没有API事件的函数中,它不会抱怨它。我阅读了来自AWS、博客和其他堆栈溢出问题的高级支持文章,但它们与我的问题不同。

FunctionB成功引用API网关ID,而FunctionA没有引用。

我在函数外部创建API,所以我认为它应该!ref其中的终结点。还有别的事吗?

AWS SAM

循环引用是通过AWS SAM使用事件来创建推荐答案定义来创建的。这基本上意味着它需要lambda函数的ARN来构造该定义,然后才能创建API。但是,因为您需要API的ID来创建lambda,所以您最终得到了一个循环引用,因为在没有另一个已经存在的情况下,这两个都不能创建。

解决此问题的第一种方法是分多个步骤部署堆栈。您可以首先部署一个空API,这将允许您在添加lambdas时引用API ID。当然,如果您想要轻松地在另一个帐户上复制此堆栈或出于某种原因重新部署API,则此方法的重大缺点是,这意味着您每次都必须再次使用此技巧。

另一种方法是,如果您真的想要将此值作为环境变量,将手动创建API的定义体(在其中构造lambda的ARN,而不是引用它们),并且假设您还需要手动创建权限,以便允许您的API Gateway资源执行lambda函数。

但是,我觉得更好的方法是使用lambda代理集成(我认为这是默认使用的,但我找不到任何文档来验证它)。使用lambda代理集成时,the incoming event in lambda contains all the information about the API。您可以轻松地从该事件中提取所需的信息,而不是将其作为环境变量,但这取决于您的具体用例。

857