In this comprehensive guide, we’ll explore three distinct approaches to creating AWS Lambda functions within AWS Cloud Development Kit (CDK) constructs, leveraging TypeScript for a seamless development experience. AWS CDK simplifies the process of defining cloud infrastructure as code, providing a higher-level abstraction over AWS CloudFormation templates.

Introduction to AWS CDK

The AWS Cloud Development Kit (CDK) is an open-source software development framework that enables developers to define cloud infrastructure using familiar programming languages like TypeScript. With AWS CDK, you can provision and manage AWS resources easily, allowing for efficient infrastructure as code (IaC) development.

Introduction to AWS Lambda Functions

AWS Lambda is a serverless compute service that allows you to run code without managing servers. It automatically scales and manages compute resources, enabling you to focus solely on your code’s functionality. Lambda functions can be triggered by various AWS services, responding to events such as S3 bucket changes, DynamoDB updates, or HTTP requests via Amazon API Gateway.

Now, let’s delve into three different ways of creating Lambda functions within AWS CDK constructs using TypeScript.

Inline Code

import { Stack, StackProps } from “aws-cdk-lib”;
import * as lambda from “aws-cdk-lib/aws-lambda”;
import { Construct } from “constructs”;export class CdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);const lambdaFunction = new lambda.Function(this, “LambdaHandler”, {
code: lambda.Code.fromInline(`
exports.handler = async (event) => {
console.log(‘request:’, JSON.stringify(event, undefined, 2));

return {
statusCode: 200,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({ message: ‘Hello world’ }),
};
};
`),
handler: “index.handler”,
runtime: lambda.Runtime.NODEJS_18_X,
});
}
}

This method utilizes inline code, leveraging the Function construct from the @aws-cdk/aws-lambda package. The runtime code is embedded as a string using the lambda.Code.fromInline method. Keep in mind that this approach is limited to supported runtimes.

Specify a Separate File

Create a file called style=”background:#ccc; border-radius:10px; padding:5px 20px;”>index.ts in the style=” border-radius:10px;background:#ccc; padding:5px 20px;”>lambda directory with the following code:

import { Stack, StackProps } from “aws-cdk-lib”;
// File: lambda/index.tsexports.handler = async (event) => {
console.log(“request:”, JSON.stringify(event, undefined, 2));

return {
statusCode: 200,
body: JSON.stringify({ message: “Hello world” }),
};
};

Now, modify the AWS CDK Stack to use this external file:

import { Stack, StackProps } from “aws-cdk-lib”;
import { Stack, StackProps } from “aws-cdk-lib”;
import * as lambda from “aws-cdk-lib/aws-lambda”;
import { Construct } from “constructs”;export class CdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);

const lambdaFunction = new lambda.Function(this, “LambdaHandler”, {
runtime: lambda.Runtime.NODEJS_18_X,
code: lambda.Code.fromAsset(“lambda”),
handler: “index.handler”,
});
}
};

In this approach, the runtime code is moved to a separate file (index.ts) in the local filesystem, and the path for the directory of the file is given to the fromAsset method of the lambda.Code class. The handler property now has the value of the filename and function name (index.handler).

NodejsFunction

import { Stack, StackProps } from “aws-cdk-lib”;
import { Stack, StackProps } from “aws-cdk-lib”;
import { Construct } from “constructs”;
import * as lambda from “aws-cdk-lib/aws-lambda”;
import * as nodeJS from “aws-cdk-lib/aws-lambda-nodejs”;export class CdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);

const lambdaFunction = new nodeJS.NodejsFunction(this, “LambdaHandler”, {
entry: “/path/to/my/file.ts”,
handler: “handler”,
runtime: lambda.Runtime.NODEJS_18_X,
});
}
}

In this approach, the NodejsFunction construct from aws-cdk-lib/aws-lambda-nodejs is used. This construct creates a Lambda function with automatic transpiling and bundling of TypeScript or JavaScript code, resulting in smaller Lambda packages that contain only the code and dependencies needed to run the function. It uses esbuild under the hood.

The entry property specifies the entry point for the TypeScript file containing your Lambda function code. Make sure to replace ‘/path/to/my/file.ts’ with the actual path to your TypeScript file. The handler property sets the entry point for the Lambda function, and the runtime property specifies the Node.js version as 18.x.

Conclusion

  • Inline code is a quick and easy way to write a Lambda function but has a limited runtime and lacks IDE support during code writing.
  • Separating the file keeps the CDK stack code and Lambda function code separated and supports IDE. However, external dependencies, except the AWS SDK, are not supported.
  • The third approach, using NodejsFunction, results in smaller Lambda packages but requires another build step and increases the size of the CDK construct.