我想动态地在我的文件中构建一个ARN,但我需要获取当前的AccountId。如何将其作为变量访问?
例如:
example: arn:aws:states:${region}:${accountId}:stateMachine:${self:service}-${self:custom.stage}-example
引用当前的正确方法是什么 region
和 accountId
?
编辑:(解决方案)
由于这种解决方案的丑陋和冗长,我对这个解决方案并不满意 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
无服务器本身无法引用这些变量,因为它们是在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"
AWS CloudFormation提供 一些变数 喜欢 AWS::AccountId
和 AWS::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
这条线:
Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'
与区域和帐户ID的硬编码相同:
Resource: "arn:aws:iot:us-east-1:1234567890:topic/foo"
如 已经回答了,无服务器框架目前不提供检索帐户ID的方法。您必须使用CloudFormation语法。
但是,如果您要定义IAM访问策略,则为您 不需要 AWS账户ID。只是放置 *
你在哪里放帐号。在以下情况下,帐户ID是必需的:
- 在构建ARN以标识特定资源(例如,通过其ARN调用函数)时,不要授予访问权限。
- 在与其他AWS账户建立信任关系时。
请看以下内容 serverless.yml 文件:
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
有用。我在用着 *
而不是我的帐号,我正在使用 ${self:provider.region}
引用我设置的区域 提供商 (美国东部-1)。