Trigger Lambda with S3 event - serverless.ts

Hello all,

I’m unable to make Cloud Formation stack work deploying a Lambda function triggered by a S3 event.

The S3 bucket already exists.

My current code:

Lambda handler.ts

export const uploadNotifications = {
    handler: `${__dirname
        .split(process.cwd())[1]
        .substring(1)
        .replace(/\\/g, '/')}/handler.uploadNotifications`,
    events: [{ s3: { bucket: 'ImagesS3Bucket', event: 's3:ObjectCreated:*', existing: true } }],
};

serverless.ts

......
......
resources: {
        Resources: {
            ImagesS3Bucket: {
                Type: 'AWS::S3::Bucket',
                Properties: {
                    BucketName: '${self:provider.environment.IMAGES_S3_BUCKET}',
                    CorsConfiguration: {
                        CorsRules: [
                            {
                                AllowedOrigins: ['*'],
                                AllowedHeaders: ['*'],
                                AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD'],
                                MaxAge: 3000,
                            },
                        ],
                    },
                },
            },
        },
    },
    functions: { uploadNotifications },
};

The function event definition is according to typing from @serverless/typescript.

{
   s3:
    | string
       | {
           bucket: string;
           event?: string;
           existing?: boolean;
           rules?: {
             prefix?: string;
             suffix?: string;
           }[];
         };
}

When I try to deploy the stack I receive the following error:

Serverless Error ---------------------------------------

  An error occurred: UploadNotificationsCustomS31 - Failed to create resource. The specified bucket does not exist See details in CloudWatch Log: 2021/03/12/[$LATEST]b7dfd24adba94cdc8ad4f91aefaabb5a.

I’ve already tried using these two other sintaxes to refer to the existing S3 bucket:

events: [{ s3: { bucket: 'Ref: ImagesS3Bucket', event: 's3:ObjectCreated:*', existing: true } 

and

events: [{ s3: { bucket: '!Ref ImagesS3Bucket', event: 's3:ObjectCreated:*', existing: true } 

Could you please help me?

Thank you very much.
BR,
Daniel.

Daniel, I’m in the exact same spot here trying to figure out how to reference a bucket I’m creating in serverless.ts from the S3 event declaration.

Indeed the handler tries to create a new bucket if I’m not declaring existing: true. The bucket logical id then becomes S3Bucket${PascalCase of bucket string value}. So it might be possible to name your resource as “S3BucketImagesS3Bucket” and the handler will find it. See below:

resources: {
        Resources: {
            S3BucketImagesS3Bucket: {
                Type: 'AWS::S3::Bucket',
                Properties: {
                    BucketName: '${self:provider.environment.IMAGES_S3_BUCKET}',
                    CorsConfiguration: {
                        CorsRules: [
                            {
                                AllowedOrigins: ['*'],
                                AllowedHeaders: ['*'],
                                AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD'],
                                MaxAge: 3000,
                            },
                        ],
                    },
                },
            },
        },
    },
    functions: { uploadNotifications },
};

Still this is more a hack than a solution. I’ll keep you posted if I find anything else.