Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add S3 trigger event on AWS Lambda function using Serverless framework?

I want to add trigger event on a Lambda function on an already existing bucket and for that I am using below configuration:

 events:
      - s3:
          bucket: serverlesstest
          event: s3:ObjectCreated:*
          rules:
            - prefix: uploads/
            - suffix: .pdf

where bucket serverlesstest is already existing on S3.

This configurations is throwing the error:

An error occurred while provisioning your stack: S3BucketServerlesstest - serverlesstest already exists.

How can I resolve this error using Serverless Framework?

like image 406
Ronit kadwane Avatar asked Jun 29 '17 06:06

Ronit kadwane


4 Answers

This is possible as of serverless version v1.47.0, by adding the existing: true flag to your event configuration: https://serverless.com/framework/docs/providers/aws/events/s3/

example from the source:

functions:
  users:
    handler: users.handler
    events:
      - s3:
          bucket: legacy-photos
          event: s3:ObjectCreated:*
          rules:
            - prefix: uploads/
            - suffix: .jpg
          existing: true # <- this makes it work with existing objects

The source provides the following caveats:

IMPORTANT: You can only attach 1 existing S3 bucket per function.

NOTE: Using the existing config will add an additional Lambda function and IAM Role to your stack. The Lambda function backs-up the Custom S3 Resource which is used to support existing S3 buckets.

like image 143
Ulad Kasach Avatar answered Jan 02 '23 01:01

Ulad Kasach


It’s not currently possible in the core framework because of CloudFormation behavior. maybe.

But you can use this plugin.

https://github.com/matt-filion/serverless-external-s3-event

After installing serverless-plugin-existing-s3 by npm install serverless-plugin-existing-s3.

And add plugins to serverless.yml

plugins:
  serverless-plugin-existing-s3

Give your deploy permission to access the bucket.

provider:
  name: aws
  runtime: nodejs4.3
  iamRoleStatements:
    ...
    -  Effect: "Allow"
       Action:
         - "s3:PutBucketNotification"
       Resource:
         Fn::Join:
           - ""
       - - "arn:aws:s3:::BUCKET_NAME or *"

And use existingS3 event, it is not just s3.

functions:
  someFunction:
    handler: index.handler
    events:
      - existingS3:
          bucket: BUCKET_NAME
          events:
            - s3:ObjectCreated:*
          rules:
            - prefix: images/
            - suffix: .jpg

After sls deploy command, You can attach event by using sls s3deploy command.

Feature Proposal

it will be added someday in the future.

https://github.com/serverless/serverless/issues/4241

like image 40
yabaiwebyasan Avatar answered Jan 02 '23 02:01

yabaiwebyasan


Unfortunately, you can't specify an existing S3 bucket to trigger the Lambda function because the Serverless Framework* can't change existing infrastructure using Cloud Formation. This configuration requires that you create a new bucket.

You can read more in the following issues that were open on GitHub:

  • Can't subscribe to events of existing S3 bucket
  • s3 events can't refer to existing bucket

* I would try to configure this trigger using AWS Console or the SDK instead of the Serverelss Framework.

like image 31
Zanon Avatar answered Jan 02 '23 01:01

Zanon


serverless.yml seems to be very sensitive to spaces. For me this advice was helpful.

If config looks like this

functions:
  hello:
    handler: handler.main
    events:
      - s3: 
        bucket: codepipeline-us-east-1-213458767560
        event: s3:ObjectCreated:*
        rules:
          - prefix: test/MyAppBuild

you need to add 2 more spaces to the indent of bucket, event & rules:

functions:
  hello:
    handler: handler.main
    events:
      - s3: 
          bucket: codepipeline-us-east-1-213458767560
          event: s3:ObjectCreated:*
          rules:
            - prefix: test/MyAppBuild
like image 34
Yevhenii Avatar answered Jan 02 '23 02:01

Yevhenii