Skip to content

CDK Version Upgrade Causing DynamoDB Table Replacement and Unreferenced Historical Data

0

In my application, the current deployment approach combines both infrastructure resources (e.g., DynamoDB tables) and serverless components (e.g., Lambda functions, SNS, SQS) within a single AWS CDK stack. After upgrading CDK and related packages (from "aws-cdk-lib": "2.95.0" to "aws-cdk-lib": "2.179.0"), redeployment is causing CloudFormation to replace the DynamoDB table—a new table is created and used by the application, while the original table with historical data remains unreferenced.

Why is the table being replaced and left unreferenced, and how can we prevent this in future CDK upgrades?

The table was originally created using the following code:

import * as cdk from "aws-cdk-lib";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
const transactionTable = new dynamodb.TableV2(this, 'MailPolicyUpdateTable', {
  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
  removalPolicy: !["e2e", "prd"].includes(appEnv) ? cdk.RemovalPolicy.DESTROY : cdk.RemovalPolicy.RETAIN,
  pointInTimeRecovery: true,
  globalSecondaryIndexes: [
    {
      indexName: "date_index",
      partitionKey: { name: 'date', type: dynamodb.AttributeType.STRING },
    },
  ],
});
1 Answer
0

When upgrading CDK versions, especially with significant version jumps like yours (from 2.95.0 to 2.179.0), you may encounter issues with resource replacement, particularly for stateful resources like DynamoDB tables.

The main reason your DynamoDB table is being replaced is likely due to one of these factors:

  1. TableV2 construct changes: The TableV2 construct might have had internal implementation changes between CDK versions that affect how CloudFormation interprets the resource definition.

  2. Table name not explicitly specified: In your code snippet, you're not providing a tableName property. Without an explicit table name, CDK generates a unique physical ID for the table. When you upgrade CDK versions, this generated ID might change, causing CloudFormation to see it as a new resource.

  3. L1 to L2 construct changes: If there were changes in how the L2 construct (TableV2) maps to the underlying L1 construct (CfnTable), this could trigger a replacement.

To prevent this issue in future upgrades:

  1. Specify an explicit table name:
const transactionTable = new dynamodb.TableV2(this, 'MailPolicyUpdateTable', {
tableName: 'MailPolicyUpdateTable',  // Add this line
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
// other properties...
});
  1. Use the CDK Refactor feature: For future structural changes, consider using CDK's refactor capability which is designed to safely reorganize resources without replacement.

  2. Split stateful and stateless resources: Consider separating your DynamoDB tables into their own stack, separate from frequently changing components like Lambda functions. This isolation helps prevent unintended replacements of stateful resources.

  3. Test upgrades in non-production environments: Always test CDK upgrades in development environments first to catch potential resource replacements before they affect production data.

For your current situation with the unreferenced historical data, you'll need to:

  1. Migrate the data from the old table to the new one
  2. Or update your application to reference the old table (you'll need to identify it in the AWS Console)
  3. Consider using the fromTableName method to reference the existing table instead of creating a new one if the table already exists

Remember to always set removalPolicy: cdk.RemovalPolicy.RETAIN for important tables in production to prevent accidental deletion, as you've already done.
Sources
Conditional Creation of DynamoDB | AWS re:Post
CDK TypeScript: Conditional Creation of DynamoDB Table | AWS re:Post
AWS Cloud Development Kit (CDK) Launches Refactor | AWS DevOps & Developer Productivity Blog
class CfnTable (construct) · AWS CDK

answered 10 months ago

AWS
EXPERT

reviewed 10 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.