Effortless Debugging: AWS CDK TypeScript Projects in VSCode
Ian
Posted on October 27, 2024
Debugging Lambda functions should be easy, right? You want to debug as you develop, using a standard editor (VSCode), a popular IaC framework (AWS CDK), and a widely adopted language (TypeScript).
But it is never quite that easy.
One of the main challenges to wider serverless adoption is the developer experience itself. Setting up an effective debugging environment for Lambda functions can be challenging, especially with the variety of tools, frameworks, and configurations available.
If you're using the same stack as I am, this guide will help you set up a smooth, flexible debugging environment so you can iterate through Lambda functions like a pro.
Introduction
The code for this article can be found here:
https://github.com/Crockwell-Solutions/cdk-lambda-debugger
The starter project provides a CDK configuration with an example resource stack (API Gateway -> Lambda -> SQS). The Lambda function is ready for debugging using both AWS SAM and Lambda Live Debugger. With this setup, you can iterate quickly through Lambda changes without any deployment delays.
Debugging Goals
When I built this, I wanted to simplify Lambda function debugging for a better developer experience. My main requirements were:
- Quick debugging (<5 seconds): Debugging has got to be quick. I don’t want to run cdk synth every time I debug: Within a large project with multiple stacks and functions, this takes too long.
- No deployment or hot-swap requirement: I want to debug without deploying each time.
- Support for ephemeral environment: Within a team, I need the setup to support multiple developer environments. I want it to work with SSO and I don't want to commit local environment variables.
- Local debugging with remote resources: I don't want to emulate resources locally, just the Lambda runtime.
This makes things a little trickier. There are plenty of options out there, but I really just needed a starter project with everything configured. I couldn't find one, so I've made one.
How it works
I want the most flexible developer experience, so the sample project uses two different debugging options.
- Run function locally, debug locally: Using AWS SAM
- Run function remotely, debug locally: Using Lambda Live Debugger
There is value in having both options available within a project as the SAM setup provides a bit more flexibility during early development for payloads and environment variables. Lambda Live Debugger provides a more representative runtime environment once you have your Lambda function is slightly more mature.
Getting Started
To get started with the sample project, clone the sample project and follow the installation instruction in the README.
After deployment, configure the required environment variables in a local.env.json file
. Here’s an example of what that file might look like:
{
"SQS_QUEUE_URL": "https://sqs.region.amazonaws.com/123456789012/LambdaDebuggerQueue"
}
This file isn’t committed to version control, so each developer can set their own local environment variables. The local.env.json
file is referenced from launch.json
in VSCode using the SAM CLI argument --container-env-vars
, which does then allow for committing and sharing of the launch.json
.
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "Lambda Function - SAM Debugger",
"preLaunchTask": "Build",
"invokeTarget": {
"target": "code",
"architecture": "arm64",
"projectRoot": "dist",
"lambdaHandler": "lambda-debugging-function.handler"
},
"aws": {
"region": "region"
},
"lambda": {
"runtime": "nodejs20.x",
"payload": {
"path": "${workspaceFolder}/test/test-payload.json"
}
},
"sam": {
"localArguments": [
"--container-env-vars",
"${workspaceFolder}/local.env.json"
]
}
}
The project includes a reusable CustomLambda
construct based on the CDK NodejsFunction
, bundling with ESBuild and including Lambda Powertools. This bundling is handled as a preLaunchTask in launch.json
, avoiding the need to perform a cdk synth
. This saves crucial seconds when initiating the debug run.
AWS SAM Debugging
This uses AWS SAM to invoke the Lambda function locally. Select Lambda Function - SAM Debugger
from the Run and Debug menu in VSCode and hit F5. You should see the logging output.
The debugger launch configuration triggers a build phase to bundle the code with ESBuild. Bundled code is saved to the dist
folder and run locally, removing the need to synth the CDK project. You can set breakpoints in src/lambda-debugging-function.ts
, and the debugger will respect source maps to link to the original code.
Lambda Live Debugging
Lambda Live Debugger is an alternative debugging option and offers the added benefit of validating permissions set up in CDK by running the Lambda functions remotely. This uses the Lambda Live Debugger project led by the industry hero Marko at Serverless Life.
- Deploy Lambda Live Debugger resources to your AWS account with
npx lld
. - Set any custom debugger options in
lldebugger.config.ts
. - In VSCode, select
Lambda Function - Lambda Live Debugger
from the Run and Debug menu, then press F5.
Lambda Live Debugger will work its magic and deploy out the required resources to your account. Now, to initiate the debug environment, you need to invoke the remote Lambda function. For example, you can add your breakpoint to your local code in src/lambda-debugging-function.ts
and then invoke the Lambda function through the API with a call such as:
curl --request POST --header "Content-Type: application/json" --data '{"message": "This is a test message"}' https://xxxxxxxx.execute-api.eu-west-1.amazonaws.com/api/data
In case of code changes, Lambda Live Debugger automatically reloads the updated code without the need to redeploy or restart the debugger. Magic!
When you’re done, remove the debugger resources with npx lld -r
.
Wrapping Up
This is still an evolving area, new tools and best practice changes all the time.
I initially used Serverless Framework (v3) for debugging, but with its deprecation and the new signup requirement in v4, I’ve moved to the setup in this article. Running Lambda functions locally always risks slight discrepancies with deployed environments (especially in terms of permissions), but this approach with AWS SAM and Lambda Live Debugger balances speed with reliability.
About Me
I’m Ian, an AWS Serverless Specialist and AWS Certified Cloud Architect based in the UK. I work as an independent consultant, having worked across multiple sectors, with a passion for Aviation.
Let's connect on linkedIn, or find out more about my work at Crockwell Solutions
Posted on October 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.