アラート対応の自動化

# はじめに

この記事はニフクラ 等を提供している、[富士通クラウドテクノロジーズ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/fjct) の 11 日目の記事です。

昨日は @ktakaaki さんの [SwitchBotのBLEでデータを取ってみた](https://qiita.com/ktakaaki/items/c3e0a33878e8397ab15e) でした。
「ホームダッシュボード」というのは初耳で驚きました。我が家にも switch bot 製品がありますが、全然活用出来ていないなあと感じ笑、大変勉強になりました。

さて、本日は
* **Alertmanager と Gitlab を連携させてチケット発行を自動化する方法**
* **Alertmanager と webhook を連携させてアラート対応を自動化する方法**

を中心にご紹介します。

# この1年で行ったこと

昨年は所属するチームで初めて障害訓練を実施し、その流れを [チームで障害訓練をした話](https://qiita.com/ks2022/items/8fc311bb52b6c6c3321c) でご紹介させていただきました。
今年もチームメンバーに変動があったため障害訓練を実施しました。

昨年は障害訓練を実施することに力を入れていましたが、
今年は実施自体はスムーズに行えたので、訓練実施後に、気づいた点の改善を行っていきました。

振り返ってみると、以下の流れで進めていきました。

* 2度目の障害訓練実施
* チケット発行の自動化
  * 過去のナレッジを蓄積する場所を用意
* ドキュメントの更新
  * アラートメッセージに応じた対応手順を用意
* アラート対応の自動化

今回はチケット発行の自動化と、アラート対応の自動化について、詳しくご紹介します。

# チケット発行の自動化

障害訓練実施後の振り返りでは、障害発生時に参考にしているドキュメントの改善だけでなく、
**過去にアラート対応した際のナレッジを蓄積**しておく場所があったほうが良いのではないか、という意見が出ました。
私たちのチームでは障害対応時にコミュニケーションツール上に情報を残してしまうことが多かったので、情報を蓄積する場所をしっかりと用意することにしました。
手動でチケットを発行するのは面倒なため、チケットが自動で発行されるようにしました。

監視には Prometheus を、
アラート管理には Alertmanager を使っています。
そこで、**Alertmanager でアラートを検知した際、Gitlab の incident（チケット）を自動発行するようにしました。**

## 1. Gitlab との連携

※[参考: Gitlab公式ドキュメント](https://docs.gitlab.com/ee/operations/incident_management/integrations.html#prometheus-endpoint)

1. アラート発生時にチケット([incident](https://docs.gitlab.com/ee/operations/incident_management/incidents.html))を発行するプロジェクトを用意
1. プロジェクトの Settings > Monitor を開く
1. Alerts の項目を開く
1. Add new integration を選択
1. Select integration type プルダウンで Prometheus を選択
1. Active にトグルを変更
1. Prometheus API のベースURLを入力
1. Save integration で設定を保存
1. View credentials タブを開いて、Webhook URL と Authorization key を確認できればOKです

## 2. Alertmanager との連携

* alertmanager.yml に以下の設定を追加します
  ```
  receivers:
    - name: gitlab
      webhook_configs:
        - http_config:
            authorization:
              bearer_token: 1.9で確認した Authorization key を入力
          send_resolved: true
          url: 1.9で確認した Webhook URL を入力
  ```

これで、アラート発生時に incident が自動発行されます。発行されたincident は issue一覧から確認可能です。
**発生時刻やアラート名が自動で入力されているので、手動で入力する手間が省けます。**
incident 自動発行時に適用されるテンプレートも設定可能です。
基本的なアラート対応時のフローをチェックリストで記載したテンプレートを用意し、適用するようにしました。
アラート発生時には自動発行された incident を開き、記載されたフローに従ってエスカレーションや、調査を行っていきます。

   
# アラート対応の自動化

障害訓練実施後、ドキュメントも更新しました。
今まで事象別（例：APIのレスポンスが遅くなっている）に対応法のドキュメントが用意されており、アラートメッセージによってはどの事象に該当するのか分かりづらいものもありました。
そのため、**アラートメッセージ毎に対処法をまとめ直しました。**

アラートメッセージ毎に対処法をまとめ直すと、自動化できるのでは？という部分が出てきましたので、自動化もしてみました。

前項でお伝えした通り、アラート管理には Alertmanager を使っているので、
**Alertmanager と webhook を連携させ、自動化することにしました。**
以下は概要です。

 ```
Alertmanager
　　↓
  webhook
　　↓
アラートチェックスクリプト
　　↓
自動化用スクリプト
```

アラート発生時に、Alertmanager が webhook を呼び出します。
webhook はアラートチェックスクリプトを実行して発生したアラートを判断し、その後アラートに応じた自動化用スクリプトを呼び出します。
自動化スクリプトには、アラート発生時に実施してほしい処理を記載しておくことで、アラート対応を自動化できます。

具体的な方法は以下の通りです。

## 1. アラート毎の自動化用スクリプトを用意する

* /path/to/script/Alert_A.sh 
    * アラートが発生した際に実施したい内容を記載してください
    * アラート名毎にスクリプトを作ると見分けやすいです
    * 例ではシェルスクリプトにしていますが、他の言語でも問題ありません

## 2. アラートチェックスクリプトを用意
    
* /path/to/script/AlertCheck.sh
   * 今回はアラート名のみ取得していますが、必要に応じてほかの情報も同様に取得可能です
    * アラート名に応じて、対応する自動化用スクリプトを呼び出すように条件分岐させます
    ```
    #!/bin/bash

    # Alertmanager API をリクエストし現在発生しているアラート一覧を取得
    api_result=`curl -X GET -G https://AlertmanagerのURL:ポート/api/v2/alerts?receiver=receiver名`
    # アラート件数を取得
    alert_count=`echo ${api_result} | jq length`

    # アラート一覧からアラート情報を取得
    for ((i=0; i<=`expr ${alert_count} - 1` i++)) do
        # アラート名を取得
        alertname=`echo ${api_result} | jq -r ".[$i].labels.alertname"`

        # アラート名に応じて自動化用スクリプトを呼び出し
        if [ ${alertname} = "Alert_A" ]; then
            /path/to/script/Alert_A.sh
        fi
    done    
    ```
## 3. webhookをインストール(Ubuntu)

```
apt install webhook
```
## 4. webhook.json の作成
* /path/to/script/webhook.json に以下を記載します
  ```
  [
    {
      "id": "alertautomation",
      "execute-command": "/path/to/script/AlertCheck.sh",
      "command-working-directory": "/path/to/script"
    }
  ]
  ```

## 5. webhook起動
 
 ```
 webhook -hooks /path/to/script/webhook.json -verbose
 ```

## 6. Alertmanager で webhook を呼び出す

* alertmanager.yml に以下の設定を追加します
    ```
    receivers:
      - name: 'webhook'
        webhook_configs:
          - url: 'http://WebhookのURL:9000/hooks/alertautomation'
    ```

※参考: [Alertmanager でアラート時にシェルスクリプトを実行する方法](https://hawksnowlog.blogspot.com/2021/10/execute-shell-command-with-alertmanager.html)


**自動化用スクリプトでは、処理実施後に結果を通知させるようにしておくと、ブラックボックスにならず状況が理解しやすくなります。**
また、**完全に対応を自動化できないアラートであっても、原因調査に役立つログ調査のみ行わせて結果を通知させる、といった一部の対応を自動化**することも可能だと思います。


# まとめ

今年も障害訓練を実施し、その振り返り内容から、

* アラート情報を蓄積する場所の用意
* 一部アラート対応の自動化

を進めることができました。
今後もさらに改善を進めていけたらと思います！


明日は @Syuparn さんの 「WASIでエディタ的なツールを作る」 です。
自分好みのエディタが出来れば、仕事もはかどりそうですね・・・！お楽しみに！