Why isn't Amazon SNS invoking my Lambda function when triggered by a CloudWatch alarm?

Last updated: 2021-06-24

I want Amazon Simple Notification Service (Amazon SNS) to invoke my AWS Lambda function when triggered by an Amazon CloudWatch alarm.

Short description

The following scenarios prevent you from invoking your Lambda function:

  • Your Lambda function's resource policy hasn't granted access to invoke the function from the SNS topic. For this scenario, complete the steps in the Check the resource-based policy document for your Lambda function section.
  • Your Lambda function invocations are delayed. For this scenario, complete the steps in the Check your Amazon SNS delivery logs section.

Note: The following resolution assumes that you can call the Publish API on your SNS topic, but are getting errors between Amazon SNS and Lambda integration. If you can't see any activity on your SNS topic, see Why didn't I receive an SNS notification for my CloudWatch alarm trigger? That activity can include the following CloudWatch metrics: NumberOfMessagesPublished, NumberOfNotificationsDelivered, or NumberOfNotificationsFailed.

Resolution

Note: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, make sure that you’re using the most recent AWS CLI version.

Check the resource-based policy document for your Lambda function

When Amazon SNS invokes a Lambda function asynchronously, Lambda returns a 202 HTTP status code back to Amazon SNS. The status code shows that Lambda has accepted the message for later processing. For more information, see Asynchronous invocation. If you get a failed response, you can check your Amazon SNS delivery logs for more information.

Choose a resolution based on the scenario in your account.

If your SNS topic and Lambda function are in the same account:

1.    Open the Lambda console.

2.    On the navigation pane, choose Functions, and then choose your function.

3.    Choose the Configuration tab, and then choose Permissions.

4.    In the Resource-based policy section, choose the policy statement from the Statement ID column to view your policy document. You see the following policy document:

statement id
your-statement-id

principal:
sns.amazonaws.com

effect
allow

action
Lambda:InvokeFunction

conditions
{ "arnlike": { "aws:sourcearn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name" } 

Note: To see your policy document in JSON, choose View policy document in the Resource-based policy section.

If you're missing the Lambda resource policy that grants Amazon SNS access to invoke the function, add the following function to your policy document. You can use the Lambda console, or the AWS CLI or AWS CloudShell.

Using the command line:

aws lambda add-permission \
--function-name your-lambda-function-name \
--statement-id triggerfromsns-statement-id \
--action lambda:invokefunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name

Note: Replace your-lambda-function-name, your-aws-region, your-aws-account-id, and your-sns-topic-name with your values. The AWS CLI command uses the default AWS Region. You can override the default Region with the --region flag if your Lambda function is in a different Region.

Using the Lambda console:

1.    Open the Lambda console.

2.    On the navigation pane, choose Functions, and then choose your function.

3.    Choose the Configuration tab, and then choose Permissions.

4.    In the Resource-based policy section, choose Add permissions.

5.    For Principal, select sns.amazonaws.com.

6.    For Actions, select Lambda:InvokeFunction.

7.    For Statement ID, enter a unique ID.

8.    Choose Save.

If your SNS topic and Lambda function are in different accounts:

1.    Set up cross-account permissions.

2.    In your CloudWatch logs, use delivery status logging to verify that Amazon SNS has successfully sent a message to Lambda or the NumberOfNotificationsDelivered CloudWatch metric.

Example of a successful response between Amazon SNS and Lambda:

{
    "notification": {
        "messagemd5sum": "your-md5-sum",
        "messageid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "topicarn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic",
        "timestamp": "2021-04-04 14:08:48.083"
    },
    "delivery": {
        "deliveryid": "your-sns-delivery-id",
        "destination": "arn:aws:lambda:your-aws-region:your-aws-account-id:function:your-function-name",
        "providerresponse": "{\ "lambdarequestid\":\ "your-lambda-request-id\"}",
        "dwelltimems": 92,
        "attempts": 1,
        "statuscode": 202
    },
        "status": "success"
}

Check your Amazon SNS delivery logs

Check your SNS topic's delivery logs to your Lambda function. If the response is successful, you see a 202 status code.

To view CloudWatch logs for your SNS topic, do the following:

1.    Open the CloudWatch console.

2.    On the navigation pane, expand Logs, and then choose Log groups.

3.    In the filter search box, enter the name of your SNS topic. Two log groups for your SNS topic appear: one for successes and one for failures.

4.    Choose the success log group.

5.    In the Log streams section, choose Search all.

Note: You can also check the timestamp of the request in the Last event time column. Then, search for the Lambda function's Amazon Resource Name (ARN) and name.

6.    From the Log stream column, choose the log stream to open it.

If you don't see any results, do the following:

1.    Choose Log groups, and then choose the failure log groups.

2.    In the Log streams section, choose Search all.

3.    From the Log stream column, choose the log stream to open it.

To troubleshoot failed log groups, do the following:

1.    Check if your Lambda function's X-Ray trace has a high dwell time. If there's a high dwell time, use the CloudWatch console to verify that your Lambda functions in that Region have the fewest number of errors and throttles. Be sure to select all functions, and then select the Errors and Throttles metrics.

Note: Hundreds of errors and throttles across functions that are invoked asynchronously can back up the internal Lambda queue, resulting in delays in function invocations. It's a best practice to keep the error and throttle rate to minimum, so you can avoid unwanted delays for function invocations. For more information, see Asynchronous invocation.

2.    Set a destination Amazon Simple Queue Service (Amazon SQS) queue or Lambda function for separate handling. This prevents message loss and is done because the maximum age of the asynchronous events can be six hours for a Lambda function.


Did this article help?


Do you need billing or technical support?