

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

# 使用 Terraform 创建和管理警报资源
<a name="v9-alerting-setup-provision-terraform"></a>

****  
本文档主题专为支持 **Grafana 9.x 版本**的 Grafana 工作区而设计。  
对于支持 Grafana 10.x 版本的 Grafana 工作区，请参阅[使用 Grafana 版本 10](using-grafana-v10.md)。  
对于支持 Grafana 8.x 版本的 Grafana 工作区，请参阅[使用 Grafana 版本 8](using-grafana-v8.md)。

使用 Terraform 的 Grafana 提供程序管理警报资源并将其配置到 Grafana 系统。Terraform 提供程序对 Grafana Alerting 的支持使创建、管理和维护整个 Grafana Alerting 堆栈即代码变得更容易。

有关使用 Terraform 管理警报资源的更多信息，请参阅 Terraform 文档中的 [Grafana 提供程序](https://registry.terraform.io/providers/grafana/grafana/latest/docs)文档。

完成以下任务，使用 Terraform 创建和管理警报资源。

1. 创建 API 密钥以进行预置。

1. 配置 Terraform 提供程序。

1. 在 Terraform 中定义警报资源。

1. 运行 `terraform apply` 以预置警报资源。

## 先决条件
<a name="v9-alerting-setup-provision-tf-prerequisites"></a>
+ 确保你有 grafana/grafana [Terraform 提供商 1.27.0](https://registry.terraform.io/providers/grafana/grafana/1.28.0) 或更高版本。
+ 确保您使用的是 Grafana 9.1 或更高版本。如果您使用 Grafana 9 版本创建了 Amazon Managed Grafana 实例，则这种情况是正确的。

## 创建 API 密钥以进行预置
<a name="v9-alerting-setup-provision-tf-apikey"></a>

您可以[创建普通的 Grafana API 密钥](Using-Grafana-APIs.md)，使用 Grafana 对 Terraform 进行身份验证。大多数使用 API 密钥的现有工具都应自动支持新的 Grafana Alerting。有关创建用于 Terraform 的密钥的具体信息，请参阅[使用 Terraform 实现 Amazon Managed Grafana 自动化](https://aws-observability.github.io/observability-best-practices/recipes/recipes/amg-automation-tf/)。

**创建 API 密钥以进行预置**

1. 为 CI 管道创建一个新的服务账户。

1. 分配角色“访问警报规则 Provisioning API”。

1. 创建新的服务账户令牌。

1. 命名并保存令牌以在 Terraform 中使用。

或者，您可以使用基本身份验证。要查看所有支持的身份验证格式，请参阅 Terraform 文档中的 [Grafana 身份验证](https://registry.terraform.io/providers/grafana/grafana/latest/docs#authentication)。

## 配置 Terraform 提供程序
<a name="v9-alerting-setup-provision-tf-configure"></a>

Grafana Alerting 支持包含在 [Grafana Terraform 提供程序](https://registry.terraform.io/providers/grafana/grafana/latest/docs)中。

下面是一个可用于配置 Terraform 提供程序的示例。

```
terraform {
    required_providers {
        grafana = {
            source = "grafana/grafana"
            version = ">= 1.28.2"
        }
    }
}

provider "grafana" {
    url = <YOUR_GRAFANA_URL>
    auth = <YOUR_GRAFANA_API_KEY>
}
```

## 预置联系点和模板
<a name="v9-alerting-setup-provision-tf-contacts"></a>

联系点将警报堆栈与外部连接起来。这些联系点通知 Grafana 如何连接到外部系统，以及向何处发送通知。有超过 15 种不同的[集成](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/contact_point#optional)可供选择。此示例使用了 Slack 联系点。

**预置联系点和模板**

1. 将此代码块复制到本地计算机上的 .tf 文件中。*<slack-webhook-url>*替换为你的 Slack webhook 网址（或其他联系人）

   此示例创建一个联系点，用于向 Slack 发送警报通知。

   ```
   resource "grafana_contact_point" "my_slack_contact_point" {
       name = "Send to My Slack Channel"
   
       slack {
           url = <slack-webhook-url>
           text = <<EOT
   {{ len .Alerts.Firing }} alerts are firing!
   
   Alert summaries:
   {{ range .Alerts.Firing }}
   {{ template "Alert Instance Template" . }}
   {{ end }}
   EOT
       }
   }
   ```

1. 在文本字段中输入通知文本。

   `text` 字段支持 [Go 样式的模板](https://pkg.go.dev/text/template)。这让您可以直接在 Terraform 中管理 Grafana Alerting 通知模板。

1. 运行 `terraform apply` 命令。

1. 转到 Grafana UI，查看联系点的详细信息。

   您无法从 UI 编辑通过 Terraform 预置的资源。这样可确保警报堆栈始终与代码保持同步。

1. 单击**测试**以验证联系点是否正常工作。

**注意**  
您可以在多个联系点重复使用相同的模板。在上面的示例中，使用语句 `{{ template "Alert Instance Template" . }}` 嵌入了共享模板。  
然后，可以在 Terraform 中单独管理此片段：  

```
resource "grafana_message_template" "my_alert_template" {
    name = "Alert Instance Template"

    template = <<EOT
{{ define "Alert Instance Template" }}
Firing: {{ .Labels.alertname }}
Silence: {{ .SilenceURL }}
{{ end }}
EOT
}
```

## 预置通知策略和路由
<a name="v9-alerting-setup-provision-tf-notifications"></a>

通知策略会通知 Grafana 如何路由警报实例，而不是路由到何处。这些策略使用标签和匹配器系统将触发警报连接到您之前定义的联系点。

**预置通知策略和路由**

1. 将此代码块复制到本地计算机上的 .tf 文件中。

   在此示例中，警报按 `alertname` 分组，这意味着来自同名警报的所有通知都将分组到同一条 Slack 消息中。

   如果要以不同的方式路由特定通知，可以添加子策略。子策略允许您根据标签匹配将路由应用于不同的警报。在此示例中，我们对标签为 a=b 的所有警报应用了静音定时。

   ```
   resource "grafana_notification_policy" "my_policy" {
       group_by = ["alertname"]
       contact_point = grafana_contact_point.my_slack_contact_point.name
   
       group_wait = "45s"
       group_interval = "6m"
       repeat_interval = "3h"
   
       policy {
           matcher {
               label = "a"
               match = "="
               value = "b"
           }
           group_by = ["..."]
           contact_point = grafana_contact_point.a_different_contact_point.name
           mute_timings = [grafana_mute_timing.my_mute_timing.name]
   
           policy {
               matcher {
                   label = "sublabel"
                   match = "="
                   value = "subvalue"
               }
               contact_point = grafana_contact_point.a_third_contact_point.name
               group_by = ["..."]
           }
       }
   }
   ```

1. 在 mute\$1timings 字段中，将静音定时与您的通知策略关联。

1. 运行 `terraform apply` 命令。

1. 转到 Grafana UI，查看通知策略的详细信息。
**注意**  
您无法从 UI 编辑通过 Terraform 预置的资源。这样可确保警报堆栈始终与代码保持同步。

1. 单击**测试**以验证通知点是否正常工作。

## 预置静音定时
<a name="v9-alerting-setup-provision-tf-mutetiming"></a>

静音定时允许在定义的时间段内将警报通知静音。

**预置静音定时**

1. 将此代码块复制到本地计算机上的 .tf 文件中。

   在此示例中，警报通知在周末处于静音状态。

   ```
   resource "grafana_mute_timing" "my_mute_timing" {
       name = "My Mute Timing"
   
       intervals {
           times {
             start = "04:56"
             end = "14:17"
           }
           weekdays = ["saturday", "sunday", "tuesday:thursday"]
           months = ["january:march", "12"]
           years = ["2025:2027"]
       }
   }
   ```

1. 运行 `terraform apply` 命令。

1. 转到 Grafana UI，查看静音定时的详细信息。

1. 使用 `mute_timings` 字段在通知策略中引用新创建的静音定时。这会将静音定时应用于部分或全部通知。
**注意**  
您无法从 UI 编辑通过 Terraform 预置的资源。这样可确保警报堆栈始终与代码保持同步。

1. 单击**测试**以验证静音定时是否正常工作。

## 预置警报规则
<a name="v9-alerting-setup-provision-tf-rules"></a>

[警报规则](v9-alerting-managerules.md)让您可以针对任何 Grafana 数据来源发出警报。这可以是您预置的数据来源，也可以在 Terraform 中与警报规则一起[定义数据来源](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source)。

**预置警报规则**

1. 创建要查询的数据来源和要存储规则的文件夹。

   在此示例中，使用 [配置用于测试 TestData 的数据源](testdata-data-source.md) 数据来源。

   您可以针对 Grafana 中的任何后端数据源定义警报。

   ```
   resource "grafana_data_source" "testdata_datasource" {
       name = "TestData"
       type = "testdata"
   }
   
   resource "grafana_folder" "rule_folder" {
       title = "My Rule Folder"
   }
   ```

1. 定义警报规则。

   有关警报规则的更多信息，请参阅[如何创建 Grafana 管理的警报](https://grafana.com/blog/2022/08/01/grafana-alerting-video-how-to-create-alerts-in-grafana-9/)。

1. 创建包含一条或多条规则的规则组。

   在此示例中，使用 `grafana_rule_group` 资源组。

   ```
   resource "grafana_rule_group" "my_rule_group" {
       name = "My Alert Rules"
       folder_uid = grafana_folder.rule_folder.uid
       interval_seconds = 60
       org_id = 1
   
       rule {
           name = "My Random Walk Alert"
           condition = "C"
           for = "0s"
   
           // Query the datasource.
           data {
               ref_id = "A"
               relative_time_range {
                   from = 600
                   to = 0
               }
               datasource_uid = grafana_data_source.testdata_datasource.uid
               // `model` is a JSON blob that sends datasource-specific data.
               // It's different for every datasource. The alert's query is defined here.
               model = jsonencode({
                   intervalMs = 1000
                   maxDataPoints = 43200
                   refId = "A"
               })
           }
   
           // The query was configured to obtain data from the last 60 seconds. Let's alert on the average value of that series using a Reduce stage.
           data {
               datasource_uid = "__expr__"
               // You can also create a rule in the UI, then GET that rule to obtain the JSON.
               // This can be helpful when using more complex reduce expressions.
               model = <<EOT
   {"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"params":[],"type":"last"},"type":"avg"}],"datasource":{"name":"Expression","type":"__expr__","uid":"__expr__"},"expression":"A","hide":false,"intervalMs":1000,"maxDataPoints":43200,"reducer":"last","refId":"B","type":"reduce"}
   EOT
               ref_id = "B"
               relative_time_range {
                   from = 0
                   to = 0
               }
           }
   
           // Now, let's use a math expression as our threshold.
           // We want to alert when the value of stage "B" above exceeds 70.
           data {
               datasource_uid = "__expr__"
               ref_id = "C"
               relative_time_range {
                   from = 0
                   to = 0
               }
               model = jsonencode({
                   expression = "$B > 70"
                   type = "math"
                   refId = "C"
               })
           }
       }
   }
   ```

1. 转到 Grafana UI 并查看您的警报规则。

   您可以查看是否触发警报规则。您还可以看到警报规则每个查询阶段的可视化效果。

   警报触发时，Grafana 会通过您定义的策略路由通知。

   例如，如果您选择 Slack 作为联系点，Grafana 的嵌入式 [Alertmanager](https://github.com/prometheus/alertmanager) 会自动向 Slack 发布消息。