justin.m.chase
justin.m.chase

Reputation: 13675

How do I get the AccountId as a variable in a serverless.yml file?

I want to build an ARN in my file dynamically, but I need to get my current AccountId. How can I access it as a variable?

For example:

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

What is the proper way to reference the current region and accountId?

Upvotes: 59

Views: 62147

Answers (5)

John Paulo Rodriguez
John Paulo Rodriguez

Reputation: 1400

This is now supported natively since version 2.3.0.

Just reference it via ${aws:accountId}. You can also reference region via ${aws:region}. Documentation here: 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}

Upvotes: 29

Zanon
Zanon

Reputation: 30790

EDIT: this question is probably outdated. Consider this comment and this answer.


AWS CloudFormation offers some variables like AWS::AccountIdand AWS::Region, but you can't use them in the serverless.yml file like ${AWS::AccountId}. Those are not supported.

@jens answer is right. You must use the CloudFormation syntax. In the example below, I provide another way to use 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

The line:

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

is the same of hard-coding the region and account id:

Resource: "arn:aws:iot:us-east-1:1234567890:topic/foo"    

Upvotes: 6

V Maharajh
V Maharajh

Reputation: 9639

This is now supported natively in Serverless Framework.

functions example

  functions:
    hello:
      handler: my-function.handler
      environment:
        var: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*:*'

iam role example

  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:*
          Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${AWS::StackName}-*

See Pseudo Parameters Reference for the official docs.

Upvotes: 58

Sam J
Sam J

Reputation: 724

There's a handy serverless plugin https://www.npmjs.com/package/serverless-pseudo-parameters that adds the ability to reference aws parameters such as region and account id that i've just started using to much success.

Upvotes: 24

jens walter
jens walter

Reputation: 14029

Serverless itself cannot reference those variables since those are defined within CloudFormation, but not exposed in serverless.

If you need those in the resources section you can directly access them via "Ref"-call.

AWS CloudFormation Pseudo-variables

If you need those variable as function environment variables, you can overwrite the serverless generated function code with CloudFormation code.

So to achieve this, you must modify you serverless.yml by the following pattern.

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"

Upvotes: 9

Related Questions