Skip to content

DynamoDB table creation using CDK typescript

0

I am implementing a solution in AWS CDK to conditionally create a DynamoDB table only if it does not already exist. Below is the code snippet I am using:

Issue: If the table exists, tableExistenceCheck.getResponseField("Table.TableName") correctly returns the table name, and tableExists is true. However, if the table does not exist, the call to getResponseField("Table.TableName") throws an error because the "Table.TableName" field does not exist in the response.

I need to implement a solution to conditionally create the DynamoDB table only if it does not already exist, and otherwise reference the existing table.

     const transactionTableName = `MailPolicyUpdatesTable`;

    // Custom Resource to check if the table exists
    const tableExistenceCheck = new cr.AwsCustomResource(this, "TransactionTableExistenceCheck", {
      onUpdate: { 
        service: "DynamoDB",
        action: "describeTable",
        parameters: {
          TableName: transactionTableName,
        },
        physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
        ignoreErrorCodesMatching: "*ResourceNotFoundException*"
      },
      policy: cr.AwsCustomResourcePolicy.fromSdkCalls({ resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE }),
    });
    
    // Check if the table exists by looking at the response 
    const tableExists = tableExistenceCheck.getResponseField('Table.TableName') !== undefined;

    // Conditionally create or reference the table
    const transactionTable = tableExists
      ? dynamodb.TableV2.fromTableName(this, "ExistingTransactionTable", transactionTableName)
      : new dynamodb.TableV2(this, "MailPolicyUpdatesTable", {
          tableName: transactionTableName,
          partitionKey: { name: "id", type: dynamodb.AttributeType.STRING },
          removalPolicy: cdk.RemovalPolicy.RETAIN,
          pointInTimeRecovery: true,
          globalSecondaryIndexes: [
            {
              indexName: "date_index",
              partitionKey: { name: "date", type: dynamodb.AttributeType.STRING },
            },
          ],
        });
1 Answer
0

To implement a solution that conditionally creates a DynamoDB table only if it doesn't already exist, you can modify your approach slightly. Instead of relying on the getResponseField method, which throws an error when the table doesn't exist, you can use the getCapturedResponse method of the AwsCustomResource. This method returns the entire response, allowing you to check for the existence of the table more safely.

Here's an improved version of your code:

const transactionTableName = `MailPolicyUpdatesTable`;

// Custom Resource to check if the table exists
const tableExistenceCheck = new cr.AwsCustomResource(this, "TransactionTableExistenceCheck", {
onUpdate: { 
service: "DynamoDB",
action: "describeTable",
parameters: {
TableName: transactionTableName,
},
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
ignoreErrorCodesMatching: "ResourceNotFoundException"
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({ resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE }),
});

// Check if the table exists by examining the entire response
const response = tableExistenceCheck.getCapturedResponse('onUpdate');
const tableExists = response && response.Table;

// Conditionally create or reference the table
const transactionTable = tableExists
? dynamodb.TableV2.fromTableName(this, "ExistingTransactionTable", transactionTableName)
: new dynamodb.TableV2(this, "MailPolicyUpdatesTable", {
tableName: transactionTableName,
partitionKey: { name: "id", type: dynamodb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.RETAIN,
pointInTimeRecovery: true,
globalSecondaryIndexes: [
{
indexName: "date_index",
partitionKey: { name: "date", type: dynamodb.AttributeType.STRING },
},
],
});

In this updated version:

  1. We use getCapturedResponse('onUpdate') to get the entire response from the DescribeTable API call.
  2. We check if the response exists and has a 'Table' property, which indicates the table exists.
  3. Based on this check, we either reference the existing table or create a new one.

This approach avoids the error when the table doesn't exist and provides a more robust way to conditionally create or reference the DynamoDB table.

Remember that this method still has a small chance of race conditions in a distributed environment. If absolute consistency is required, you might need to implement additional error handling or use a more robust strategy.
Sources
CDK TypeScript: Conditional Creation of DynamoDB Table | AWS re:Post
class CfnTable (construct) · AWS CDK

answered a year 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.