Skip to main content

How to set semi-random name for Amazon S3 bucket using AWS CDK

ยท 3 min read
Nathan Agez

AWS CDK

Sometimes you may need to deploy Amazon S3 buckets ๐Ÿชฃ with a semi-random names.

In my case, I needed to deploy 2 Amazon S3 buckets with this format:

<projectName>-<environment>-input-<uid>
<projectName>-<environment>-output-<uid>

When creating a bucket with AWS CDK, we use the Amazon S3 Construct Library.

If we take a look at the bucketName construct prop, it says that if nothing is provided, CloudFormation will automatically generate a name for us. bucketName prop

So, if you have Construct IDs and logical IDs that make sense, it should give you a unique bucket name every time.

The logical names of resources in AWS CloudFormation are different from the names of resources that are shown in the AWS Management Console after AWS CloudFormation has deployed the resources. The AWS CDK calls these final names physical names.

To understand how CloudFormation is going to format these names, we need to understand how physical names work.

Physical names of the Stacks โœจ

The physical names of the AWS CloudFormation stacks are automatically determined by the AWS CDK based on the stack's construct path in the tree. By default, a stack's name is derived from the construct ID of the Stack object, but you can specify an explicit name using the stackName prop (in Python, stack_name), as follows.

new MyStack(this, 'constructId', { stackName: 'Stack2' });

Physical names of the Resources ๐Ÿƒ

If we create our Amazon S3 bucket without specifying a bucket name inside our MyStack stack

// const bucket = new s3.Bucket(this, 'theConstructId');
const bucket = new s3.Bucket(this, 'MyBucket');

AWS CloudFormation will create the Amazon S3 bucket with the logical ID Stack2MyBucket4DD88B4F with the physical name stack2mybucket4dd88b4f-iuv1rbv9z3to.

ARN and Instrasic Functions to the rescue ๐Ÿ˜ฒ

If we go back to our basic problem and want to generate accurate semi-random names, we can do it this way:

Using the Stack ARN suffix, which is a random guid: arn:aws:cloudformation:us-west-2:account-id:stack/Stack2/1234567db123-11e4-da77-872e-51af3dc0 and Intrinsic functions Fn::Select and Fn::Split

import * as cdk from '@aws-cdk/core'
import * as s3 from '@aws-cdk/aws-s3'
import { Construct } from 'constructs'
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper'

export class cdkStack extends cdk.Stack {
constructor(
scope: Construct,
id: string,
props?: cdk.StackProps,
amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps
) {
super(scope, id, props)

/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
new cdk.CfnParameter(this, 'env', {
type: 'String',
description: 'Current Amplify CLI env name',
})

const {projectName} = AmplifyHelpers.getProjectInfo()

// Gives you `1234567db123`
const uid = cdk.Fn.select(0, cdk.Fn.split('-', cdk.Fn.select(2, cdk.Fn.split('/', this.stackId))))

const outputBucket = new s3.Bucket(this, 'output-bucket', {
bucketName: `${projectName.toLowerCase()}-${cdk.Fn.ref('env')}-output-${uid}`,
})

const inputBucket = new s3.Bucket(this, 'input-bucket', {
bucketName: `${projectName.toLowerCase()}-${cdk.Fn.ref('env')}-input-${uid}`,
})
}
}

Please also keep in mind that you cannot use Template literals (Template strings) for Construct IDs. Some values in our CDK code can't get resolved at synthesis time, but rather get resolved at deployment time. These values are called Tokens.

If you want read more about Tokens in AWS CDK checkout this article ๐Ÿ“™.

Follow me on Twitter (@nathanagez) to stay in touch!