Don't assign names to CDK resources

avatar

Borislav Hadzhiev

Last updated: Apr 13, 2022

banner

Photo from Unsplash

The drawbacks of explicitly assigning Names in AWS CDK #

When we create a CDK resource and explicitly set its name we are unable to update properties on that resource that require replacement.

If we attempt to update an immutable configuration property on a resource with an explicitly set name, our CDK Stack will be in a gridlocked state.

The only ways for us to continue development would be to delete the stack and re-create it or rename the resource.

For example, say we have the following Dynamodb table:

const table = new dynamodb.Table(this, 'todos-table', { // 👇 explicitly setting tableName tableName: 'my-table', partitionKey: {name: 'date', type: dynamodb.AttributeType.STRING}, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, removalPolicy: cdk.RemovalPolicy.DESTROY, });

If we look at the CloudFormation stack, we can see that the Physical ID (resource name) of the table is my-table:

explicit table name

Let's now update the table's partitionKey property:

const table = new dynamodb.Table(this, 'todos-table', { // 👇 explicitly setting tableName tableName: 'my-table', // 👇 updated the partition key partitionKey: {name: 'todoId', type: dynamodb.AttributeType.NUMBER}, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, removalPolicy: cdk.RemovalPolicy.DESTROY, });

If we run npx aws-cdk diff, we see that the change we've made requires resource replacement:

requires replacement

Let's now try to go through with the update and update our stack with:

npx aws-cdk deploy

As expected our update failed with the message:

CloudFormation cannot update a stack when custom-named resource requires replacing. Rename resource-name and update the stack again.

update failed

At this point we have 2 options:

  • Change the name we've set for the resource so the stack can get unstuck
  • Delete our stack and re-deploy it

After updating the tableName property, the stack is in an UPDATE_COMPLETE state again:

const table = new dynamodb.Table(this, 'todos-table', { // 👇 updated the name to fix the stack tableName: 'my-table-2', partitionKey: {name: 'todoId', type: dynamodb.AttributeType.NUMBER}, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, removalPolicy: cdk.RemovalPolicy.DESTROY, });

updated name

If we have to constantly keep changing our resource names every time we have to change a property that requires resource replacement, it's probably not a good idea to explicitly set resource names to begin with.

Letting CDK generate Names for us #

The solution is to let CDK generate a name for us. For example, if we omit the tableName property:

const table = new dynamodb.Table(this, 'todos-table', { partitionKey: {name: 'todoId', type: dynamodb.AttributeType.NUMBER}, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, removalPolicy: cdk.RemovalPolicy.DESTROY, });

CDK will auto-generate a unique Physical ID (Resource name) for us that won't cause issues on consecutive updates:

autogenerated name

The name consists of the stack name, in this case my-cdk-stack, the construct id - todos-table and a hash. If you want to learn more about Identifiers in CDK check out my other article - CDK Identifiers Tutorial.

The Exception #

When we need to refer to resources from another CDK stack, we have to explicitly set resource names.

The resource name that we import in one stack has to match the name of the exported resource from the other stack.

Further Reading #

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.