Datadogのアラート時の対応をRundeckで自動化する


やりたかったこと

datadogのMonitorsで閾値超過時にアラートをslackに通知しているが、対応方法が決まっているものがある。
そういうものはトイルになるので、自動化したかった。

構成

全体の構成としては、下図のようなものになる。
DatadogでGKEをモニタリングしており、Monitorによるアラート発報時にwebhookにてRUNDECKのJOBを実行する。
なお、RUNDECKはCloudArmorにてSourceIPを制限している。

しくみを作る

CloudArmorにDatadog webhookのSourceIPを許可する

公式ドキュメント通り、datadogの各サービスのsource ipは取得できる。

curl -X GET "https://ip-ranges.datadoghq.com/" \
-H "Content-Type: application/json"

今回は以下のようにwebhooksのみを取得し、CloudArmorに追加しておく

curl -X GET "https://ip-ranges.datadoghq.com/" \
-H "Content-Type: application/json" \
| jq '.webhooks'

rundeck側で実施するjobを作成する

取り敢えず、適当にjobを追加しておく

追加したjobの Workflowには 引数に ${option.raw}を追加する。このrawにdatadogのアラートの詳細情報(Payload)が乗ってくる。

rundeck側でwebhookの設定をする

以下からwebhookを追加する

webhookの詳細を追加する。
先程追加したjobを指定し、
datadogのドキュメントにも記載されているが、-raw ${raw} -event_type ${data.event_type} をoptionに追加しておく。
このrawにdatadogのアラートの詳細情報(Payload)が乗ってくる。

webhookを保存すると、Post URLが発行される。

datadog側でwebhookの設定をする

Integrations -> webhook で検索

Webhooks Integration の Webhooks から + New

適当にNameを入れて、 URL には rundeck 側で発行された Post URL 記載する。
このPayloadに記載されたものが rundeck側で設定した raw に乗ってくる。
デフォルトでは "alert_scope": "$ALERT_SCOPE"が無いが、アラートの条件がほしかったので追加しておく。
その他、追加できるものは公式ドキュメントに記載されている。

datadogのアラート設定

Monitors にてアラートを設定する
以下はKubernetesのPVCのディスク使用率が80%になったらアラートとしている。

アラート時にwebhookを呼び出したいので、以下を入れておく

{{#is_alert}}
@webhook-test-webhook 
{{/is_alert}}

アラートの確認

Test NotificationでNotificationをテストする

rundeck側でjobが実行されている。

ユースケースに応じて、このPayloadからイジイジしてシェルスクリプトを作る
alert_scopeを付加しておくと以下の感じでいじるときに便利だったから追加しておいた

echo $1 | jq 

TARGET=`echo $1 | jq '.alert_scope' | sed 's/"//g'`
echo debugging target alert_scope is ${TARGET}

# Namespaceとかpod名がどの順番で来てもいいようにしておく
NAMESPACE="hoge"
POD_NAME="fuga"
for i in $(echo $TARGET | sed "s/,/ /g")  # カンマ区切りを先ずバラす
  do 
    echo debugging for_statement index is "$i"
    if [ `echo $i | grep 'namespace:'` ] ; then # namespace名を取得する
      NAMESPACE=$(echo $i | cut -d ":" -f2)
    elif [ `echo $i | grep 'pod_name:'` ] ; then # pod名を取得する
      POD_NAME=$(echo $i | cut -d ":" -f2)
    fi

 done

echo The target namespace is $NAMESPACE
echo The target pod_name is $POD_NAME 

sudo gcloud container clusters get-credentials クラスタ名 --zone asia-northeast1-a --project プロジェクト名
sleep 2
sudo kubectl exec pod -n $NAMESPACE $POD_NAME -- やりたい処理