Reputation: 986
Use Case : Refer to an existing bucket while creating a S3 event for the Lambda function in SAM YAML file
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM Template for sam-app
Globals:
Function:
Timeout: 900
MemorySize: 2048
Environment:
Variables:
TABLE_NAME: "111"
ENDPOINT_OVERRIDE: "222"
Resources:
SomePull:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/demo-1.0.0.jar
Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
Runtime: java8
Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
events:
bucket: codedeploytestxxx
event: s3:ObjectCreated:*
rules:
- prefix: uploads
- suffix: .jpg
existing: true
Reference : https://github.com/serverless/serverless/pull/6290
I tried couple of approaches , but still I am not able to refer to an existing bucket while creating an event , what configuration(s) I am missing from the above.
Error I get after executing the above script :
Invalid. property events not defined for resource of type AWS::Serverless::Function
Upvotes: 3
Views: 4608
Reputation: 4648
That pull request is from a third party Serverless Framework while you're using AWS Serverless Application Model (SAM)
Properties are case-sensitive:
AWS::Serverless::Function.Events
AWS::Serverless::Function S3 Event
Converting that section to AWS Serverless Application Model (SAM) syntax leads to:
Resources:
SomePull:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/demo-1.0.0.jar
Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
Runtime: java8
Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
Events:
Event1:
Type: S3
Properties:
Bucket: codedeploytestxxx
Events: s3:ObjectCreated:*
Filter:
S3Key:
Rules:
- Name: prefix
Value: uploads
- Name: suffix
Value: .jpg
[cfn-lint] E0001: Error transforming template: Resource with id [SomePull] is invalid. Event with id [Event1] is invalid. S3 events must reference an S3 bucket in the same template.
AWS Serverless Application Model (SAM) issue about referencing an existing S3 bucket
Upvotes: 6
Reputation: 4261
What worked for me was to remove the event from the lambda completely and then add a Notification Configuration in the S3 bucket, as well as a Lambda Permission.
So your lambda becomes:
SomePull:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/demo-1.0.0.jar
Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
Runtime: java8
Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
I imported the existing bucket into a separate stack and then updated that stack to contain the following:
BucketTopicPolicy:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: <my lambda function>
Principal: 's3.amazonaws.com'
DeletionPolicy: Delete
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: <my existing bucket>
NotificationConfiguration:
LambdaConfigurations:
- Event: 's3:ObjectCreated:*'
Function: <my lambda function>
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
It might very well be that you can import the existing bucket first and then add both the lambda and the lambda permission to the stack and simply update it. (Note that you cannot import existing resources to a stack if the stack contains also new resources)
Upvotes: 1