Borislav Hadzhiev
Wed Apr 13 2022·3 min read
Photo by Ihor Malytskyi
Updated - Wed Apr 13 2022
In order to access the accountId
, region
and availabilityZones
properties in our CDK code, we have to set the env
property when instantiating
our Stack.
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); console.log('accountId: ', cdk.Stack.of(this).account); console.log('region: ', cdk.Stack.of(this).region); console.log('availability zones: ', cdk.Stack.of(this).availabilityZones); } } const app = new cdk.App(); new MyCdkStack(app, `my-cdk-stack-dev`, { stackName: `my-cdk-stack-dev`, // 👇 now explicitly setting account and region env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
If we run the npx aws-cdk synth
command, we can see that we are now able to
access the accountId
, region
and availabilityZones
at synthesis time in
our CDK code:
I have excluded the accountId property from the screenshot, but it too was resolved.
The
recommended way by the CDK team
to get access to the accountId
and region
properties is to use the
Stack.of(this).account
and Stack.of(this).region
API.
Notice that in our code snippet above, we used two environment variables that are available in our CDK environment:
{ region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }
The value of these environment variables depends on whether we pass in a
--profile
flag when we issue the npx aws-cdk deploy
command.
For example, if we specify a profile
, the values of CDK_DEFAULT_REGION
and
CDK_DEFAULT_ACCOUNT
would correspond to the profile's region
and account
properties:
npx aws-cdk deploy --profile myprofile my-stack
If we don't set the --profile
flag, the values would correspond to the default
profile's region and account properties:
npx aws-cdk deploy my-stack
Either way, if we have the AWS CLI configured on our machine, by passing in the
CDK_DEFAULT_REGION
and CDK_DEFAULT_ACCOUNT
properties we are explicitly
setting the environment, which enables us to access the properties at synthesis
time in our CDK code.
CDK_DEFAULT_REGION
and CDK_DEFAULT_ACCOUNT
environment variables. The default profile of the different developers working on the project could be set to different regions and accounts.Instead just pass the values as environment variables explicitly. You can hard code the values, manage them as secrets, etc.
An environment-agnostic stack is a stack where we haven't explicitly set the
account
and region
properties.
const app = new cdk.App(); new MyCdkStack(app, `my-cdk-stack-dev`, { stackName: `my-cdk-stack-dev`, // 👇 we are not explicitly setting the region and account // env: { // region: 'us-east-1', // account: 123456789, // } });
Because we haven't explicitly set the env
property in our stack, the account
and region
properties will be resolved by CloudFormation at deploy time rather
than synthesis time.
Since we want access to these properties in our CDK code we have to find a way to resolve them at synthesis time.
Let's try to get the accountId
, region
and availabilityZones
properties in
an environment agnostic stack, without explicitly setting the env property:
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 👇 recommended way to get access to the properties console.log('accountId: ', cdk.Stack.of(this).account); console.log('region: ', cdk.Stack.of(this).region); console.log('availability zones: ', cdk.Stack.of(this).availabilityZones); } } const app = new cdk.App(); new MyCdkStack(app, `my-cdk-stack-dev`, { stackName: `my-cdk-stack-dev`, // 👇 we are not explicitly setting the region and account // env: { // region: 'us-east-1', // account: 123456789, // } tags: {env: 'dev'}, });
We only get unresolved token values that will eventually be resolved at deploy time by CloudFormation.
The solution is to explicitly set the account
and region
and call the
Stack.of
APIs:
console.log('accountId:', cdk.Stack.of(this).account); console.log('region', cdk.Stack.of(this).region); console.log('availability zones', cdk.Stack.of(this).availabilityZones);