PREREQUISITES
- Install AWS CDK and AWS SAM (along with Docker)
- Install Webstorm
- 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”.
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.
Click the lambda function logo and select “Modify Run Configuration”.
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.
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.
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 .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.
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”!
Top comments (0)