Lambda Function Example in AWS CDK - Complete Guide

avatar

Borislav Hadzhiev

Sat May 01 20214 min read

banner

Photo by Thomas Somme

Table of Contents #

  1. Creating Lambda Functions in AWS CDK
  2. Adding Permissions to a Lambda Function in AWS CDK

Creating Lambda Functions in AWS CDK #

In order to create a Lambda function in CDK, we have to instantiate the Function class.

If you want your Lambda code in TypeScript - check out my other article Write TypeScript Lambda functions in AWS CDK - Complete Guide.
The code for this article is available on GitHub

Let's create and configure a simple lambda function in CDK:

lib/cdk-starter-stack.ts
import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as path from 'path'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ๐Ÿ‘‡ lambda function definition const lambdaFunction = new lambda.Function(this, 'lambda-function', { runtime: lambda.Runtime.NODEJS_14_X, memorySize: 1024, timeout: cdk.Duration.seconds(5), handler: 'index.main', code: lambda.Code.fromAsset(path.join(__dirname, '/../src/my-lambda')), environment: { REGION: cdk.Stack.of(this).region, AVAILABILITY_ZONES: JSON.stringify( cdk.Stack.of(this).availabilityZones, ), }, }); } }

Let's go over the code snippet.

  1. We created a lambda function by instantiating the Function class.
  2. The configuration props we passed to the function are:
  • runtime - the runtime environment (programming language and version) of the lambda function
  • memorySize - the amount of memory,in MB, we want to allocate to the function. The default is 128 MB.
  • timeout - the time our function has to run, before it is terminated. The default timeout is 3 seconds.
  • handler - the format is fileName.functionName, in our case the file, storing the lambda function is named index.js and the handler function is named main.
  • code - the source code of the lambda function. The static fromAsset method on the Code class takes a path to a directory on the local file system, where our lambda handler code is located. This directory eventually gets zipped and uploaded to an S3 bucket before a deployment.
  • environment - a map of environment variables. Note that the values must be of type string, so if you're passing an environment variable ot type array, it has to be converted to a json string - like we've done with the array of availability zones.

Let's add the code for the lambda function at src/my-lambda/index.js:

src/my-lambda/index.ts
async function main(event) { console.log('region ๐Ÿ‘‰', process.env.REGION); console.log('availability zones ๐Ÿ‘‰', process.env.AVAILABILITY_ZONES); return { body: JSON.stringify({message: 'SUCCESS ๐ŸŽ‰'}), statusCode: 200, }; } module.exports = {main};

All our lambda does is print the environment variables we've set and return a success message.

Let's synth the cdk stack:

shell
npx cdk synth

In preparation for deployment, the assets and CloudFormation templates get generated in the cdk.out directory. If we take a look at the cdk.out directory we can see that our lambda has been extracted and is ready to get zipped and uploaded to an s3 bucket:

lambda cdk out

The name of the folder, that stores the lambda code, includes a hash and that's how CDK knows when we've updated the code of our lambda function.

Let's execute a deployment:

shell
npx cdk deploy

After we've deployed, we can test the function in the Lambda management console:

lambda function tested

Adding Permissions to a Lambda Function in AWS CDK #

CDK automatically creates an IAM role for our lambda functions.

If we look at the permissions policy attached to the auto-generated lambda role we can see that it adds simple CloudWatch logging permissions:

lambda default permissions

The easiest way to add permissions to a Lambda function in CDK is to attach policies to the auto-generated role of the function.

The code for this article is available on GitHub

Let's grant our lambda function a permission to list all of the S3 buckets in the account:

lib/cdk-starter-stack.ts
import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as path from 'path'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ... rest // ๐Ÿ‘‡ create a policy statement const listBucketsPolicy = new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:ListAllMyBuckets'], resources: ['arn:aws:s3:::*'], }); // ๐Ÿ‘‡ attach the policy to the function's role lambdaFunction.role?.attachInlinePolicy( new iam.Policy(this, 'list-buckets', { statements: [listBucketsPolicy], }), ); } }

Let's go over what we did in the code snippet.

  1. we created a policy statement, that grants the s3:ListAllMyBuckets action on all s3 resources. Note that the default for the effect prop is ALLOW, so we could have omitted the prop altogether.
  2. we attached the policy to the role of the lambda function

Let's execute a deployment:

shell
npx cdk deploy

By going to the IAM management console and inspecting the role of the lambda function, we can see that it now has 2 permission policies attached, including the one that grants the s3:ListAllMyBuckets action:

updated lambda permissions

Clean up #

To delete the resources we have provisioned, execute the destroy command:

shell
npx cdk destroy

Further Reading #

Add me on LinkedIn

I'm a Web Developer with TypeScript, React.js, Node.js and AWS experience.

Let's connect on LinkedIn

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee