How to get ARN of resources in AWS CDK

avatar
Borislav Hadzhiev

Last updated: Jan 26, 2024
4 min

banner

# Getting ARNs of Resources in AWS CDK

ARNs (Amazon Resource Names) are used to uniquely identify AWS resources across all regions, accounts and services.

To get the Arn of a resource we have to use the resource-specific resourceNameArn property, for example:

The code for this article is available on GitHub

Let's look at an example of accessing the ARN of an S3 bucket.

lib/cdk-starter-stack.ts
import * as s3 from 'aws-cdk-lib/aws-s3'; 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); const s3Bucket = new s3.Bucket(this, 'avatars-bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // ๐Ÿ‘‡ assign the arn to a variable const s3BucketArn = s3Bucket.bucketArn; console.log('bucketArn ๐Ÿ‘‰ ', s3BucketArn); new cdk.CfnOutput(this, 'myBucketArn', { value: s3BucketArn, description: 'The arn of the s3 bucket', }); } }

In the code sample:

  1. We used the Bucket construct to create a bucket resource.

  2. We accessed the bucketArn property and stored the value in the s3BucketArn variable.

  3. We passed the bucket ARN in a call to console.log and wrote the value to an Output.

I'll now run the synth command to run my CDK code and generate the CloudFormation template.

shell
npx aws-cdk synth

The output shows that the bucket ARN is a token at synthesis time.

token arn

Tokens in CDK are encoded values that will get resolved at deployment time by CloudFormation. This means that we can't access the resolved resource Arn in our CDK code.

When we run the cdk synth command a CloudFormation template gets generated in the cdk.out directory of our project.

If we take a look at the Outputs section, we can see that our reference to the bucket Arn has been replaced by the GetAtt intrinsic function.

cdk out arn

I'll deploy via the cdk deploy command, so we can see the Arn value resolved in the Outputs section of the CloudFormation console.

shell
npx aws-cdk deploy

The resolved Arn is visible in the Value column of our Outputs section.

arn resolved

The value for the Arn of resources gets resolved by CloudFormation at deployment time, rather than synthesis time. We only have access to the encoded token value in our code.

If you are working with CfnResources instead of Level 2 Constructs.

# Getting ARN of Cfn Resources in CDK

Sometimes, we have to work with the lower-level Cfn resources, which don't expose the resourceNameArn properties.

In order to access the Arn of a Cfn Resource, we have to use the attrArn property on the resource.

lib/cdk-starter-stack.ts
import * as s3 from 'aws-cdk-lib/aws-s3'; 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); const s3Bucket = new s3.Bucket(this, 'avatars-bucket'); // ๐Ÿ‘‡ Get access to the Cfn Resource const cfnBucket = s3Bucket.node.defaultChild as s3.CfnBucket; // ๐Ÿ‘‡ access the arn const cfnArn = cfnBucket.attrArn; } }

We used the attrArn property. The name of the attrArn property is consistent. For example, getting the ARN of a Dynamodb CfnTable looks as follows:

lib/cdk-starter-stack.ts
const table = new dynamodb.Table(this, 'my-table', { partitionKey: {name: 'todoId', type: dynamodb.AttributeType.NUMBER}, removalPolicy: cdk.RemovalPolicy.DESTROY, }); console.log('on Level 2 Construct ๐Ÿ‘‰', table.tableArn); // ๐Ÿ‘‡ get access to the Level 1 Cfn resource const cfnTable = table.node.defaultChild as dynamodb.CfnTable; // ๐Ÿ‘‡ access the arn const cfnTableArn = cfnTable.attrArn;

# Getting ARNs via the GetAtt Function in CDK

The third method to get the Arn of a resource is very close to how we would do it in CloudFormation.

We have to use the getAtt method on the Fn class and get the Arn attribute:

lib/cdk-starter-stack.ts
import * as s3 from 'aws-cdk-lib/aws-s3'; 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); const s3Bucket = new s3.Bucket(this, 'avatars-bucket'); // ๐Ÿ‘‡ Get access to the Cfn Resource const cfnBucket = s3Bucket.node.defaultChild as s3.CfnBucket; // ๐Ÿ‘‡ access the arn const bucketArn = cdk.Fn.getAtt(cfnBucket.logicalId, 'Arn').toString(); } }

We used the getAtt method on the Fn class. The method takes two parameters:

  1. the logical ID of the resource
  2. the name of the attribute we're trying to access

The getAtt method returns an object that exposes a toString() function, which we use in order to get a string representation of the value.

This approach is very similar to how we would do this in CloudFormation, via the GetAtt intrinsic function:

template.json
{ "Outputs": { "myCfnBucketArn": { "Value": { // ๐Ÿ‘‡ "Fn::GetAtt": [ "avatarsbucketE3043F49", "Arn" ] } } } }

# Summary

The best way to access an Arn in CDK is by using the resource-specific resourceNameArn property on the Level 2 Construct.

lib/cdk-starter-stack.ts
const s3Bucket = new s3.Bucket(this, 'avatars-bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); const bucketArn = s3Bucket.bucketArn;

When working with Cfn Resources (Level 1 Constructs), we have to use the attrArn property:

lib/cdk-starter-stack.ts
const s3Bucket = new s3.Bucket(this, 'avatars-bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // ๐Ÿ‘‡ Get access to the Cfn Resource const cfnBucket = s3Bucket.node.defaultChild as s3.CfnBucket; const cfnArn = cfnBucket.attrArn;

The ARN values are just encoded Tokens at synthesis time, they are resolved by CloudFormation at deployment time.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev