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

时间:2017-03-05 18:49:04

标签: amazon-web-services serverless-framework

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

例如:

example: arn:aws:states:${region}:${accountId}:stateMachine:${self:service}-${self:custom.stage}-example

引用当前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

然后:

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


functions:
  foo:
    handler: handler.foo
    environment:
      example_arn: ${file(arns.yml):example}

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

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

account.stag.yml
account.prod.yml

每个文件可能如下所示:

# account.stag.yml
account: 123456789
region: ${opt:region, "us-east-1"}
domain: mycompany.qa

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

gulp build --account stag

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

build/account.yml

我可以在我的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

6 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:7)

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

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

AWS CloudFormation Pseudo-variables

如果您需要将这些变量用作函数环境变量,则可以使用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"

答案 2 :(得分:3)

AWS CloudFormation提供AWS::AccountIdAWS::Region之类的some variables,但您无法在 serverless.yml 文件中使用它们,例如{{1 }}。那些不受支持。

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

${AWS::AccountId}

该行:

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

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

 Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'

答案 3 :(得分:1)

现在从 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}

答案 4 :(得分:0)

作为already answered,无服务器框架目前还没有提供检索帐户ID的方法。您必须使用CloudFormation语法。

但是,如果您要定义IAM访问政策,则不需要 AWS账户ID。只需将declare threshold int; set threshold = 6; insert into newTable( id, gap, groupID ) select A.id, A.gap, case when A.gap > threshold then (select case when max(groupID) is null then 0 else max(groupID)+1 end from newTable) else (select case when max(groupID) is null then 0 else max(groupID) end from newTable) end from A order by A.id asc; 放在您输入帐号的位置即可。在以下情况下,帐户ID是必需的:

  • 当您构建ARN以识别特定资源(例如,通过其ARN调用函数)时,不要授予访问权限。
  • 与其他AWS账户建立信任关系时。

请查看以下 serverless.yml 文件:

public static void main(String[] args) {
    String x = "DannyKrosis@Gmail.com";
    boolean y = false;
    for (int a = 0; a < x.length(); a++) {
        switch (x.charAt(a)) {
            case '@':
                x = replaceCharAt(x, a, ' ');
                x = x.replaceAll("\\s+", "");
                y = true; // Stops for loop
                break;
            default:
                x = replaceCharAt(x, a, ' ');
                break;
        }
        if (y) {
            break;
        }
    }
    System.out.println(x); // prints "Gmail.com"
}

public static String replaceCharAt(String s, int pos, char c) {
    return s.substring(0, pos) + c + s.substring(pos + 1);
}

有效。我使用*而非我的帐号,并且使用service: testing-aws-account-id provider: name: aws runtime: nodejs4.3 region: us-east-1 iamRoleStatements: - Effect: "Allow" Action: - "iot:Publish" Resource: "arn:aws:iot:${self:provider.region}:*:topic/foo" functions: publishIot: handler: handler.publishIot 来引用我在提供商中设置的区域(我们 - 东 - 1)。

答案 5 :(得分:0)

现在,无服务器框架本身支持此功能。

wrap_plots()

有关官方文档,请参见Pseudo Parameters Reference