Modifying auto generated Serverless v1.0 AWS CloudFormation resources

SNS Events

By following the Serverless documentation on SNS events it should be pretty straight forward. Our “serverless.yml” should look something like this:

functions:
hello:
handler: handler.hello
events:
- sns: dispatch

Here we go…

Step 1: Trigger “serverless deploy -v” and expect everything to work as expected.

Step 2: Submit a test SNS event with the following AWS CLI command:

aws sns publish --topic-arn arn:aws:sns:us-east-1:YOUR_AWS_ACCOUNT_ID:dispatch --message '{ "message": "foo" }'
{
"MessageId": "0a38b298-96fd-11e6-ae22-56b6b6499611"
}

Step 3: Verify if our Lambda function was triggered with “sls logs -f hello”:

START RequestId: 172c30f6-96fd-11e6-ae22-56b6b6499611 Version: $LATEST
END RequestId: 172c30f6-96fd-11e6-ae22-56b6b6499611
REPORT RequestId: 172c30f6-96fd-11e6-ae22-56b6b6499611 Duration: 2.23 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 5 MB

Yup, it worked :)

It works, why are you still reading?

Well, there was something that caught my attention while I was inspecting my deployed resources through the AWS console.

Now this doesn’t look good :(
Whut, looks good to me….

What can we do about this?

After inspecting the resulting CloudFormation resources within the “.serverless” directory, they should look something like this:

...
"SNSTopicDispatch": {
"Type": "AWS::SNS::Topic",
"Properties": {
"TopicName": "dispatch",
"DisplayName": "",
"Subscription": [
{
"Endpoint": {
"Fn::GetAtt": [
"HelloLambdaFunction",
"Arn"
]
},
"Protocol": "lambda"
}
]
}
},
"HelloLambdaPermissionDispatch": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"HelloLambdaFunction",
"Arn"
]
},
"Action": "lambda:InvokeFunction",
"Principal": "sns.amazonaws.com"
}
}
...

Comparing this with the CloudFormation documentation on AWS::Lambda::Permission resource types, there seems to be an extra property called “SourceArn”.

This is optional; however, when granting Amazon S3 permission to invoke your function, you should specify this field with the Amazon Resource Name (ARN) as its value. This ensures that only events generated from the specified source can invoke the function.

Now let’s update our serverless.yml

functions:
hello:
handler: handler.hello
events:
- sns: dispatch
resources:
Resources:
HelloLambdaPermissionDispatch:
Type: AWS::Lambda::Permission
Properties:
FunctionName:
Fn::GetAtt:
- HelloLambdaFunction
- Arn
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn:
Ref: SNSTopicDispatch

Trigger an “sls deploy” and check what happened…

Better!

TBH I haven’t realy noticed any differences from before and after adding the new property(except for the AWS console looking happier), but I do hope this approach gave you some insights on how to “overwrite” auto generated CloudFormation resources by the Serverless Framework!

What’s next

If you want to read about more serverless tips, I’m planning to post them on Medium over the next couple of weeks.

Update

After visiting serverlessconf I realised only specifying the property within “Properties”, is enough :)

resources:
Resources:
HelloLambdaPermissionDispatch:
Properties:
SourceArn:
Ref: SNSTopicDispatch