I am trying to use boto3 to programmatically subscribe my lambda function to a sns topic. When I execute my script, I see the integration in the AWS Lambda Console but publishing to the SNS topic does not invoke the function.
I then created the integration between the SNS topic and Lambda function directly in the AWS console itself. The AWS Console adds an Identifier field with the sns arn as the value. Now, publishing to the topic invokes the function.
In my script,I have added permissions(lambda_client.add_permission) using the values:,
{'Action': 'lambda:InvokeFunction',
'FunctionName':'my_lambda',
'Principal': 'sns.amazonaws.com',
'SourceArn': 'arn:aws:sns:us-east-1:redacted_acct_no:my-topic',
'StatementId': 'lambda-03a99f95-f490-4b9c-8bf8-20ee85fb2bff'}
I also do
sns_client.subscribe() and have successfully subscribed the lambda function to the topic
For testing purposes, I created two integrations, to two different topics and I called lambda_client.get_policy() and the policies are identical(of course, the StatementIds are different.
I have a similar setup for S3 which works.
Related
I have a question regarding the relationship between Lambda functions and Amazon SNS as a service.
In SNS you create subscriptions to a topic, one being a Lambda function. In my head I'd imagine this is to invoke and trigger the function when a message is sent out from that topic. But on the Lambda side you can create triggers to do that same thing, one of them being SNS.
What exactly is the difference, it kinda seems like they do the same thing. But if I create a subscription for a topic using a Lambda, it does not show up in the the triggers of the function in the Lambda services, which makes me wonder what exactly is the difference between these two?
What exactly is the difference?
There is no difference from the functional point of view. What you are observing are just console imperfections.
To make sure, I manually verified using my SNS and my lambda function.
When you use Create subscription in the SNS console, and add a lambda function, it does show up as a trigger in lambda console.
Similarly, if you use lambda console and add SNS trigger, you will find the function in the Subscriptions section of SNS console.
However, AWS console is not perfect. For example, if you remove the lambda function from Subscriptions, it will not remove it from triggers on lambda console. Instead you will see the following error:
For some this may be a bug, for others a feature. I learned not to rely heavily on what AWS console shows. Just double check if the subscription works or not.
I need to add 'SNS' based trigger to my Lambda function, But create-event-source-mapping — AWS CLI Command Reference says only DynamoDB, Kinesis, SQS.
The aws lambda create-event-source-mapping command for SNS, S3 etc based triggers fails with --event-source-arn:
An error occurred (InvalidParameterValueException) when calling the CreateEventSourceMapping operation: Unrecognized event source, must be kinesis, dynamodb stream or sqs. Unsupported source arn
However these can be accomplished through AWS console.
Any thoughts?
To have a SNS triggers a Lambda, the Lambda need to subscribe the SNS's topic. You can refer to Tutorial: Using AWS Lambda with Amazon Simple Notification Service on getting Lambda triggered when a message published to SNS's topic.
*the cdk construct lib links provided are in python but you can use a language or your choice
In order to set a sns trigger on Lambda you have do following things,
1) create a SNS Topic
2) create a Lambda function
3) create a Lambda event source
4) integrate all
You can use AWS CDK to do all this
Creating a SNS Topic:
https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_sns/Topic.html
Creating a Lambda Function
https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_lambda/Function.html
Use functuon_obj.add_ecent_source(SNS_obj) to integrate all.
The IAM permissions to invoke your function on sns event will automatically get handled and you see then under Lambda permissions tab on console.
Do mark the answer right if it helps.
I am trying to get lambda in another account to get it invoked by RDS instance event notifications.
RDS event subscription is set to invoke SNS topic which triggers lambda in other account.
I have setup an entire stack using cloudformation. Things I achieved so far are
RDS events are able to invoke SNS topic, I have tested it using creating email subscription to SNS topic
SNS topic is able to trigger lambda in another account. I have tested it using publish messages in SNS topic. I can see that is flowing through in cloudwatch logs.
Part I am not able to get working is, RDS events triggering SNS and then Lamba in other account. Its very strage as individual bits are working fine but not end to end. Other observation is status of the SNS subscription in RDS events is shown as Active and I can see subscription log in lambda but nothing happens after I reboot RDS instance to test.
Also, I see this bizzare behaviour that subscription status is set to Null.
I followed below links for reference
https://jimmythompson.co.uk/blog/sns-and-lambda/
https://medium.com/pablo-perez/infrastructure-as-a-code-should-not-be-imperative-43d9a64e3998
Is there something I am missing? Any help is much appreciated.
I have created lambda and SNS using cloudformation. Here first lambda is invoking a SNS which has a subscription of another lambda. Here SNS is supposed to invoke alias of lambda. In SNS topic lambda ARN is showing as subscriber but in lambda it is not added as trigger. There is not a single invocation log of the lambda invoked from SNS. So is this problem about some kind of permission or else ? need help...
Yes, this is a permissions issue. You need to add a permission to the lambda function to allow SNS to invoke it.
Use the AWS::Lambda::Permission resource to add permissions to allow SNS to invoke the lambda function.
I had a heck of a time with one. I had originally set my lambda function to look for an event source of "aws:s3". In order to get the event source from an s3 event, I used "event.Records[0].eventSource". When I tested event.Records[0].eventSource == "aws:sns" to check if my SNS trigger had fired, it wouldn't work. It wasn't until I found sample SNS event JSON that I noticed that SNS events have an event source node of "EventSource". It's capital case. I changed my test to
event.Records[0].EventSource == "aws:sns"
and it worked. So much for consistency in event message formats.
Is that possible if the user create a ticket in freshdesk that needs to be trigger the AWS lambda function.
That shouldn't be that hard. I would like to recommend using the following architecture
FreshDesk Ticket Trigger
FreshDesk Ticket Trigger Handler Published Message to SNS Topic
AWS Lambda Configured to SNS Topic as Event Source
AWS Lambda Code Accepts the SNS topic message (as Input) and performs the necessary processing
The advantages of using SNS rather directly calling Lambda are
Reducing the exposure of AWS API to only SNS topic and completely sealing rest of the API (IAM Privileges)
Possibility of Fan-Out Architecture [Multiple Lambda Functions can listen to the same SNS topic - near zero configuration]
For anyone landing on this topic.
It's possible with Freshdesk Marketplace app. With onTicketCreate product event, any actions can be written to execute with a Serverless function. It's completely run in Freshworks platform cloud.
If required, it can call your AWS Lambda.