Debugging lambda functions with AWS CDK (using Webstorm)
Tags: devops, aws, cloud, serverless
Published: 2022-05-02 12:01:41


## PREREQUISITES
1. Install AWS CDK and AWS SAM (along with Docker)
2. Install Webstorm 
3. Install AWS Toolkit Webstorm plugin

---

## INTRODUCTION
Step-debugging lambda functions in AWS CDK applications can be quite tricky since the invocation of lambda functions behave of that of a docker container.

AWS SAM can be used to invoke/run your lambda functions locally with the following commands:

`$ sam local start api`
`$ sam local invoke `

Partnered by API clients (e.g Postman, Insomnia) and/or CLI tools to transfer data using various network protocols (e.g curl), local development can be quite robust with AWS CDK. 

However, step-debugging is not quite as seamless as locally invoking lambda functions with CDK. Through docker containers, **_the behavior of invoking local lambda functions mimics that of a lambda function deployed in the cloud_**. 

In the cloud, lambda functions are ephemeral where execution environments only exist for a brief time when the function is invoked. This behavior is exactly the same with that of local development through docker containers. When a lambda is locally invoked, Docker builds an image that of the lambda function and runs the container. After the runtime of the lambda function, the container then stops and gets deleted. Can you see the parallelism with deployed lambda functions in the cloud? **_Turns on when called and then goes back to sleep after execution_**.

When locally invoking a lambda function, **_an API call with the use of an API client will only call the container that has successfully been built_**. This is the reason why we cannot simply attach a debugger using our IDEs - a containerized application (in this case a lambda function) must be debugged inside the container as well. 

In order to debug the lambda function locally, **_we must attach a debugger as soon as we invoked the lambda function_**. 

---

## WALKTHROUGH
First we need to configure the AWS toolkit plugin by updating your AWS credentials.  You will be asked for your AWS ACCESS KEY ID and your AWS SECRET ACCESS KEY. After configuring your AWS credentials, go to Settings → Tools → AWS. Then select the drop down button of the AWS tab then select “Lambda”. Check the “Show gutter icons for all potential AWS Lambda handlers”.

![AWS Tookit Lambda option](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5nvulimxgqjgwx8h9a5.png)

Then go to your lambda function handler. You will now be able to see a lambda function logo in the gutter next to your handler.

![Lambda function logo in the gutter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irhpd0vuq2mklamski4g.png)
 
Click the lambda function logo and select “Modify Run Configuration”. 

![Modify run configuration (AWS Toolkit)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnu1c6daxlr49n8tfxie.png) 

Fill-out the necessary information about your lambda function. The input portion is asking for an event that invokes the lambda function. This mimics the actual invocation of a lambda function from the cloud. The event that I used in this example is an API Gateway AWS Proxy where it invokes a lambda function through an API call from AWS API Gateway service.

![events.json file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8wiktmwuu8pro738uowj.png) 
 
This is an example of an API Gateway AWS Proxy event. Looks daunting? Don’t worry! **_AWS Toolkit provides you templates to use for specific events_** located at the configuration settings of your lambda functions. 

![Event Templates](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e51ev5ssxk1vcavfrt7k.png) 

Click on the “-- Event Templates --” drop down and **_AWS Toolkit will provide you with ALL the events that invokes lambda functions in AWS_**. 

Moving forward, go to the SAM CLI tab and select “Build function inside a container”. This is the safest way to avoid NodeJS version errors. An example would be if you are using a different version of Node and the compatible runtimes of your lambda functions are different too. It’s best to containerize the debugging session to an isolated environment to avoid these types of errors. 

Apply all your changes and you are all set! **_To debug your lambda function, setup some breakpoints and click the lambda function logo and run “Debug”!_**

---

## PROBLEMS
The walkthrough above seems seamless and quite easy right? However, **_lambda functions invoked from the handler does not take into account lambda layers_**. You might ask why can’t we just select the “From template” option? But the thing is, **_with CDK, there is no template.yaml file_**. You might also suggest to convert the <stackName>.template.json file to a template.yaml with the command: 

`$ cdk synth --no-staging > template.yaml`

Yes, this converts the template.json file to a template.yaml however, the **_template.yaml produced is NOT the same as the template.yaml of AWS SAM_**. This then will lead to errors in compile time when AWS Toolkit runs:

`$ sam build`

We also don’t want to create another template.yaml file with the correct AWS SAM format. This will just only mimic your current IaC (Infrastructure as Code) with CDK which may lead you to confusion in the future since editing infrastructure will lead you to change both AWS CDK’s stacks and AWS SAM’s template.yaml file. A problem may arise where you deployed your infrastructure through the AWS SAM CLI instead using AWS CDK. **_Remember that SAM is a tool for CDK - not the other way around_**. Also, DRY!! - Don’t Repeat Yourself.

---

## WORKAROUND
My workaround is to create a package.json file with all the dependencies inside the lambda functions folder. I know what you’re thinking, aren’t I repeating myself? Yes, I am but this is only for local development and great developer experience for us to use step-debugging in lambda functions with AWS CDK. If we were using AWS SAM this maybe quite easier for us but CDK is quite more robust when it comes to infrastructure. I consider it as the “true” IaC since we can also test the infrastructure with testing libraries such as Jest.

![File structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82jgtrf8d9hzt0c78cgl.png) 

Install all the dependencies and don’t forget to put “node_modules”, “aws-toolkit-ts-output”, and “aws-toolkit-tsconfig.json” in the gitignore since these files were created when AWS Toolkit ran 

`$ sam build`

If you don’t want to use step-debugging, you can just simply invoke the API Gateway with the command 

`$ sam local start-api`

and call you’re API endpoints with an API Client such as Postman or Insomnia. 

**_As said above, after creating a package.json and install the needed dependencies, just setup some breakpoints in your lambda function and click the lambda function logo located at the gutter and run “Debug”!_**