

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon SNS 作为警报接收器
<a name="AMP-alertmanager-receiver-createtopic"></a>

您可以使用现有的 Amazon SNS 主题作为 Amazon Managed Service for Prometheus 的警报接收器，也可以创建一个新的主题。我们建议您使用**标准**类型的主题，这样您就可以将来自该主题的警报转发到电子邮件、短信或 HTTP。

要创建新的 Amazon SNS 主题作为警报管理器接收方，请按照[步骤 1：创建主题](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html#step-create-queue)中的步骤进行操作。主题类型请务必选择**标准**。

如果您希望每次向该 Amazon SNS 主题发送消息时都收到电子邮件，请按照[步骤 2：创建主题订阅](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html#step-send-message)中的步骤进行操作。

无论使用新的还是现有的 Amazon SNS 主题，您都需要 Amazon SNS 主题的 Amazon 资源名称（ARN）来完成以下任务。

**Topics**
+ [授予 Amazon Managed Service for Prometheus 向 Amazon SNS 主题发送警报消息的权限](AMP-alertmanager-receiver-AMPpermission.md)
+ [配置警报管理器以向 Amazon SNS 主题发送消息](AMP-alertmanager-receiver-config.md)
+ [将警报管理器配置为以 JSON 格式向 Amazon SNS 发送消息](AMP-alertmanager-receiver-JSON.md)
+ [将 Amazon SNS 配置为向其他目的地发送警报消息](AMP-alertmanager-SNS-otherdestinations.md)
+ [了解 Amazon SNS 消息验证规则](AMP-alertmanager-receiver-validation-truncation.md)

# 授予 Amazon Managed Service for Prometheus 向 Amazon SNS 主题发送警报消息的权限
<a name="AMP-alertmanager-receiver-AMPpermission"></a>

您必须授予 Amazon Managed Service for Prometheus 向您的 Amazon SNS 主题发送消息的权限。以下策略声明将授予该权限。其中包括一项 `Condition` 声明，以防止出现被称为“混淆代理”**问题的安全问题。该 `Condition` 声明限制了对 Amazon SNS 主题的访问权限，仅允许来自该特定账户和 Amazon Managed Service for Prometheus 工作区的操作。有关混淆代理人问题的更多信息，请参阅[防止跨服务混淆座席](#cross-service-confused-deputy-prevention)。

**授予 Amazon Managed Service for Prometheus 向您的 Amazon SNS 主题发送消息的权限**

1. [在 v3/home 上打开亚马逊 SNS 控制台。https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/v3/home)

1. 在导航窗格中，选择**主题**。

1. 选择您正用于 Amazon Managed Service for Prometheus 的主题的名称。

1. 选择**编辑**。

1. 选择**访问策略**，将以下策略声明添加到现有策略。

   ```
   {
       "Sid": "Allow_Publish_Alarms",
       "Effect": "Allow",
       "Principal": {
           "Service": "aps.amazonaws.com"
       },
       "Action": [
           "sns:Publish",
           "sns:GetTopicAttributes"
       ],
       "Condition": {
           "ArnEquals": {
               "aws:SourceArn": "workspace_ARN"
           },
           "StringEquals": {
               "AWS:SourceAccount": "account_id"
           }
       },
       "Resource": "arn:aws:sns:region:account_id:topic_name"
   }
   ```

   [可选] 如果您的 Amazon SNS 主题启用了服务端加密 (SSE)，则需要在用于加密主题的密 AWS KMS 钥策略中添加`kms:GenerateDataKey*`和`kms:Decrypt`权限，从而允许适用于 Prometheus 的亚马逊托管服务向该加密主题发送消息。

   例如，您可以在策略中添加以下内容：

   ```
   {
     "Statement": [{
       "Effect": "Allow",
       "Principal": {
         "Service": "aps.amazonaws.com"
       },
       "Action": [
         "kms:GenerateDataKey*",
         "kms:Decrypt"
       ],
       "Resource": "*"
     }]
   }
   ```

   有关更多信息，请参阅 [SNS 主题的AWS KMS 权限](https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html#sns-what-permissions-for-sse)。

1. 选择**保存更改**。

**注意**  
 默认情况下，Amazon SNS 会创建带有 `AWS:SourceOwner` 条件的访问策略。有关更多信息，请参阅 [SNS 访问策略](https://docs.aws.amazon.com/sns/latest/dg/sns-access-policy-use-cases.html#source-account-versus-source-owner)。

**注意**  
IAM 遵循[最严格的策略优先](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html)规则。在您的 SNS 主题中，如果存在比记录在案的 Amazon SNS 策略块更严格的策略数据块，则不会授予该主题策略的权限。要评估您的策略并了解已授予的权限，请参阅[策略评估逻辑](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html)。

## 选择加入区域的 SNS 主题配置
<a name="AMP-alertmanager-sns-regional-config"></a>

您可以使用配置`aps.amazonaws.com`与适用于 Prometheus 的亚马逊托管服务工作区 AWS 区域 相同的亚马逊 SNS 主题。要将来自 non-opt-in区域（例如 us-east-1）的 SNS 主题与可选区域（例如 af-south-1）一起使用，您需要使用区域服务主体格式。在区域服务原则中，*us-east-1*替换为您要使用的 non-opt-in区域：**aps.*us-east-1*.amazonaws.com**。

下表列出了选择加入区域及其相应的区域服务主体：


**选择加入区域及其区域服务主体**  

| 区域名称 | Region | 区域服务主体 | 
| --- | --- | --- | 
| 非洲（开普敦） | af-south-1 | af-south-1.aps.amazonaws.com | 
| 亚太地区（香港） | ap-east-1 | ap-east-1.aps.amazonaws.com | 
| 亚太地区（泰国） | ap-southeast-7 | ap-southeast-7.aps.amazonaws.com | 
| 欧洲地区（米兰） | eu-south-1 | eu-south-1.aps.amazonaws.com | 
| 欧洲（苏黎世） | eu-central-2 | eu-central-2.aps.amazonaws.com | 
| 中东（阿联酋）： | me-central-1 | me-central-1.aps.amazonaws.com | 
| 亚太地区（马来西亚） | ap-southeast-5 | ap-southeast-5.aps.amazonaws.com | 

有关启用选择加入区域的信息，请参阅 Amazon Web Services 一般参考中的《IAM 用户指南》**中的[管理 AWS 区域](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-regions.html)。

在为这些选择加入区域配置 Amazon SNS 主题时，请确保使用正确的区域服务主体来启用跨区域发送警报。

## 防止跨服务混淆座席
<a name="cross-service-confused-deputy-prevention"></a>

混淆代理问题是一个安全性问题，即不具有操作执行权限的实体可能会迫使具有更高权限的实体执行该操作。在中 AWS，跨服务模仿可能会导致混乱的副手问题。一个服务（*呼叫服务*）调用另一项服务（*所谓的服务*）时，可能会发生跨服务模拟。可以操纵调用服务，使用其权限以在其他情况下该服务不应有访问权限的方式对另一个客户的资源进行操作。为防止这种情况， AWS 提供可帮助您保护所有服务的数据的工具，而这些服务中的服务主体有权限访问账户中的资源。

我们建议在资源策略中使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 和 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件上下文键，以限制 Amazon Managed Service for Prometheus 为 Amazon SNS 提供的资源访问权限。如果使用两个全局条件上下文键，在同一策略语句中使用时，`aws:SourceAccount` 值和 `aws:SourceArn` 值中的账户必须使用相同的账户 ID。

`aws:SourceArn` 的值必须为 Amazon Managed Service for Prometheus 工作区的 ARN。

防范混淆代理问题最有效的方法是使用 `aws:SourceArn` 全局条件上下文键和资源的完整 ARN。如果不知道资源的完整 ARN，或者正在指定多个资源，请针对 ARN 未知部分使用带有通配符（`*`）的 `aws:SourceArn` 全局上下文条件键。例如 `arn:aws:servicename::123456789012:*`。

[授予 Amazon Managed Service for Prometheus 向 Amazon SNS 主题发送警报消息的权限](#AMP-alertmanager-receiver-AMPpermission) 中所示的策略演示了如何使用 Amazon Managed Service for Prometheus 中的 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键来防范混淆代理人问题。

# 配置警报管理器以向 Amazon SNS 主题发送消息
<a name="AMP-alertmanager-receiver-config"></a>

在您拥有（新的或现有的）**标准**类型的 Amazon SNS 主题后，您可以将其作为警报接收器添加到警报管理器配置中。警报管理器可将警报转发给已配置的警报接收器。要完成此操作，您必须知道 Amazon SNS 主题的 Amazon 资源名称（ARN）。

有关 Amazon SNS 接收方配置的更多信息，请参阅 Prometheus 配置文档中的 [<sns\$1configs>](https://prometheus.io/docs/alerting/latest/configuration/#sns_configs)。

**不支持的属性**

Amazon Managed Service for Prometheus 支持 Amazon SNS 作为警报接收方。但是，由于服务限制，并非支持 Amazon SNS 接收方的所有属性。Amazon Managed Service for Prometheus 警报管理器配置文件中不允许使用以下属性：
+ `api_url:` – Amazon Managed Service for Prometheus 会为您设置 `api_url`，因此不允许使用此属性。
+ `Http_config` – 此属性允许您设置外部代理。Amazon Managed Service for Prometheus 目前不支持此功能。

此外，还需要 SigV4 设置才能具有 Region 属性。如果没有 Region 属性，Amazon Managed Service for Prometheus 就没有足够的信息来提出授权请求。

**配置将您的 Amazon SNS 主题作为接收方的警报管理器**

1. 如果您使用的是现有的警报管理器配置文件，请在文本编辑器中打开该文件。

1. 如果 `receivers` 数据块中当前有 Amazon SNS 以外的接收方，请将其移除。您可以将多个 Amazon SNS 主题配置为接收方，方法是将它们放在 `receivers` 数据块内单独的 `sns_config` 数据块中。

1. 在 `receivers` 部分中添加以下 YAML 数据块。

   ```
   - name: name_of_receiver
     sns_configs:
       - sigv4:
           region: AWS 区域
         topic_arn: ARN_of_SNS_topic
         subject: yoursubject
         attributes:
           key: yourkey
           value: yourvalue
   ```

如果未指定 `subject`，则默认情况下，将使用带有标签名称和值的默认模板生成主题，这可能会导致值对于 SNS 来说太长。要更改应用于主题的模板，请参阅本指南中的 [将警报管理器配置为以 JSON 格式向 Amazon SNS 发送消息](AMP-alertmanager-receiver-JSON.md)。

现在，必须将警报管理器配置文件上传到 Amazon Managed Service for Prometheus。有关更多信息，请参阅 [将您的警报管理器配置文件上传到 Amazon Managed Service for Prometheus](AMP-alertmanager-upload.md)。

# 将警报管理器配置为以 JSON 格式向 Amazon SNS 发送消息
<a name="AMP-alertmanager-receiver-JSON"></a>

默认情况下，Amazon Managed Service for Prometheus 警报管理器以纯文本列表格式输出消息。这可能会增加其他服务的解析难度。您可以将警报管理器配置为以 JSON 格式发送警报。JSON 可以更轻松地在接收网络挂钩的终端节点中 AWS Lambda 或接收网络挂钩的终端节点中处理来自 Amazon SNS 的下游消息。您可以定义一个自定义模板来以 JSON 格式输出消息内容，这样可以更轻松地在下游函数中进行解析，而不必使用默认模板。

要以 JSON 格式将警报管理器中的消息输出到 Amazon SNS，请更新警报管理器配置，在 `template_files` 根部分中包含以下代码：

```
default_template: |
   {{ define "sns.default.message" }}{{ "{" }}"receiver": "{{ .Receiver }}","status": "{{ .Status }}","alerts": [{{ range $alertIndex, $alerts := .Alerts }}{{ if $alertIndex }}, {{ end }}{{ "{" }}"status": "{{ $alerts.Status }}"{{ if gt (len $alerts.Labels.SortedPairs) 0 -}},"labels": {{ "{" }}{{ range $index, $label := $alerts.Labels.SortedPairs }}{{ if $index }}, {{ end }}"{{ $label.Name }}": "{{ $label.Value }}"{{ end }}{{ "}" }}{{- end }}{{ if gt (len $alerts.Annotations.SortedPairs ) 0 -}},"annotations": {{ "{" }}{{ range $index, $annotations := $alerts.Annotations.SortedPairs }}{{ if $index }}, {{ end }}"{{ $annotations.Name }}": "{{ $annotations.Value }}"{{ end }}{{ "}" }}{{- end }},"startsAt": "{{ $alerts.StartsAt }}","endsAt": "{{ $alerts.EndsAt }}","generatorURL": "{{ $alerts.GeneratorURL }}","fingerprint": "{{ $alerts.Fingerprint }}"{{ "}" }}{{ end }}]{{ if gt (len .GroupLabels) 0 -}},"groupLabels": {{ "{" }}{{ range $index, $groupLabels := .GroupLabels.SortedPairs }}{{ if $index }}, {{ end }}"{{ $groupLabels.Name }}": "{{ $groupLabels.Value }}"{{ end }}{{ "}" }}{{- end }}{{ if gt (len .CommonLabels) 0 -}},"commonLabels": {{ "{" }}{{ range $index, $commonLabels := .CommonLabels.SortedPairs }}{{ if $index }}, {{ end }}"{{ $commonLabels.Name }}": "{{ $commonLabels.Value }}"{{ end }}{{ "}" }}{{- end }}{{ if gt (len .CommonAnnotations) 0 -}},"commonAnnotations": {{ "{" }}{{ range $index, $commonAnnotations := .CommonAnnotations.SortedPairs }}{{ if $index }}, {{ end }}"{{ $commonAnnotations.Name }}": "{{ $commonAnnotations.Value }}"{{ end }}{{ "}" }}{{- end }}{{ "}" }}{{ end }}
   {{ define "sns.default.subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}]{{ end }}
```

**注意**  
此模板根据字母数字数据创建 JSON。如果您的数据包含特殊字符，请在使用此模板之前对其进行编码。

为确保在传出通知中使用此模板，请在您的 `alertmanager_config` 数据块中引用该模板，如下所示：

```
alertmanager_config: |
  global:
  templates:
    - 'default_template'
```

**注意**  
此模板适用于整个消息正文，采用 JSON 格式。此模板会覆盖整个消息正文。如果您想使用此特定模板，则不能覆盖消息正文。任何手动完成的覆盖都将优先于模板。

有关以下内容的更多信息：
+ 警报管理器配置文件，请参阅 [在 Amazon Managed Service for Prometheus 中创建警报管理器配置以管理和路由警报](AMP-alertmanager-config.md)。
+ 上传您的配置文件，请参阅 [将您的警报管理器配置文件上传到 Amazon Managed Service for Prometheus](AMP-alertmanager-upload.md)。

# 将 Amazon SNS 配置为向其他目的地发送警报消息
<a name="AMP-alertmanager-SNS-otherdestinations"></a>

Amazon Managed Service for Prometheus 只能向 Amazon Simple Notiﬁcation Service（Amazon SNS）发送警报消息。要将这些消息发送到其他目的地，例如电子邮件、webhook、Slack 或 OpsGenie，您必须将 Amazon SNS 配置为将消息转发到这些终端节点。

以下各节将介绍如何配置 Amazon SNS 以将警报转发到其他目的地。

**Topics**
+ [电子邮件](#AMP-alertmanager-SNS-otherdestinations-email)
+ [Webhook](#AMP-alertmanager-SNS-otherdestinations-webhook)
+ [Slack](#AMP-alertmanager-SNS-otherdestinations-Slack)
+ [OpsGenie](#AMP-alertmanager-SNS-otherdestinations-OpsGenie)

## 电子邮件
<a name="AMP-alertmanager-SNS-otherdestinations-email"></a>

要将 Amazon SNS 主题配置为将消息输出到电子邮件，请创建订阅。在 Amazon SNS 控制台中，选择**订阅**选项卡以打开**订阅**列表页面。选择**创建订阅**，然后选择**电子邮件**。Amazon SNS 将向列出的电子邮件地址发送确认电子邮件。接受确认后，您就可以通过电子邮件接收来自您订阅主题的 Amazon SNS 通知。有关更多信息，请参阅[订阅 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html)。

## Webhook
<a name="AMP-alertmanager-SNS-otherdestinations-webhook"></a>

要将 Amazon SNS 主题配置为将消息输出到 Webhook 终端节点，请创建订阅。在 Amazon SNS 控制台中，选择**订阅**选项卡以打开**订阅**列表页面。选择**创建订阅**，然后选择 **HTTP/HTTPS**。创建订阅后，必须按照确认步骤将其激活。当订阅处于活动状态时，您的 HTTP 终端节点应该会收到 Amazon SNS 通知。有关更多信息，请参阅[订阅 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html)。有关使用 Slack Webhook 向各目标发布消息的更多信息，请参阅[如何使用 Webhook 将 Amazon SNS 消息发布到 Amazon Chime、Slack 或 Microsoft Teams？](https://aws.amazon.com/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/)

## Slack
<a name="AMP-alertmanager-SNS-otherdestinations-Slack"></a>

要将 Amazon SNS 主题配置为向 Slack 输出消息，您有两个选择。你可以与 Slack 的 email-to-channel集成集成，允许 Slack 接受电子邮件并将其转发到 Slack 频道，也可以使用 Lambda 函数将亚马逊 SNS 通知重写到 Slack。有关将电子邮件转发到 slack 频道的更多信息，请参阅[确认 Slack Webhook 的 AWS SNS 主题订阅](https://stackoverflow.com/questions/49341187/confirming-aws-sns-topic-subscription-for-slack-webhook)。有关构建 Lambda 函数以将 Amazon SNS 消息转换为 Slack 的更多信息，请参阅[如何将 Amazon Managed Service for Prometheus 与 Slack 集成](https://aws.amazon.com/blogs/mt/how-to-integrate-amazon-managed-service-for-prometheus-with-slack/)。

## OpsGenie
<a name="AMP-alertmanager-SNS-otherdestinations-OpsGenie"></a>

有关如何配置要向其输出消息的 Amazon SNS 主题的信息，请参阅[将 Opsgenie 与传入的亚马逊 SNS 集成](https://support.atlassian.com/opsgenie/docs/integrate-opsgenie-with-incoming-amazon-sns/)。 OpsGenie

# 了解 Amazon SNS 消息验证规则
<a name="AMP-alertmanager-receiver-validation-truncation"></a>

Amazon Simple Notification Service（Amazon SNS）要求消息符合特定标准。不符合这些标准的消息将在收到后予以修改。如有必要，Amazon SNS 接收器将根据以下规则验证、截断或修改警报消息：
+ 消息包含非 UTF 字符。
  + 消息将替换为 **Error - not a valid UTF-8 encoded string**。
  + 将添加一个消息属性，键为 **truncated**，值为 **true**。
  + 将添加一个消息属性，键为 **modified**，值为 **Message: Error - not a valid UTF-8 encoded string**。
+ 消息为空。
  + 消息将替换为 **Error - Message should not be empty**。
  + 将添加一个消息属性，键为 **modified**，值为 **Message: Error - Message should not be empty**。
+ 消息已被截断。
  + 消息将包含被截断的内容。
  + 将添加一个消息属性，键为 **truncated**，值为 **true**。
  + 将添加一个带有 “已修改” 键的消息属性，并且 “**消息：错误-消息” 的值已从 *X* KB 中截断，因为它超过 256 KB 的大小**限制。
+ 主题包含控制字符或非 ASCII 字符。
  + 如果主题包含控制字符或非 ASCII 字符，则 SNS 会将主题替换为 **Error - contains control- or non-ASCII characters**。
  + 对于 SNS 电子邮件主题，请移除控制字符，例如换行符：`\n`。
+ 主题不是 ASCII 字符。
  + 主题将替换为 **Error - contains non printable ASCII characters**。
  + 将添加一个消息属性，键为 **modified**，值为 **Subject: Error - contains non-printable ASCII characters**。
+ 主题已被截断。
  + 主题将包含被截断的内容。
  + **将添加一个带有 modified 键的消息属性，并且 “**主题：错误-主题” 的值已从*X*字符中截断，因为它超过了 100 个字符的大小**限制。**
+ 消息属性的键/值无效。
  + 无效的消息属性将被删除。
  + **将添加一个带有 modified 键的消息**属性，且由于无效 MessageAttributeKey 或，消息属性的值为MessageAttribute:Error-*X* 已被删除 MessageAttributeValue**。**
+ 消息属性已被截断。
  + 额外的消息属性将被删除。
  + **将添加一个带有 modified 键的**消息属性，并删除消息属性的值MessageAttribute：Error-*X*，因为它超过了 256KB 的大小**限制。**