Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allowing CloudWatch Alarm to send to SNS in other account

I have a SNS topic in account "A", which is a trigger of a Lambda function in that same account. This Lambda function sends a message to a private Slack channel.

This works fine, as long as the CloudWatch alarm is in the same account (Account A).

But I also want to do this from "Account B", but there I get:

{
  "error": "Resource: arn:aws:cloudwatch:REGION:ACCOUNT_B:alarm:ALARM is not authorized to perform: SNS:Publish on resource: arn:aws:sns:REGION:ACCOUNT_A:TOPIC",
  "actionState": "Failed",
  "notificationResource": "arn:aws:sns:REGION:ACCOUNT_A:TOPIC",
  "stateUpdateTimestamp": 1495732611020,
  "publishedMessage": null
}

So how do I allow the CloudWatch Alarm ARN access to publish to the topic?

Trying to add the policy fails with:

Invalid parameter: Policy Error: PrincipalNotFound (Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter; Request ID: 7f5c202e-4784-5386-8dc5-718f5cc55725)

I see that someone else have/had the same problem (years ago!) at https://forums.aws.amazon.com/thread.jspa?threadID=143607, but it was never answered.

Update:

Trying to solve this, I'm now trying to use a local SNS topic, which then sends this to the remove account. However, I'm still getting:

"error": "Resource: arn:aws:cloudwatch:REGION:LOCAL_ACCOUNT:alarm:ALARM is not authorized to perform: SNS:Publish on resource: arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC"

This, with this SNS policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowLambdaAccountToSubscribe",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::REMOTE_ACCOUNT:root"
      },
      "Action": [
        "sns:Subscribe",
        "sns:Receive"
      ],
      "Resource": "arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC"
    },
    {
      "Sid": "AllowLocalAccountToPublish",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "LOCAL_ACCOUNT"
        }
      }
    }
  ]
}

If I manually send a message to the topic with the Publish to topic, I can see that it reaches the Lambda function, so everything except the CloudWatch access rights.

like image 228
Fransurbo Avatar asked May 25 '17 17:05

Fransurbo


People also ask

How do I send an email from my CloudWatch alarm?

Amazon CloudWatch uses Amazon SNS to send email. First, create and subscribe to an SNS topic. When you create a CloudWatch alarm, you can add this SNS topic to send an email notification when the alarm changes state. For more information, see the Amazon Simple Notification Service Getting Started Guide.

Why didn't ti receive SNS notification for my CloudWatch alarm trigger?

To determine why you're not receiving SNS notifications, check the history of the CloudWatch alarm to find the status of the trigger action. SNS restricts the sources that can publish messages to the topic using access policies.

Can CloudWatch send notifications?

You can configure CloudWatch Logs to send a notification whenever an alarm is triggered for CloudTrail. Doing so enables you to respond quickly to critical operational events captured in CloudTrail events and detected by CloudWatch Logs. CloudWatch uses Amazon Simple Notification Service (SNS) to send email.

How do I enable CloudWatch on SNS?

To enable and view CloudWatch Logs for your SMS messagesSign in to the Amazon SNS console . In the console menu, set the region selector to a region that supports SMS messaging. On the navigation panel, choose Text messaging (SMS).

Which Amazon service can you use to send immediate email alerts based on CloudWatch alarms?

Using Amazon CloudWatch alarms, you can set up metric thresholds and send alerts to Amazon Simple Notification Service (SNS). SNS can send notifications using e-mail, HTTP(S) endpoints, and Short Message Service (SMS) messages to mobile phones, and it can even trigger a Lambda function.


1 Answers

By means of trial-and-error, I discovered it was the Condition that didn't work. For some reason. Not sure why it didn't see the source account...

A more extensive policy made it work:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowLambdaAccountToSubscribe",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::REMOTE_ACCOUNT:root"
      },
      "Action": [
        "sns:Subscribe",
        "sns:Receive"
      ],
      "Resource": "arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC"
    },
    {
      "Sid": "AllowLocalAccountToPublish",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "LOCAL_ACCOUNT"
        }
      }
    },
    {
      "Sid": "AllowCloudWatchAlarmsToPublish",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:REGION:LOCAL_ACCOUNT:TOPIC",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:cloudwatch:REGION:LOCAL_ACCOUNT:alarm:*"
        }
      }
    }
  ]
}
like image 179
Fransurbo Avatar answered Sep 27 '22 21:09

Fransurbo