Skip to content

How do I resolve the "Already Exists" error that I receive when I redeploy my AWS CDK code after I delete the stack from the deployment?

6 minute read
1

When I redeploy my AWS Cloud Development Kit (AWS CDK) code, I receive an "Already Exists" error.

Short description

By default, AWS CDK protects certain resources that store user data such as Amazon Simple Storage Service (Amazon S3) buckets and Amazon DynamoDB tables. AWS CDK sets the removalPolicy property for these resources to RETAIN.

When you delete an AWS CloudFormation stack, these resources stay in your AWS account even after the stack reaches the DELETE_COMPLETE state.

If you assigned custom names such as bucketName or tableName for these retained resources, then you receive the "Already Exists" error when you try to redeploy the same CDK code. AWS can't use a name that already exists in your account to create a new resource.

Note: The following examples use an Amazon S3 bucket resource associated with the S3 bucket class in AWS CDK.

Example custom named resource:

const s3Bucket = new s3.Bucket(this, 's3-bucket', { 
  bucketName: 'amzn-s3-demo-bucket', 
  versioned: false, 
  encryption: s3.BucketEncryption.S3_MANAGED 
});

To resolve this issue, use one of the following options.

Resolution

Use CloudFormation automatic import

To manage an existing resource with your new CloudFormation stack, use the auto import feature to add it to the stack. This is the simplest solution for most scenarios. CloudFormation's auto-import feature automatically detects and imports existing resources during deployment. For more information, see Import AWS resources into a CloudFormation stack automatically.

To turn on automatic import, complete the following steps:

  1. Add a property to your CDK code that specifies the exact name of your existing resource. The name in your code must match the existing resource exactly. Make sure that this identifier matches the existing resource name or identifier. The following is an example CDK code for an existing S3 bucket named my-existing-bucket:

    new s3.Bucket(this, 'MyBucket', { 
        bucketName: 'my-existing-bucket', // Must match the existing resource's name exactly 
      });

    In the preceding example, bucketName specifies the physical name for the bucket.

  2. From your CDK project directory, deploy your stack with the --import-existing-resources flag. Run the following command in your terminal:

    cdk deploy --import-existing-resources

Manually delete the retained resource

If you don't need to keep the existing resource, then you can delete it manually and redeploy your stack.

Note: This permanently deletes the resource and any data that it contains.
To delete the resource and redeploy your stack, complete the following steps:

  1. Open the AWS Management Console.
  2. Navigate to the service console for the retained resource.
  3. Manually delete the resource.
  4. From your CDK project directory, run the following command in your terminal to redeploy your AWS CDK stack:
    cdk deploy

Change the Resource Name

Update your CDK code to use a different custom name that doesn't conflict with the retained resource. This creates a new resource with a new name. The old resource remains in your account.
To update resource name in CDK code, complete the following steps:

  1. Open the stack file in your code editor where you defined the resource.
  2. Update the custom name property to a unique value.
    Example:
    const s3Bucket = new s3.Bucket(this, 's3-bucket', { 
      bucketName: 'amzn-s3-demo-bucket-v2', // Changed name 
      versioned: false, 
      encryption: s3.BucketEncryption.S3_MANAGED 
    });
    In the preceding example, the S3 bucket name is changed to amzn-s3-demo-bucket-v2.
    Note: Different resource types use different naming properties. For example, S3 buckets use bucketName, DynamoDB tables use tableName, and Lambda functions use functionName.
  3. From your CDK project directory, run the following command in your terminal:
    cdk deploy

Remove the Custom Name

Remove the custom name property from your code and AWS CDK automatically generates a unique name for you.

To remove the custom name property, complete the following steps:

  1. Open the stack file in your code editor where you defined the resource, then remove the custom name property. 
    Example:
    const s3Bucket = new s3.Bucket(this, 's3-bucket', { 
      // bucketName: 'amzn-s3-demo-bucket-v2', property removed 
      versioned: false, 
      encryption: s3.BucketEncryption.S3_MANAGED 
    });
    In the preceding example, without the bucketName property, CDK automatically generates a unique name for the resource.
  2. From your CDK project directory, run the following command in your terminal to redeploy your stack:
    cdk deploy

Use the cdk import command to manually import resources

You can use the cdk import command to manually import resources to the stack. This option gives you precise control over the import process but does require manual steps.

Important: During a cdk import operation, you can't create or update other resources.

To manually import resources to your stack, complete the following steps:

  1. Verify that the resource you want to import supports the import operation. To verify, see the Import column for the specific resource type in the Resource type support documentation. If the resource type shows Yes in the Import column, you can proceed.

  2. Open your CDK stack file in your code editor and temporarily comment out all other resource definitions. Leave only the resource you want to import uncommented. This is important because cdk import can’t handle other resources during the import process.

  3. Make sure the resource definition includes a removal policy set to RETAIN. This prevents accidental deletion if the resource is later removed from the stack.
    Example for an S3 Bucket:

    const s3Bucket = new s3.Bucket(this, 's3-bucket', { 
      bucketName: 'amzn-s3-demo-bucket', 
      removalPolicy: RemovalPolicy.RETAIN 
    });
  4. From your CDK project directory, run the following command in your terminal to start the import:

    cdk import
  5. When prompted, enter the resource identifier for the resource you want to import. The identifier depends on the resource type. For example, for an S3 Bucket, enter the bucket name such as amzn-s3-demo-bucket.

  6. After the import completes successfully, go back to your CDK stack file and uncomment the other resource definitions that you commented out in Step 2.

  7. From your project directory, run the following command in your terminal to deploy the complete stack with all resources:

    cdk deploy
12 Comments

This article does not explain the usual action following retaining, which is the intent to re-use the retained resource in the next stack creation. Regardless of using a custom or auto-generated name, how does one import them? The ".from" static functions on the CDK resources for imports are only pointers to the account resources and cannot be resumed with ongoing modifications to the stack resources.

replied 3 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT

replied 3 years ago

Unfortunately, this post is very disappointing. Is there a way AWS CDK can be smart to automatically import these retained stateful resources back into the stack? That was the resolution I was hoping to see. Correct me if I'm wrong, but if we'd like to keep the date stored in these resources, we'd have to craft a workaround? Perhaps, rename retained resource and write some script / lambda function to import items?

replied 3 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT

replied 3 years ago

What if I want to reuse the resource? That's the main purpose of retaining it in my case also.

replied 3 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
MODERATOR

replied 3 years ago

CDK should automatically import resources that already exist, otherwise it's largely useless for IaC for anything that isn't stateless.

replied 3 years ago

Echoing the replies you have already received on this article. The usual desired behavior is to re-import these already existing resources. You should either explain how to do that manually or implement the behavior for cdk to do this.

replied 2 years ago

I agree with the comments above, we have been facing as well this error with "Resource of type 'AWS::IAM::Role' with identifier 'our-role-name-here' already exists.", although IAM Role have a default removalPolicy property to DESTROY.

replied 2 years ago

I agree, I expected to see a way to deploy changes retaining the bucket containing the data. Should we handle "manually" the import of the arn?

    def __get_or_create_s3_bucket(self) -> Bucket:
        """
        Retrieves the S3 bucket.  If it exists, it is imported.  If it
        does not exist, a new bucket is created.

        :return: The S3 Bucket
        """
        bucket_arn = Fn.sub("arn:aws:s3:::${bucketName}", {"bucketName": self.bucket_name})
        try:
            # Attempt to import the bucket.
            bucket = Bucket.from_bucket_arn(self.stack, self.bucket_id, bucket_arn)
            print(f"Imported existing bucket: {self.bucket_name}")
            return bucket

replied 2 years ago

We are getting this error with an AWS Batch job definition in one of our Stacks, however it is not possible to delete Batch job definitions, only deregister them to have them auto-deleted 180 days later. We don't have the option to use a new name, but also can't wait 180 days to have it deleted before redeploying our Stack.

replied a year ago

This article was reviewed and updated on 2026-06-16.

EXPERT

replied 2 months ago