【问题标题】:How do I get the ARN of an AWS Lambda function for a Cloud Formation specific resource property?如何获取 Cloud Formation 特定资源属性的 AWS Lambda 函数的 ARN?
【发布时间】:2019-12-31 02:54:15
【问题描述】:

我似乎无法让 RefFn:GetAtt 返回用于设置资源的有效值。

serverless.yml

...etc...

functions:
  bearerTokenAuthentication:
    handler: app.bearerTokenAuthentication
    name: ${self:service}-auth-bearer

resources:
  - ${file(./serverless_resources.yml)}

serverless_resources.yml

Resources:
  ApiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
        Name: restapi-${self:provider.stage}
        Description: Endpoints
        ApiKeySourceType: HEADER # (to read the API key from the X-API-Key header of a request)

  ApiGatewayBearerAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Type: token
      IdentitySource: method.request.header.Authorization
      Name: BearerAuthorization
      AuthorizerResultTtlInSeconds: 300
      AuthorizerUri: !Join  #arn:aws:apigateway:${self:provider.region}:lambda:path/${self:functions.bearerTokenAuthentication.name}
        - ''
        - - 'arn:aws:apigateway:'
          - !Ref 'AWS::Region'
          - ':lambda:path/2015-03-31/functions/'
          - !GetAtt 
            - bearerTokenAuthentication # also tried !Ref bearerTokenAuthentication and '${self:functions.bearerTokenAuthentication.name}'
            - Arn
          - /invocations
      RestApiId: !Ref ApiGateway

无论我做什么,GetAtt 都找不到在bearerTokenAuthentication 中声明的 Lambda 函数的 ARN。我只是不断收到此错误:

错误:CloudFormation 模板无效:模板错误:Fn::GetAtt 实例引用未定义资源 BearerTokenAuthentication

...或者如果尝试Ref ...

错误:CloudFormation 模板无效:模板格式错误:模板的 Resources 块中未解决的资源依赖项 [bearerTokenAuthentication]

是否可以从资源部分引用 Lambda ARN?从错误消息看来,它正在寻找“资源”名称。我一直认为 lambda 函数声明也被认为是一种资源(当然除了明显的 Resources: 块之外),也许我误解了一些东西。

【问题讨论】:

  • 如果是“未解决的资源依赖”问题,您可以在“ApiGatewayBearerAuthorizer”的 Type 和 Properties 属性之间添加“DependsOn: bearerTokenAuthentication”,这将阻止创建该资源,直到 bearerTokenAuthentication 创建并可用。
  • 什么都不做。似乎完全忽略了它。

标签: amazon-web-services aws-lambda serverless-framework serverless


【解决方案1】:

我想通了。我有一个 NodeJS 项目,并且正在使用“无服务器”命令行 (sls) 使用 serverless.yml 进行部署。事实证明,它创建了一个 .serverless 子目录,其中包含一些文件。其中之一是 AWS Cloud Formation 的编译模板,名为 cloudformation-template-update-stack.json。该实用程序似乎喜欢通过将第一个字符大写并将“LambdaFunction”添加到所有函数名称(无论出于何种原因)来破坏名称。在这种情况下,bearerTokenAuthentication 被重命名为 BearerTokenAuthenticationLambdaFunction(实际资源名称)。查看编译后的模板后,一切都变得清晰起来。该实用程序似乎也可以找出依赖关系,这很高兴知道。这是最终结果:

  AuthorizerUri: !Join 
    - ''
    - - 'arn:aws:apigateway:'
      - !Ref 'AWS::Region'
      - ':lambda:path/2015-03-31/functions/'
      - !GetAtt [ BearerTokenAuthenticationLambdaFunction, Arn ]
      - '/invocations'

其他“陷阱”:

如果您还在函数中使用event 映射,请不要定义AWS::ApiGateway::RestApi 资源(就像我在问题中所做的那样),否则您将创建2 个API。 event 条目会自动创建一个名为“ApiGatewayRestApi”的 API - 这是由 sls 实用程序生成的资源名称。最后一个文件的最后一行改成这样:

  RestApiId: !Ref ApiGatewayRestApi

我的ApiGateway: 部分已被删除。

感谢这篇文章,它帮助我更清楚到底发生了什么:https://forum.serverless.com/t/fixed-how-do-i-get-reference-api-gateway-restapi-id-in-serverless-yml/3397/5

上一个答案:

我也找到了另一种方法。这就是我在找到正确(更短)的方式之前所做的事情。我能够提取 lambda 名称并手动将所需的 URI 拼接在一起:

  AuthorizerUri: !Join
    - ''
    - - 'arn:aws:apigateway:'
      - !Ref 'AWS::Region'
      - ':lambda:path/2015-03-31/functions/arn:aws:lambda:'
      - !Ref 'AWS::Region'
      - ':'
      - !Ref 'AWS::AccountId'
      - ':function:'
      - '${self:functions.bearerTokenAuthentication.name}'
      - '/invocations'

我希望这有助于节省一些时间来尝试理解复杂的 .yml 文件。我也无法理解为什么很难让它变得简单易懂。有人要做的就是(对我来说)是“sls 需要一个'serverless.yml'文件和可选的包含文件(例如特定于云系统本身的声明,如 AWS Cloud Formation),并生成一个模板 JSON 文件目标云服务系统使用它来部署您的解决方案。此外,您提供的名称可能会被破坏,因此请检查模板。我也很惊讶没有人创建一个编辑器来让这一切变得更容易——也许有一天我会研究一下自己。 ;)

【讨论】:

  • 这正是我所需要的。非常感谢分享这个!
  • 谢谢!你让我开心。
【解决方案2】:

您始终可以转到已部署的 lambda 并查找 aws:cloudformation:logical-id 标记。这样你就可以得到你应该在 serverless.yaml 中使用的逻辑 ID。 (也不喜欢这种幕后起名的把戏……)

【讨论】:

    猜你喜欢
    • 2021-05-29
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2021-04-24
    • 2021-06-29
    • 1970-01-01
    • 2023-03-09
    • 2018-01-24
    相关资源
    最近更新 更多