💥 AWS CDK 101 - 💫 Dynamodb Local setup and integrating with sam invoke
Tags: typescript, aws, serverless, awscdk
Published: 2022-09-18 17:44:37

🔰  Beginners new to AWS CDK, please do look at my previous articles one by one in this series.

If in case missed my previous article, do find it with the below links.

🔁 Original post at 🔗 [Dev Post aws-cdk-101-sam-local-to-test-and-debug-lambda-function](https://devpost.hashnode.dev/aws-cdk-101-sam-local-to-test-and-debug-lambda-function)

🔁 Reposted at 🔗 [dev to @aravindvcyber aws-cdk-101-sam-local-to-test-and-debug-lambda-function-1afj](https://dev.to/aws-builders/aws-cdk-101-sam-local-to-test-and-debug-lambda-function-1afj)

Also, we have started to develop an open source project which we would be using to play around with refracting the architecture as well as learn CDK stuff at the same time we will provide something useful for our community. Find more about this discussed in the article below.

![arch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msrbf94oefdrnu29a5db.jpeg)

🔁 Original project post at 🔗 [Dev Post aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder](https://devpost.hashnode.dev/aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder)

🔁 Reposted project post at 🔗 [dev to aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder-1m0m](https://dev.to/aws-builders/aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder-1m0m)

[event-forwarder Github repo](https://github.com/aravindvcyber/event-forwarder/)

## Dynamodb local with sam invoke :dango:

Earlier in our article, we have seen how to set up local integration testing of the lambda using sam invoke. Dynamodb local will not only be a cool integration setup to inspect in locally, but also it can help to understand the dynamodb data model using NoSQL workbench. 

### So why do we need now :grey_question:

In our previous article, we mentioned that we have sam local to test the function locally. But we don't have the local dynamodb. We set up that brings that into the same docker network in this article to fix the below error.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tph1bzq3cae01u6banv.png)


Thank you fully the error slack hook post the exception clearly to my slack

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b5c9b44am0xpux5nuhif.png)

## Docker composes dynamodb local :star2:

Let us use docker compose to spin up dynamodb local

### Dynamodb local container :clown_face:

I prefer to use the docker mode of setting up dynamodb local since it was very much predictable and can also use docker compose yml file alongside.

Here in this snippet of yaml file below, you can find a simple dynamodb docker container bound to `cloud` network and local volume `ddb-data` which has been already pre-created.

```yaml
version: "3.5"

services:
  dynamo:
    container_name: local-ddb
    image: amazon/dynamodb-local
    networks:
      - cloud
    ports:
      - "8000:8000"
    volumes:
      - ddb-data:/home/dynamodblocal
    working_dir: /home/dynamodblocal
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ."

networks:
  cloud:
    external: true

volumes:
  ddb-data:
    external: true 
```

### Create the docker network :sweat_drops:

Here let us define a docker network to be shared by our local cloud containers.

```sh
docker network create -d bridge cloud
```

### Create the docker volume :fish:

Here let us create a new docker volume and mount it to our local folder

```sh
docker volume create \
        --driver local \
        --opt type=none \
        --opt o=bind \
        --opt device=*******Your Local Volume folder*********** \
        ddb-data
```

### Start and Stop dynamodb local :seedling:

Navigate to the directory you have defined the docker compose file. Open the terminal and run the below command to start it.

```sh
docker-compose up -d
```

And to stop the container run the below command

```sh
docker-compose down

```

### Validate the ddb connection local :palm_tree:

Run the below command in the local terminal to make sure the port is correct as per your docker-compose you have defined above.

```sh
aws dynamodb list-tables --endpoint-url http://localhost:8000
```

You may get some results like the below.

```json
{
  "TableNames": [
    
  ]
}
```

### Create local table :ear_of_rice:

Before that if the table already exists you can delete it as shown below.

```sh
aws dynamodb delete-table --table-name eventStores9 --endpoint-url http://localhost:8000
```

Net us create the table by copying the schema from the cloud table by running the below describe-table command

```sh
aws dynamodb describe-table --table-name eventStores9 --profile av > eventStores9.json
```

Note in the above step, I have not used the endpoint but rather used my AWS named profile `av` to connect. In your case, you can have your own and write the output to the file `eventStores9.json`

Now run the below command using the file created above (note it is expected to throw error)

```sh
aws dynamodb create-table --cli-input-json file://eventStores9.json --endpoint-url http://localhost:8000
```

![ddb local table creation error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hve1y14hjga2trx96ayb.png)

When you get the above error, you simply have to remove those nodes from the JSON file you are using and the cleanup version of the file is already checkin to the local of this project to help you identify.

And then you can run the same command again, if it does not throw any error it should create the table and will give the description of the table as output.

```sh
aws dynamodb create-table --cli-input-json file://eventStores9.json --endpoint-url http://localhost:8000
```

### Validate by listing the tables locally :cherry_blossom:

```sh
aws dynamodb list-tables --endpoint-url http://localhost:8000
```

You may get some results like the below.

```json
{
  "TableNames": [
    "eventStores9"
  ]
}
```

And there you have it your local dynamodb table is ready to help you.

## NoSQL Workbench :dragon_face:

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html

You may also try this tool which can help you model dynamodb much faster and even push it to the cloud or local connection. However, this tool does not support LSI in the data modeling stage. Hope it is available soon. If it supports LSI, we would have directly imported the cloud formation template without parameters to create the schema in the tool itself. I tried it but is ignoring the LSI. So that is why I used the AWS CLI to generate the table.

Still, this tool can help us with the `Operation Builder` feature which will connect to the dynamodb tables directly and help with a range of other features and even help with some code snippets as well to design.

### Create a new database connection :goat:

![local connection setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09s3znev3y2gxwbjjlkh.png)

Inspect the metadata and LSI and GSI definitions

![local connected table metadata](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfh8y6488ix2x3u93auq.png)

With this interface, you can directly query, inspect and manipulate the local table data during testing and debugging.

Further, you can also use LSI and GSI in your operations seamlessly.

## Code changes to the function  :leaves:

Code changes to the function to enable local ddb connection. Just like how we identified AWS_SAM_LOCAL, we can do the same here as well in the `dynamodb-util.ts` file.

Take note of the name of the host it is the container name we defined in docker-compose yaml

```ts
if(process.env.AWS_SAM_LOCAL) {
  options.endpoint = 'http://local-ddb:8000'
}

const dynamo = AWSXRay.captureAWSClient(new DynamoDB(options));
```

## Run script changes :evergreen_tree:

Here we will readily know that sam CLI scripts are part of the run scripts as we demonstrated in the previous article. Here we need to include the docker network while using `sam local invoke` to be able to connect to used other

```json
{
  "sam:i": "sam local invoke $npm_config_fname --docker-network cloud -e $npm_config_event | jq .",
    "sam:i:debug": "sam local invoke $npm_config_fname --docker-network cloud -d 9999 -e $npm_config_event  --log-file logs/sam-debug-logs.txt --debug | jq .",
}
```

This should help to connect the function with local dynamodb as expected.

## Post testing events results in dynamodb :chestnut:

I have run all the test events I have prepared in the last article in `events` and I can see the results in the local table.

```sh
npm run t:1:1 -- --event=events/event_stack_create_complete.json
npm run t:1:1 -- --event=events/event_stack_delete_complete.json
npm run t:1:1 -- --event=events/event_stack_update_complete.json
npm run t:1:1 -- --event=events/event_resouce_create_complete.json
npm run t:1:1 -- --event=events/event_drift_detection_complete.json
```

Scan dynamodb items

![dynamodb items local](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bp6z46dxz5ep3h0mniz3.png)

Normal Query

![normal query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgml4b75svzjbyw78ui4.png)

Query using LSI_STATUS

![lsi status query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix0a6ctzw4nscy7b5y80.png)

## Debugging the data in vscode  :herb:

```sh
npm run d:1:func1 -- --event=events/event_stack_create_complete.json
```

![debugger started](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nnn5w7xpinz82zvnq57.png)


Verify that it is passing through the sam local script section when it is true and it resets the dynamodb endpoint.

![sam local verification and local ddb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4ddh43c1oxy6fi5u4bo.png)


With this approach, we will be able to monitor data moving in and out of the dynamodb table in local
![inspect data moving and out of ddb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqm1ry493ap9y6gt5o6e.png)

If you don't like to use js debugging when using typescript with webpack you can add the below to your launch config attach configuration `sourceMapPathOverrides` as discussed in the previous article.

```json
{
"sourceMapPathOverrides": {
    "meteor://💻ap{workspaceFolder}/*",
    "webpack:///./{workspaceFolder}/node_*",
    "webpack://?:{workspaceFolder}/*"
}
```

![source map overrides](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pj8hqbtvtsymx2jdhv1m.png)

Then directly you can place break points in the typescript files and you can cleanly debug them as follows.

Sample typescript debugging screenshots

![typescript debug 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u36gynuartbsv032bo68.png)

Sample typescript debugging screenshots with a specific point of interest

![typescript debug 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbmx3dyalacqvoh6qkzu.png)

## Conclusion :fountain:

This will be extremely useful when you repeatedly iterate and make code changes to the processor and you could use the test event to test it swiftly using local dynamodb setup and integration.

We will be talking about more similar engineering concepts as we refactor and refine the event forwarder project. Keep following for similar posts on engineering with IaC primarily using AWS CDK and Serverless.

Also, feel free to contribute to the progress of the below solution with your comments, and issues, maybe you can also do a pr if you feel it can help our community.

[event-forwarder Github repo](https://github.com/aravindvcyber/event-forwarder/)

![arch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msrbf94oefdrnu29a5db.jpeg)

🔁 Original project post at 🔗 [Dev Post aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder](https://devpost.hashnode.dev/aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder)

🔁 Reposted project post at 🔗 [dev to aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder-1m0m](https://dev.to/aws-builders/aws-cdk-101-projects-cdk-stackresourcedrift-events-forwarded-to-cool-slack-posts-event-forwarder-1m0m)

⏭ We have our next article in serverless and IaC, do check out

🎉 Thanks for supporting! 🙏

Would be great if you like to [☕ Buy Me a Coffee](https://www.buymeacoffee.com/AravindVCyber), to help boost my efforts 😍.

<a href="https://www.buymeacoffee.com/AravindVCyber"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=AravindVCyber&button_colour=BD5FFF&font_colour=ffffff&font_family=Cookie&outline_colour=000000&coffee_colour=FFDD00" /></a>

<a href='https://ko-fi.com/X8X0CITDJ' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi4.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>

🔁 Original post at 🔗 [Dev Post aws-cdk-101-dynamodb-local-setup-and-integrating-with-sam-invoke](https://devpost.hashnode.dev/aws-cdk-101-dynamodb-local-setup-and-integrating-with-sam-invoke)

🔁 Reposted at 🔗 [dev to @aravindvcyber aws-cdk-101-dynamodb-local-setup-and-integrating-with-sam-invoke-527f](https://dev.to/aws-builders/aws-cdk-101-dynamodb-local-setup-and-integrating-with-sam-invoke-527f)