Photo by NASA / Unsplash

The AWS CDK is a tool that makes it easy to create your infrastructure through the code. Before, we were using CloudFromation or the AWS console to create our infrastructure. Using these paths have some drawbacks like:

  • The CloudFormation is hard to read and navigate
  • There is no way to use computed or dynamics expressions
  • When using the console, you don't have the history of our changes on the infrastructure.
  • It is impossible to share the configuration since there is no way to update the changes applied.

The CDK solves these issues in an elegant way: the ability to describe your infrastructure as a code using your favorite programming language. Currently, at the time I'm writing this, it supports TypeScript, JavaScript, Python, Java, C#/.Net, and (in developer preview) Go. The source can be versioned in Git so that we can keep the history of changes applied.

In this tutorial, we will see how to create a Lambda function with the CDK and deploy it in production.

Prerequisites

To achieve this, here are some elements required:

  • An AWS account
  • AWS CLI configured (check out this link to see how to do it)
  • Node.js 12+

Install the CDK globally

We need to install the Node package to use the CDK commands through the CLI to create and manage our infrastructure. Run the command:

npm install -g cdk

Check if the installation succeeded by running: cdk --version

Create the project with CDK

Now, create a folder that will hold the source code of our project.

mkdir node-app-cdk
cd node-app-cdk

Initialize the project with the CDK by running the command below:

cdk init sample-app --language typescript

The command will generate many files and install the necessary dependencies. Below is the project structure:

Project structure of Node.js app created by the CDK

This is a classic minimal Node.js project with Typescript but, there are some files to focus on:

  • lib/lambda-node-cdk-stack.ts is where your CDK application’s main stack is defined. This is the file we’ll be spending most of our time in.
  • bin/lambda-node-cdk.ts Is the entry point of the CDK application. It will load the stack defined in lib/lambda-node-cdk-stack.ts.
  • test/lambda-node-cdk.test.ts is where we write tests for our stack defined in lib/lambda-node-cdk-stack.
  • cdk.json Tells the toolkit on how to run your app. In our case, it will be npx ts-node bin/lambda-node-cdk.ts.

We will focus on the lib/lambda-node-cdk.ts file to create our Lambda function.

Create the Lambda function

The current code creates an SQS queue, creates an SNS topic, and finally subscribes to the topic. Delete the whole code in the file to make it looks like this:

import * as cdk from '@aws-cdk/core';

export class LambdaNodeCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

  }
}

Let's install the CDK node modules for AWS Lambda.  

npm i @aws-cdk/aws-lambda

Update the file to create our Lambda function with the necessary properties:

import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';

export class LambdaNodeCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new lambda.Function(this, 'LambdaNodeStack', {
      code: lambda.Code.fromAsset('./src'),
      functionName: "lambdaNode",
      handler: 'index.handler',
      memorySize: 1024,
      runtime: lambda.Runtime.NODEJS_14_X,
      timeout: cdk.Duration.seconds(300),
    });
  }
}

Let's explain what we did here:

We create a Lambda function called lambdaNode Running on Node.js 14 with 1GB of memory allocated.  The timeout is set to 300 seconds which is equal to 5 minutes. The property code indicates the folder's path to find the code to run when the Lambda is triggered. It is located in the src folder at the project root but, it doesn't exist yet,, so let's create it with mkdir src.
The handler property indicates the entry file then the function to run inside this file. So the index.handler can be broken down to:

  • index: the file called index.js inside the src directory.
  • handler: the function inside the index.js to executes.

Inside the src folder, create a file called index.js and add the content below:

exports.handler = async function(event) {
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/json" },
    body: JSON.stringify({ message: "Hello from my Lambda node!" })
  };
};

Deploy the Lambda function

The first step to deploy the Lambda is to generate the CloudFormation template from the CDK code. The command to do that is:

cdk synth

This command will output the CloudFormation stack to be created in the console.

The next step is to bootstrap an environment. This action is required only if it is the first time you want to deploy with the CDK; you can skip this if you have already done it before.

This command will create a stack that includes resources used for the toolkit’s operation, like an S3 bucket to store templates and assets during the deployment process.

cdk bootstrap

⏳  Bootstrapping environment aws://123456789012/eu-west-1...

Once done, we can deploy our app:

cdk deploy

You will have the output below; press the touch y to continue...

Summary of the stack to be created

Wait for the process to complete, then go to the AWS console to test your lambda function.

View the Lambda functions in the AWS console

We see our lambda function; click on it to go to the function page.

Page with the details of the Lambda function

Click on the "test" button to configure the payload of the request. A modal will popup

Create a sample of payload to be sent when invoking the Lambda

Once the payload is configured, click on the test button again.

The execution of the Lambda was completed successfully.

Yess 🎉. You have successfully deployed a Lambda function with the CDK.

Test the lambda function locally

We tested our function in production, but how do we test this Lambda locally before deploying it in production in the classic software development lifecycle. To do it with the CDK, we will use the AWS SAM CLI.

Note: CDK integration with the AWS SAM CLI is currently in public preview. During public preview, it may be subject to backward-incompatible changes.

We will first install the SAM CLI; check out this link to see the installation process for your operating system. For MacOS users, run the command below:

brew tap aws/tap
brew install aws-sam-cli-beta-cdk
sam-beta-cdk --version

SAM CLI, version 1.29.0.dev202108311500

If you want to upgrade the SAM CDK CLI, run. brew upgrade aws-sam-cli-beta-cdk.

To run your Lambda, run this command:

sam-beta-cdk local invoke LambdaNodeCdkStack/LambdaNode

We got the output below:

Test the Lambda function locally with the sam-beta-cdk

You can now test your function locally!

Find the lambda name to pass to SAM CDK CLI

If we see the command used to run our lambda:

sam-beta-cdk local invoke LambdaNodeCdkStack/LambdaNode

We may wonder how do we get the LambdaNodeCdkStack/LambdaNode part?

  • LambdaNodeCdkStack: it is the name of the stack and comes from the file bin/lambda-node-cdk.ts.
  • LambdaNode: it is the name of the Lambda Stack  and comes from the file lib/lambda-node-cdk-stack.ts.

Find the final code source on the GitHub Repository.

Follow me on Twitter or subscribe to my newsletter to not miss the upcoming posts and the tips and tricks I share every week.

Happy to see you soon 😉