Cloudformation refuses to set up an EventSourceMapping, but it works in the UI,
because under the hood the UI creates a push based setup, which can be re-created via
Cloudformation.
{ "Resources": { "SNSTopic": { "Type": "AWS::SNS::Topic", "Properties": { "Subscription": [ { "Endpoint": { "Fn::GetAtt": [ "Function", "Arn" ] }, "Protocol": "lambda" } ] } }, "Function": { "Type": "AWS::Lambda::Function", "Properties": { "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "LambdaExecutionRole", "Arn" ] }, "Code": { "ZipFile": { "Fn::Join": [ "", [ "exports.handler = function(event, context) {", "context.done(null,event)", "};" ] ] } }, "Runtime": "nodejs", "Timeout": "25" } }, "LambdaInvokePermission": { "Type": "AWS::Lambda::Permission", "Properties": { "FunctionName": { "Fn::GetAtt": [ "Function", "Arn" ] }, "Action": "lambda:InvokeFunction", "Principal": "sns.amazonaws.com", "SourceArn": { "Ref": "SNSTopic" } } } }, "LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Policies": [ { "PolicyName": "root", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:*" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "sns:Subscribe" ], "Resource": [ "*" ] } ] } } ] } } }