I use aws cdk to deploy a stack that contains a dynamoDB table. For each deploy of my stack, CloudFormation creates a new table and links it to my lambda function. I want to know how I can reuse an existing table, without the need to create a new one if it was already created for this stack (to avoid migrating my record to a new instance of the dynamoDB table).
Here is my code:
const table = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
I previously tried to use Table.fromTableName
, but I cloudn’t link my lambda function to the table…
Here is the code I tried:
let myTable: Table; // my table
let lambdaFunction: Function = new Function(...); // my function
// table creation
try {
myTable = Table.fromTableName(stack, tableId, name);
} catch (_) {
myTable = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
}
//referencing the table in my lambda function via env
lambdaFunction.addEnvironment("TABLE_NAME", myTable.tableName);
When the lambda tries to access the table a ResourceNotFound
exception is thrown.
Any ideas?
As well I heard that if I use the same tableName
in new Table(...)
dynamoDB will return me the existing table without creating a new one, but I don’t know if it’s true…
Does someone knows?
3
Answers
I rechecked the matter, the answer actually is to use constant constructor ids along with constant resource names.
From this blog:
So what I did is to give hard-coded constructor ids, along with hard-coded table name, that wouldn't be changed. This preserve the logical ID of the resource to CloudFormation would identify it and prevent deletion and re-creation of the resource.
Note that you need to take a different approach if you are using nested constructors, as detailed in the blog:
So, as said here is the fixed code:
This will work with an existing table, no need to use
Table.fromTableName
to import it :)So, it wasn't linked to the removal policy of the table or the use of
Table.fromTableName
, only that the logical ID was messed up...First of all you need to change retention policy of the table, as a
Snapshot
will not retain your table and data in a usable manner. Explicitly defining a table name will also allow you to easily import the table again, without having to understand what CDK named the table for you.Then
Table.fromTableName
will work, as long as you provide the correct table name from theTable
interface.If you create the stack often, and don’t often know what the tableName is, then every time you change the table you can store the name in Parameter Store and retrieve it when needed.
To reuse a DynamoDB table in TypeScript, you can use the AWS SDK for JavaScript/TypeScript (
aws-sdk
package) to interact with DynamoDB. Here’s an example of how you can reuse a DynamoDB table:Install the necessary dependencies by running the following command in your project directory:
Import the necessary modules in your TypeScript file:
Configure the AWS SDK with your AWS credentials and the appropriate region:
Replace ‘YOUR_REGION’, ‘YOUR_ACCESS_KEY’, and ‘YOUR_SECRET_ACCESS_KEY’ with your actual AWS region and credentials.
Create a DynamoDB document client using the configured AWS SDK:
Use the DynamoDB client to perform operations on the existing table. For example, to retrieve an item from the table:
Replace ‘YOUR_TABLE_NAME’ with the name of your existing DynamoDB table and ‘PRIMARY_KEY_VALUE’ with the actual value of the primary key attribute you want to retrieve.
By following these steps, you can reuse the existing DynamoDB table and perform various operations using the AWS SDK for JavaScript/TypeScript.