如何将AccountId作为serverless.yml文件中的变量?

jus*_*ase 17 amazon-web-services serverless-framework

我想动态地在我的文件中构建一个ARN,但我需要获取当前的AccountId.如何将其作为变量访问?

例如:

example: arn:aws:states:${region}:${accountId}:stateMachine:${self:service}-${self:custom.stage}-example
Run Code Online (Sandbox Code Playgroud)

参考当前regionaccountId?的正确方法是什么?

编辑:(解决方案)

由于解决方案的丑陋和冗长,我对这个解决方案并不十分满意,Fn::Join但我最终做的是制作一个arns.yml文件,其中所有这些只在这一个地方然后通过其他地方的变量引用.

# arns.yml
example:
  Fn::Join:
    - ":"
    - - arn
      - aws
      - states
      - Ref: AWS::Region
      - Ref: AWS::AccountId
      - stateMachine
      - ${self:service}-${self:custom.stage}-example
Run Code Online (Sandbox Code Playgroud)

然后:

# serverless.yml
custom:
  stage: "${opt:stage, self:provider.stage}"


functions:
  foo:
    handler: handler.foo
    environment:
      example_arn: ${file(arns.yml):example}
Run Code Online (Sandbox Code Playgroud)

编辑2 :(更好的解决方案)

这可能听起来很蹩脚,但我最终选择的解决方案是将其硬编码到我的自定义变量中.我实际上有两个帐户,我使用自定义生成步骤来复制具有帐户特定设置的两个文件,如下所示:

account.stag.yml
account.prod.yml
Run Code Online (Sandbox Code Playgroud)

每个文件可能如下所示:

# account.stag.yml
account: 123456789
region: ${opt:region, "us-east-1"}
domain: mycompany.qa
Run Code Online (Sandbox Code Playgroud)

当我构建时,我指定一个帐户,并使用gulp来完成我的所有建筑:

gulp build --account stag
Run Code Online (Sandbox Code Playgroud)

然后,我将我的帐户特定设置重命名为

build/account.yml
Run Code Online (Sandbox Code Playgroud)

我可以在我的serverless.yml中引用它,如下所示:

# build/serverless.yml
custom: ${file(account.yml)}
functions:
  foo:
    handler: handler.foo
    environment:
      example_arn: arn:aws:states:${self:custom.region}:${self:custom.account}:${self:service}-${opt:stage}-example
Run Code Online (Sandbox Code Playgroud)

Joh*_*uez 28

从 2.3.0 版本开始,现在已原生支持此功能。

只需通过 引用即可${aws:accountId}。您还可以通过 引用区域 ${aws:region}。此处的文档: https: //www.serverless.com/framework/docs/providers/aws/guide/variables#referencing-aws-specific-variables

service: new-service
provider: aws

functions:
  func1:
    name: function-1
    handler: handler.func1
    environment:
      ACCOUNT_ID: ${aws:accountId}
      REGION: ${aws:region}
Run Code Online (Sandbox Code Playgroud)

  • 接受的答案在 `!Sub` 函数的帮助下使用 Cloudformation 伪参数引用*(`AWS::AccountId` 带双冒号)。我的答案本身支持“${aws:accountId}”,但仅在无服务器版本 >= 2.3.0 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html 上受支持 (2认同)

Viv*_*ajh 20

现在,无服务器框架本身就支持这一点。

函数示例

  functions:
    hello:
      handler: my-function.handler
      environment:
        var: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*:*'
Run Code Online (Sandbox Code Playgroud)

我的角色示例

  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:*
          Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${AWS::StackName}-*
Run Code Online (Sandbox Code Playgroud)

官方文档见伪参数参考

  • 对于那些尝试使用此解决方案的人,请确保在前面包含 `!Sub`。 (3认同)

Sam*_*m J 16

有一个方便的无服务器插件https://www.npmjs.com/package/serverless-pseudo-parameters,它增加了引用aws参数的能力,例如我刚开始使用的区域和帐户ID,取得了很大的成功.


jen*_*ter 7

无服务器本身无法引用这些变量,因为它们是在CloudFormation中定义的,但不会在无服务器中公开.

如果您需要资源部分中的那些,您可以通过"Ref"-call直接访问它们.

AWS CloudFormation伪变量

如果需要将这些变量用作函数环境变量,则可以使用CloudFormation代码覆盖无服务器生成的函数代码.

因此,要实现此目的,您必须通过以下模式修改serverless.yml.

functions:
  hello:
    handler: handler.hello
resources:
  Resources:
   HelloLambdaFunction:
     Type: AWS::Lambda::Function
     Properties:
       Environment:
         Variables:
           accountId:
             Ref: AWS::AccountId
           region:
             Ref: AWS::Region
           arn:
             Fn::Join:
               - ""
               - - "arn:aws:states:"
                 - Ref: AWS::Region
                 - ":"
                 - Ref: AWS::AccountId
                 - ":stateMachine:"
                 - ${self:service}
                 - "-"
                 - ${self:custom.stage}
                 - "-example"
Run Code Online (Sandbox Code Playgroud)


Zan*_*non 5

编辑:这个问题可能已经过时了。考虑这个评论这个答案


AWS CloudFormation 提供了一些变量,比如AWS::AccountIdAWS::Region,但你不能在serverless.yml文件中使用它们,比如${AWS::AccountId}。不支持这些。

@jens 回答是对的。您必须使用 CloudFormation 语法。在下面的示例中,我提供了另一种使用 CloudFormation 的方法。

service: testing-aws-account-id

provider:
  name: aws
  runtime: nodejs4.3
  region: us-east-1
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "iot:Publish"
      Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'

functions:
  publishIot:
    handler: handler.publishIot
Run Code Online (Sandbox Code Playgroud)

线路:

 Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'
Run Code Online (Sandbox Code Playgroud)

与硬编码区域和帐户 ID 相同:

Resource: "arn:aws:iot:us-east-1:1234567890:topic/foo"    
Run Code Online (Sandbox Code Playgroud)

  • @BamaPookie,我不这么认为。仅当您添加 [此插件](https://www.npmjs.com/package/serverless-pseudo-parameters) 时,它才能工作。 (2认同)
  • 我得到 `Partition "" 对资源 "arn::Join: ["", [ "arn:` 无效 (2认同)