Creating Lambda Functions in AWS CDK - Complete Guide

avatar
Borislav Hadzhiev

4 min

banner

# 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 - Complete Guide

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 iam from 'aws-cdk-lib/aws-iam'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as cdk from 'aws-cdk-lib'; 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_16_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, ), }, }); } }
If you still use CDK version 1, switch to the cdk-v1 branch in the GitHub repository.

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 to type array, it has to be converted to a JSON string - as 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 aws-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 run the deploy command:

shell
npx aws-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-lib/aws-iam'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as cdk from 'aws-cdk-lib'; 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 sample:

  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 run the deploy command:

shell
npx aws-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, issue the destroy command:

shell
npx aws-cdk destroy

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2023 Borislav Hadzhiev