Bill
Bill

Reputation: 2993

How to get the account id with cdk

I wrote a simple typescript with AWS CDK and try to get the account id

import cdk = require("@aws-cdk/core");

const app = new cdk.Stack();

console.log(app.account);

But get below output

$ tsc index.ts 
$ node index.js 
${Token[AWS::AccountId.0]}

So what's the meaning of Token here? How to get the real account id?

Updates

$ cdk init app --language=typescript

# replace lib/<name>-stack.ts with @Rob Raisch 's code

$ cdk synth
${Token[AWS::AccountId.0]}
Outputs:
  MyStackAccount:
    Description: Account of this stack
    Value:
      Ref: AWS::AccountId
Resources:
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Modules: aws-cdk=1.2.0,@aws-cdk/core=1.8.0,@aws-cdk/cx-api=1.8.0,jsii-runtime=node.js/v10.15.3

$ cdk deploy
${Token[AWS::AccountId.0]}
MyStack: deploying...
MyStack: creating CloudFormation changeset...
 0/2 | 11:58:59 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 1/2 | 11:58:59 AM | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata 
 2/2 | 11:59:00 AM | CREATE_COMPLETE      | AWS::CloudFormation::Stack | MyStack 

 ✅  MyStack

Outputs:
MyStack.MyStackAccount = 123456789012

Upvotes: 20

Views: 35498

Answers (3)

valentin
valentin

Reputation: 637

You can use the environment variable CDK_DEFAULT_ACCOUNT:

console.log(process.env.CDK_DEFAULT_ACCOUNT)

Quoting AWS documentation:

...your stack can use two environment variables provided by the AWS CDK CLI: CDK_DEFAULT_ACCOUNT and CDK_DEFAULT_REGION. These variables are set based on the AWS profile specified using the --profile option, or the default AWS profile if you don't specify one.

Note: I'm using version 2.84.0 of aws-cdk

Upvotes: 4

Matt Klein
Matt Klein

Reputation: 8444

The question is "How to get the account id" but you don't mention why.

If you want to get your Account number for IAM purposes, such as only allowing your account to use your API Gateway (for example), then you can also use the Principal type AccountRootPrincipal which always points to the "current" account.

    const policy = new PolicyStatement({
      effect: Effect.ALLOW,
      actions: ['execute-api:Invoke'],
      resources: ['arn:aws:execute-api:*:*:*/*'],
      principals: [new AccountRootPrincipal()], // <-- Your account only
    });

Upvotes: 3

Rob Raisch
Rob Raisch

Reputation: 17367

I had exactly the same issue until I realized that, until you run cdk deploy, there are no such values, only placeholders (like ${Token[AWS::AccountId.0]}) that will be filled in during deployment.

Think of it this way, your CDK stack is a plan to create a number of resources, but until you run cdk deploy, those resources do not exist and so, cannot be queried for their values.

One way to get the value you need would be to add this to your stack constructor:

// Publish the custom resource output
new cdk.CfnOutput(this, "MyStackAccount", {
  description: "Account of this stack",
  value: this.account
});

As in:

class MyStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, "MyStack", props);

    new cdk.CfnOutput(this, "MyStackAccount", {
      description: "Account of this stack",
      value: this.account
    });
  }
}

which, when you run cdk deploy, will output:

MyStack.StackAccount = 987XXXXXX456

Upvotes: 27

Related Questions