Last updated: Jan 26, 2024
Reading timeยท4 min
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:
Let's look at an example of accessing the ARN of an S3 bucket.
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:
We used the Bucket construct to create a bucket resource.
We accessed the bucketArn
property and stored the value in the
s3BucketArn
variable.
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.
npx aws-cdk synth
The output shows that the bucket ARN is a token at synthesis time.
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.
I'll deploy via the cdk deploy
command, so we can see the Arn
value resolved
in the Outputs
section of the CloudFormation console.
npx aws-cdk deploy
The resolved Arn is visible in the Value
column of our Outputs
section.
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.
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.
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:
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;
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:
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:
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:
{ "Outputs": { "myCfnBucketArn": { "Value": { // ๐ "Fn::GetAtt": [ "avatarsbucketE3043F49", "Arn" ] } } } }
The best way to access an Arn
in CDK is by using the resource-specific
resourceNameArn
property on the Level 2 Construct.
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:
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.
You can learn more about the related topics by checking out the following tutorials: