DEV Community

Cover image for How to Trigger an AWS Lambda from S3
Alex Kates for AWS Community Builders

Posted on • Edited on • Originally published at alexkates.dev

How to Trigger an AWS Lambda from S3

In this post we are going to use the AWS CDK to build an AWS Lambda Function that triggers from AWS S3 Put requests.

All of the code can be found in this repository.

Setup

We need to run a few commands to setup our CDK app.

mkdir how-to-trigger-lambda-from-s3
cd how-to-trigger-lambda-from-s3
npx cdk init app --language typescript

Enter fullscreen mode Exit fullscreen mode

This should give you the following directory structure.
Directory structure after running the CDK init command

Also make sure you have your AWS CLI configured. For more information follow the AWS CLI quickstart guide.

Create an S3 Bucket

Install the S3 CDK package.

npm i @aws-cdk/aws-s3
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-s3-stack.ts, add a new S3 Bucket, and deploy.

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

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

    const bucket = new s3.Bucket(this, 'OurBucket', {
      /**
       * The following properties ensure the bucket is properly 
       * deleted when we run cdk destroy */
      autoDeleteObjects: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY
    })
  }
}

Enter fullscreen mode Exit fullscreen mode

npm run cdk deploy

You may need to confirm some IAM changes.
Confirm IAM changes when running cdk deploy

Create a Lambda

Install the Lambda CDK package.

npm i @aws-cdk/aws-lambda
Enter fullscreen mode Exit fullscreen mode

Deploying a Lambda function requires bootstrapping your CDK app which gives us an S3 bucket where our Lambda's source code will live. This is a one time operation.

npm run cdk bootstrap
Enter fullscreen mode Exit fullscreen mode

Create src/index.js and paste the following code

exports.handler = async (event) => {
  event.Records.forEach((record) => {
    console.log('Event Name: %s', record.eventName);
    console.log('S3 Request: %j', record.s3);
  });
};
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-s3-stack.ts, add a new Lambda function, and deploy.

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

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

    const bucket = new s3.Bucket(this, 'OurBucket', {
      /**
       * The following properties ensure the bucket is properly 
       * deleted when we run cdk destroy */
      autoDeleteObjects: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });

    const lambdaFunction = new lambda.Function(this, 'Function', {
      code: lambda.Code.fromAsset('src'),
      handler: 'index.handler',
      functionName: 'BucketPutHandler',
      runtime: lambda.Runtime.NODEJS_12_X,
    });
  }
}

Enter fullscreen mode Exit fullscreen mode

Deploy again ...

npm run cdk deploy
Enter fullscreen mode Exit fullscreen mode

You may need to confirm more IAM changes.
More IAM changes after deploying stack with Lambda function

Create the Event Source

Install the Lambda Event Sources CDK package.

npm i @aws-cdk/aws-lambda-event-sources
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-s3-stack.ts, add a new S3EventSource to the Lambda Function.

import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
import * as lambda from '@aws-cdk/aws-lambda';
import * as lambdaEventSources from '@aws-cdk/aws-lambda-event-sources';

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

    const bucket = new s3.Bucket(this, 'OurBucket', {
      /**
       * The following properties ensure the bucket is properly 
       * deleted when we run cdk destroy */
      autoDeleteObjects: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });

    const lambdaFunction = new lambda.Function(this, 'Function', {
      code: lambda.Code.fromAsset('src'),
      handler: 'index.handler',
      functionName: 'BucketPutHandler',
      runtime: lambda.Runtime.NODEJS_12_X,
    });

    const s3PutEventSource = new lambdaEventSources.S3EventSource(bucket, {
      events: [
        s3.EventType.OBJECT_CREATED_PUT
      ]
    });

    lambdaFunction.addEventSource(s3PutEventSource);
  }
}
Enter fullscreen mode Exit fullscreen mode

One more deployment ...

npm run cdk deploy
Enter fullscreen mode Exit fullscreen mode

One last time, you may need to approve IAM changes.

IAM changes approval after deploying the S3 event source

Testing

Create a text file that we will use to upload to the S3 bucket.

echo "This is a test" > testFile.txt
Enter fullscreen mode Exit fullscreen mode

Use the AWS CLI to upload this file into our S3 bucket from earlier. Your bucket name will vary, but for me this command looks like this.

aws s3 cp ./testFile.txt s3://howtotriggerlambdafroms3stack-ourbucket48caf57c-1p9g74rol1cza/testFile.txt
Enter fullscreen mode Exit fullscreen mode

Verify that the Lambda executed by looking in CloudWatch. Find the LogGroup named /aws/lambda/BucketPutHandler and open up the latest LogStream. You should see some log messages that look similar to this.

CloudWatch results after uploading an object to S3

Clean Up

Don't forget to delete your stack when you are finished!

npm run cdk destroy
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! If you found this useful, please follow me here
https://dev.to/thealexkates
https://twitter.com/thealexkates

Top comments (2)

Collapse
 
vijayalaxmi777 profile image
Vijayalaxmi Wakode

Helpful!

Collapse
 
uranthos profile image
uranthos

This is all good and all but I need it to run as a single rerunnable deployment script