Skip to content

How do I resolve authorization errors when CloudWatch alarms invoke Lambda functions?

4 minute read
0

I want to resolve the "CloudWatch Alarms isn't authorized to perform lambda:InvokeFunction" error that I receive on my AWS Lambda function resource.

Short description

When you configure an Amazon CloudWatch alarm to invoke a Lambda function, the alarm uses the lambda.alarms.cloudwatch.amazonaws.com service principal to perform the invocation. The Lambda function must have a resource-based policy that grants the service principal permission to invoke the function. Without this permission, the alarm fails and you receive the following authorization error message:

"CloudWatch Alarms is not authorized to perform: lambda:InvokeFunction on the resource because no resource-based policy allows the lambda:InvokeFunction action"

Resolution

Grant CloudWatch alarms permission to invoke your Lambda function

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.

To grant the required permission to the service principal, you can use the AWS CLI or Lambda console.

Note: If your CloudWatch alarm and Lambda function are in different AWS accounts, then you must also configure the appropriate AWS Identity and Access Management (IAM) permissions in the account where the alarm resides.

AWS CLI

Run the following add-permission command to add the resource-based policy:

aws lambda add-permission \--function-name YourFunctionName \--statement-id AllowCloudWatchAlarmInvoke \--action lambda:InvokeFunction \--principal lambda.alarms.cloudwatch.amazonaws.com \--source-arn arn:aws:cloudwatch:region:123456789012:alarm:MyAlarmName

Note: Replace YourFunctionName with your Lambda function name, source-arn with the Amazon Resource Name (ARN) of your CloudWatch alarm.

Lambda console

Complete the following steps:

  1. Open the Lambda console.
  2. In the navigation pane, choose Functions, and then select the Lambda function.
  3. Choose the Configuration tab, and then choose Permissions.
  4. In the Resource-based policy statements section, choose Add permissions.
  5. Configure the following permissions settings:
    For AWS Service, choose Other.
    For Service principal, enter lambda.alarms.cloudwatch.amazonaws.com.
    Note: Always use the lambda.alarms.cloudwatch.amazonaws.com service principal for CloudWatch alarms.
    For Source ARN, enter the ARN of your CloudWatch alarm such as, arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarmName.
    For Action, choose lambda:InvokeFunction.
    For Statement ID, enter a unique identifier such as, AllowCloudWatchAlarmInvoke.
  6. Choose Save.

Check the Condition element in the Lambda resource-based policy

To allow only a specified alarm to invoke the Lambda function, check that the Condition element in the resource-based policy includes only the alarm's name in the ARN.

Example resource-based policy:

{"Sid": "AllowCloudWatchAlarmInvoke","Effect": "Allow","Principal": {"Service": "lambda.alarms.cloudwatch.amazonaws.com"},"Action": "lambda:InvokeFunction","Resource": "arn:aws:lambda:us-east-1:123456789012:function:MyFunction","Condition": {"ArnLike": {"AWS:SourceArn": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarmName"}}}

To allow any or multiple alarms in the specified account and AWS Region to invoke the function, use a wildcard (*) in the AWS:SourceArn condition.

Example resource-based policy snippet that uses the wildcard (*):

"Condition": {"ArnLike": {"AWS:SourceArn": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:*"}}

There's a size limit for resource-based policies that you attach to a Lambda function. If you grant permissions to many alarms, then it's a best practice to use wildcards to reduce the number of permissions statements in the policy.

Important: If you remove the Condition element from the policy, then any CloudWatch alarm, not just alarms in your account, can invoke the function. Always include the Condition element to restrict alarms that can invoke the function.

Verify that the alarm invokes the Lambda function

After you add the resource-based policy, verify that the alarm successfully invokes the Lambda function.

To test the alarm before the alarm state changes to ALARM, run the following run the following set-alarm-state command to manually change the alarm state:

aws cloudwatch set-alarm-state \--alarm-name MyAlarmName \--state-value ALARM \--state-reason "Testing Lambda invocation"

Note: Replace MyAlarmName with the name of your CloudWatch alarm.

Then, check the invocation in the alarm history and the Lambda invocation metrics.

Review the alarm history

Complete the following steps:

  1. Open the CloudWatch console.
  2. In the navigation pane, choose Alarms, and then choose All alarms.
  3. Select your alarm.
  4. Choose the History tab.
  5. Check whether the history shows that the alarm initiated and no authorization errors appear.

Review the Lambda invocation metrics

Complete the following steps:

  1. Open the Lambda console.
  2. In the navigation pane, choose Functions and then select your function.
  3. Choose the Monitor tab.
  4. Review the Invocations metric to confirm that the function invoked.

Related information

Invoke a Lambda function from an alarm

Create a CloudWatch alarm based on a static threshold