2017-03-05 26 views
10

我想動態地在我的文件中創建一個ARN,但我需要獲取當前的AccountId。我怎樣才能將它作爲一個變量來訪問?如何將AccountId作爲serverless.yml文件中的變量獲取?

例如:

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 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 

回答

5

有一個方便的無服務器插件https://www.npmjs.com/package/serverless-pseudo-parameters,它增加了引用aws參數的能力,例如我剛剛開始使用的區域和帳戶ID,取得了很大的成功。

+0

我還沒有審查過這個插件,但這似乎是老實說的最佳答案,轉而成爲正確的答案。 –

4

無服務器本身不能引用,因爲這些都是內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

AWS CloudFormation提供some variablesAWS::AccountIdAWS::Region,但你不能在serverless.yml文件中像${AWS::AccountId}使用它們。那些不支持。

@jens answer是對的。您必須使用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"  
+0

可以將該行替換爲'Resource:'!Sub arn:aws:iot:$ {AWS :: Region}:$ {AWS :: AccountId}:topic/foo''? – BamaPookie

+0

@BamaPookie,我不這麼認爲。它應該只在你添加[這個插件](https://www.npmjs.com/package/serverless-pseudo-parameters)時才起作用。 – Zanon

1

由於already answered,無服務器框架目前不提供一種方法檢索帳戶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}來引用我在我的供應商(us-east-1)中設置的區域。

相關問題