我创建了一个 Amazon CloudWatch 警报,以便在警报的状态发生变化时发送 Amazon Simple Notification Service(Amazon SNS)主题的通知。但是,当 CloudWatch 警报状态发生变化时,我没有收到 SNS 通知。
解决方法
SNS 通知传输取决于 SNS 主题和 CloudWatch 警报的配置。要确定未收到 SNS 通知的原因,请查看 CloudWatch 警报的历史记录以查看触发操作的状态。
如果触发操作因 SNS 访问策略限制而失败,则 CloudWatch 警报历史记录将显示一条与以下内容类似的消息:
"Failed to execute action arn:aws:sns:us-east-1:ACCOUNT_ID:TOPIC_NAME.Received error: "Resource: arn:aws:cloudwatch:us-east-1:ACCOUNT_ID:alarm:ALARM_NAME is not authorized to perform: SNS:Publish on resource: arn:aws:sns:us-east-1:ACCOUNT_ID:TOPIC_NAME""
SNS 使用访问策略来限制可向主题发布消息的来源。如果出现权限错误,请在 SNS 访问策略的 Statement 部分下添加以下权限。该策略更新可向 CloudWatch 警报服务授予向 SNS 主题发布消息的权限:
{
"Sid": "Allow_Publish_Alarms",
"Effect": "Allow",
"Principal": {
"Service": [
"cloudwatch.amazonaws.com"
]
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:ACCOUNT_ID:TOPIC_NAME"
}
注意: 将 us-east-1 替换为通知所针对的 AWS 区域,将 ACCOUNT_ID 替换为您的账户 ID,将 TOPIC_NAME 替换为 SNS 主题名称。
要限制针对特定警报向主题发布消息的能力,请添加全局条件键。以下示例策略使用 ArnLike 条件运算符和 aws:SourceArn 全局条件键。有关更多信息,请参阅 Example cases for Amazon SNS access control。
{
"Sid": "Allow_Publish_Alarms",
"Effect": "Allow",
"Principal": {
"Service": [
"cloudwatch.amazonaws.com"
]
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:REGION:ACCOUNT_ID:TOPIC_NAME",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:cloudwatch:us-east-1:ACCOUNT_ID:alarm:ALARM_NAME"
}
}
}
注意: 将 us-east-1 替换为通知所针对的区域,将 ACCOUNT_ID 替换为您的账户 ID,将 TOPIC_NAME 替换为 SNS 主题名称,将 ALARM_NAME 替换为警报名称。
重要事项: 条件中包含的账户中的任何警报都可以发布到策略中资源的 SNS 主题。例如,警报资源所有者的账户 ID 可以发布到主题。对于 SNS 主题账户 ID 和拥有警报的账户 ID,将策略限制为同一个账户。
如果触发操作因 SNS 主题加密而失败,则 CloudWatch 警报历史记录将显示一条类似于以下内容的消息:
"Failed to execute action arn:aws:sns:us-east-1:ACCOUNT_ID:TOPIC_NAME.Received error: "null (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException;)""
SNS 允许对其主题进行静态加密。如果 SNS 使用默认 AWS Key Management Service(AWS KMS)alias/aws/sns 密钥进行加密,则 CloudWatch 警报无法发布到 SNS 主题。SNS 的默认 AWS KMS 密钥策略不允许 CloudWatch 警报执行 kms:Decrypt 和 kms:GenerateDataKey API 调用。由于 AWS 管理此密钥,因此您无法手动编辑该策略。
如果必须对 SNS 主题进行静态加密,请使用客户自主管理型密钥。客户自主管理型密钥必须在密钥策略 Statement 部分下包含以下权限。这些权限允许 CloudWatch 警报将消息发布到加密的 SNS 主题:
{
"Sid": "Allow_CloudWatch_for_CMK",
"Effect": "Allow",
"Principal": {
"Service": [
"cloudwatch.amazonaws.com"
]
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
如果触发操作成功,则 CloudWatch 警报历史记录将显示一条与以下内容类似的消息:
"Successfully executed action arn:aws:sns:us-east-1:ACCOUNT_ID:TOPIC_NAME"
上述消息表示 CloudWatch 警报已成功向 SNS 主题发布了一条消息。如果通知不是由 SNS 传送的,请检查 SNS 主题及其指标是否存在任何传输失败情况。有关详细信息,请参阅如何访问推送通知的 Amazon SNS 主题传输日志?
注意: CloudWatch 不会测试或验证您指定的操作。CloudWatch 也不会检测到当您尝试调用不存在的操作时导致的 Amazon EC2 Auto Scaling 或 Amazon SNS 错误。确保您的操作存在。
相关信息
使用 Amazon CloudWatch 告警
Encrypting messages published to Amazon SNS with AWS KMS