Debugging AWS Lambda functions in Node JS using VS Code

The SLAppForge Debugger NodeJS is a toolkit that can be utilized to perform step-through debugging for the Lambda functions executing on live AWS environment, using your own local IDE.

This toolkit contains 3 components as below.

  1. Lambda Proxy
  2. Local Client
  3. Broker Server

 

Getting Started

Getting Started

The SLAppForge Debugger for NodeJS consists of two end-user visible components. The first is an AWS Lambda Layer which contains the slappforge-lambda-debug-proxy Node module. The second is a user agent, which executes on the local machine where the favorite IDE runs. The Lambda function connects with the IDE through the SLAppForge Debug Server, and both communication ends are secured with basic auth based authentication to ensure that only authorized developers can debug a function.

Any large enterprises such as financial services or Government organizations that are extremely security-sensitive can deploy their own Debug Server within a VPC or internal network. This default implementation of the debug server can be further secured with SSL encryption, IP based access filtering and any other forms of additional security.

Prerequisites

As a prerequisite for using the SLAppForge Debugger for NodeJS, you should have a SLAppForge Access Key and a Secret. This key and the secret is used for authenticating the Lambda connection as well as the IDE connection to the SLAppForge Debug Server.

To create your access keys, visit https://www.slappforge.com/java-debug and login with your SLAppForge account credentials. If you do not already have an account with SLAppForge, you will be directed to the registration page.

When you click the GENERATE KEY button, you will be presented with a set of credentials for live debugging as follows, and you can re-generate a new secret again at any time.

If you are new to the Sigma IDE – be aware that now you can always use the SLAppForge credentials to login to it. The Sigma IDE is the first browser based IDE custom built for developing Serverless applications with NodeJS and Python, for both Amazon Web Services (AWS) and the Google Cloud Platform (GCP). It supports drag-and-drop code generation, about 3 second updates for function re-deployment – which really saves time during iterative development, and also supports live debugging of Lambda functions on AWS. Read more about the Sigma IDE, or watch the quick introduction video.

Implement the Lambda code

To get things started, let’s implement a simple NodeJS Lambda function as below. This function will read a name from the name field of the event and then respond back with a greeting to that name with ‘Hello’. Also to get the debug functionality, we have to require the slappforge-lambda-debug-proxy NPM library at the very end of this file.

exports.handler = async (event) => {

    debugger;
    console.log('Event', event);
    let name = event['name'];

    return `Hello ${name}`;
};
require('slappforge-lambda-debug-proxy');

We can either install this slappforge-lambda-debug-proxy module as a dependency of our Lambda project itself, or configure the Lambda to use SLAppForge’s pre-built Lambda layer that contains this module.

We are going to use the latter approach here, as it prevents this module from getting included in our deployment bundle.

In addition, make sure to add a debugger; line as the first executable line of your lambda handler, so the VS Code debugger will suspend at that line until we add our custom breakpoints.

Create the Lambda Function

Let’s first create a NodeJS based Lambda function via the AWS console. Then bundle our code into a zip file and upload it to the Lambda as its content. (Since we only have a single JS file here, we can, of course, copy the content of it and paste it into the Lambda code editor. But let’s do it the proper way, shall we?)

Then we have to add SLAppForge Lambda Debug Layer to our Lambda function. The layer ARN is as below.

arn:aws:lambda:us-east-1:892904900711:layer:slappforge-debug-nodejs-1-0-0-build-01:1

Configuring the SLAppForge Debug Layer

 

Next, let’s create a test event and invoke it to see if our Lambda works correctly. We can see that the execution completes in a few milliseconds and we get a successful response.

Lambda execution without debugging enabled

Configure Debug Parameters in Lambda

Now we have to configure some parameters that are required to enable debugging for this Lambda function. First, let’s add the following 4 environment variables to the Lambda function.

Environment VariableDescription
SLAPP_DEBUGGER_ACTIVEThis is the flag that indicates whether the Lambda should be invoked in debug mode or not. Setting this to true will enable debugging.
SLAPP_KEYThis is the Access Key obtained earlier from the SLAppForge Access Key Manager
SLAPP_SECRETThis is the Access Secret obtained earlier from the SLAppForge Access Key Manager
SLAPP_SESSIONThis is a unique ID to distinguish this Lambda function for the debugger to connect. This can be any string value. (Make sure to use the same value when the Local Client is configured later)

Secondly, we have to increase the timeout of the Lambda function to allow enough time for the debugging before the Lambda runs out of time. While at present we can increase the timeout for up to 15 minutes, generally we don’t need a debug session as long as that. Hence, somewhere between 2 to 5 minutes should be generally adequate for most scenarios.

Finally, let’s save the changes and move on to the next step.

Install and run Local Client

Since we have completed the Lambda side configurations, let’s move into the configurations to be done on our developer machine. So as the first step, we need to install the SLAppForge Local Debug Client in our machine. This is a NodeJS command-line tool, which is responsible for connecting our IDE to the SLAppForge Debug Server.

This Local Client is available in the NPM repository and we can install it as a global NPM module executing the below command.

npm i slappforge-debug-client -g

Once installed we can run it from our command line or terminal as follows providing the required parameters.

slp-debug-client -k=fca8c359-7df9-4b16-8a69-949bfadfd8e9 -x=1iyOP3fgCf3ARMRgZ3Wen0JdpqmQ98Xt -f=MySampleLambdaDebug
ParameterDescription
-kThis is the Access Key obtained earlier from the SLAppForge Access Key Manager
-xThis is the Access Secret obtained earlier from the SLAppForge Access Key Manager
-fThis is a unique ID to distinguish this Lambda function for the debugger to connect. This can be any string value. (Make sure to use the same value configured for the SLAPP_SESSION environment variable of the Lambda function)
Running the Local Client

Please note that it is possible to use the same Local Client session for multiple debugging sessions for the same Lambda function. Therefore we can start this once and keep it running.

Add a Debug Configuration in the IDE

The next step is to create a Debug Configuration in the VS Code.

  • While in the workspace containing our Lambda project, click on the Run and Debug button on the left tool panel.
  • Then open the Run and Debug drop down on the top left, and choose to Add Config for the Lambda project.
  • VS Code will automatically create a file called launch.json with a default configuration. Remove that configuration first.
  • Then click on the Add Configuration… button on the bottom right, and select NodeJS: Attach to Remote Program as the configuration type.
  • When the configuration is added to the launch.json file, change its parameters as below.
    • name – Provide any name for the run configuration
    • address – Set the address as localhost or 127.0.0.1 (Should be specified as a string value)
    • port – Set the port as 9249 (Should be specified as a numeric value)
    • remoteRoot – Set the remote root value /var/task. This is the location of our code at the Lambda instance.
  • Once the parameters are configured, save the launch.json file and return back to the Lambda file (index.js).
VS Code Debug Configuration

Running Debug Session

Now we have completed all the configurations and ready to run our debug session.

As the first step, we have to invoke our Lambda function. We can do it either using a test event from the AWS console or if you have set any triggers such as an API Gateway, S3 event, one of those also can be used.

 

Executing Lambda with debugging enabled

 

Now we can see that our Lambda function does not complete its processing within a few milliseconds as we saw earlier. Instead, it connects to the Debug Server and waits for an IDE debugger to be connected.

If we do not connect an IDE, Lambda function will wait until the configured timeout passes without completing.

Once we have invoked our Lambda function in debug mode, then we can start our VS Code debugger.

 

VS Code debugger in action

 

After successfully connected, we can fully utilize the debug functionality of the IDE similar to when we remote debug a typical NodeJS function. Once we completed the debugging, the Lambda function will complete its execution as well.

 

Lambda completes after the debugging

Avoiding Surprises

Here are a few tips to ensure you have a great debugging experience while you debug your Lambda functions live on AWS as they execute.

  • To quickly disable debugging, set the environment variable SLP_DEBUGGER_ACTIVE to false. This allows you to let the function run without waiting for the debugger to attach. Without this being set, be aware that the function will not execute but timeout – if your debugger does not connect.
  • Make sure the following settings are appropriate for your debugging session
    • Adequate memory allocated for the function – depending on your function and its dependencies
    • Timeout – adequate for a debugging session, but not too much to avoid having to wait too long for a function to timeout, incase the debugger does not connect, or you run into any other issue
    • Concurrency – If you can set this to one, this is recommended

Node JS logo

SLAppForge Debugger for Node.js

SLAppForge Debugger for NodeJS is a toolkit that can be utilized to perform step-through debugging for the Lambda functions executing on live AWS environment, using your own local IDE.

Learn More