Import an Existing S3 Bucket in AWS CDK

avatar
Borislav Hadzhiev

Last updated: Apr 14, 2022
4 min

banner

# Table of Contents

  1. Import an S3 Bucket by Name in AWS CDK
  2. Import an S3 Bucket by ARN in AWS CDK
  3. Import an S3 Bucket by Attributes in AWS CDK
  4. Importing Existing Resources in CDK

# Import an S3 Bucket by Name in AWS CDK

The easiest way to import an existing S3 bucket into a CDK stack is to use the static fromBucketName method on the Bucket class.

The code for this article is available on GitHub
lib/cdk-starter-stack.ts
import * as iam from 'aws-cdk-lib/aws-iam'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const importedBucketFromName = s3.Bucket.fromBucketName( this, 'imported-bucket-from-name', 'YOUR_EXTERNAL_BUCKET_NAME', ); console.log('bucket name ๐Ÿ‘‰', importedBucketFromName.bucketName); console.log('bucket arn ๐Ÿ‘‰', importedBucketFromName.bucketArn); // ๐Ÿ‘‡ using methods on the imported bucket importedBucketFromName.grantRead(new iam.AccountRootPrincipal()); } }

We used the fromBucketName static method to import an external S3 bucket by name.

After we have imported the bucket into our CDK stack, we can use the associated methods. For example, to grant read permissions to a lambda function.

If I synthesize the stack with npx aws-cdk synth command, we can see that CDK is able to infer the bucket name based on our input to the fromBucketName method:

import bucket from name

The only unresolved value is the partition, which CDK is not able to infer from the bucket name.

You could pass the bucket name to your CDK stack as an environment variable, in CDK context, or via a parameter.

# Import an S3 Bucket by ARN in AWS CDK

In order to import an existing S3 bucket by ARN in AWS CDK, we have to use the static fromBucketArn method on the Bucket class.

The code for this article is available on GitHub
lib/cdk-starter-stack.ts
import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const importedBucketFromArn = s3.Bucket.fromBucketArn( this, 'imported-bucket-from-arn', 'arn:aws:s3:::YOUR_EXTERNAL_BUCKET_NAME', ); console.log('bucket name ๐Ÿ‘‰', importedBucketFromArn.bucketName); console.log('bucket arn ๐Ÿ‘‰', importedBucketFromArn.bucketArn); } }

We used the fromBucketArn static method to import an external S3 bucket into our CDK stack.

Same as with fromBucketName, we can use the methods associated with the class after we've imported the bucket.

Based on the ARN we passed in the call to fromBucketArn, CDK is able to infer the bucket name and bucket ARN at synthesis time:

import bucket from arn

# Import an S3 Bucket by Attributes in AWS CDK

In order to import an existing S3 bucket by Attributes in CDK, we have to use the static fromBucketAttributes method on the Bucket class.

The code for this article is available on GitHub
lib/cdk-starter-stack.ts
import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const importedBucketFromAttributes = s3.Bucket.fromBucketAttributes( this, 'imported-bucket-from-attributes', { bucketArn: 'arn:aws:s3:::YOUR_EXTERNAL_BUCKET_NAME', region: 'SOME_OTHER_REGION', }, ); console.log('bucket name ๐Ÿ‘‰', importedBucketFromAttributes.bucketName); console.log('bucket arn ๐Ÿ‘‰', importedBucketFromAttributes.bucketArn); } }

You would use the fromBucketAttributes method if the region name of the external bucket differs from the region the CDK stack is configured for.

By default, the region property for the bucket is inferred from the CDK stack's region.

Since the region of the bucket is not present in the ARN, there isn't a good way for CDK to infer it, other than to assume the bucket's region is the same as the CDK stack's region.

# Importing Existing Resources in CDK

To import existing resources in CDK we have to use the static fromResource* methods on the resource's construct, for instance:

As a general rule of thumb, we use the fromResourceName and fromResourceArn methods unless we don't have access to the name or ARN of the resource, in which case we use the fromResourceAttributes method.

The code for this article is available on GitHub

To import an existing bucket by name into a CDK stack, we can use the fromBucketName static method:

lib/cdk-starter-stack.ts
const existingBucketFromName = s3.Bucket.fromBucketName( this, 'bucket-from-name-id', 'YOUR_BUCKET_NAME', ); console.log('existingBucketFromName ๐Ÿ‘‰ ', existingBucketFromName.bucketName);

If I now run the cdk synth command, we can see that the value is resolved at synthesis time:

existing bucket name

To import an existing bucket by ARN we can use the fromBucketArn static method:

lib/cdk-starter-stack.ts
const existingBucketFromArn = s3.Bucket.fromBucketArn( this, 'bucket-from-arn-id', 'YOUR_BUCKET_ARN', );

And to import an existing bucket from Attributes, we use the fromBucketAttributes static method:

lib/cdk-starter-stack.ts
const existingBucketFromAttributes = s3.Bucket.fromBucketAttributes( this, 'bucket-from-attributes-id', { region: 'us-east-1', bucketArn: 'arn:aws:s3:::YOUR_BUCKET_NAME', }, );

All of the above methods resolve at synthesis time.

Most Level 2 Constructs implement at least 2 of the 3 fromResource* methods.

For example, to import an existing Dynamodb table by name, we have to use the fromTableName static method:

lib/cdk-starter-stack.ts
const existingTableFromName = dynamodb.Table.fromTableName( this, 'table-from-name-id', 'YOUR_TABLE_NAME', ); console.log('existingTableFromName ๐Ÿ‘‰ ', existingTableFromName.tableName);

The value again resolves at synthesis time:

existing table name

To import an existing table from ARN we have to use the fromTableArn static method:

lib/cdk-starter-stack.ts
const existingTableFromArn = dynamodb.Table.fromTableArn('YOUR_TABLE_ARN');

And to import an existing table from attributes we have to use the fromTableAttributes static method:

lib/cdk-starter-stack.ts
const existingTableFromAttributes = dynamodb.Table.fromTableAttributes( this, 'table-from-attributes-id', { tableName: 'YOUR_TABLE_NAME', }, );

It's quite repetitive once we know what the naming convention of the methods is.

Most of the time we end up using the fromResourceName and fromResourceArn methods, and resort to using fromResourceAttributes when we don't have the name or the ARN of the resource.

# 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 ยฉ 2023 Borislav Hadzhiev