🔔

Grafana Cloud IRM/OnCall と Google Cloud のアラートを連携する

2025/02/10に公開

はじめに

普段アラートを Slack へ通知することはしていても、四六時中 Slack をみているわけにもいかないです。また、寝てたら Slack の通知なんで気づくわけもないので、なにかしら叩き起こしてくれるものが欲しくなります。
今回は、OSS もあって最近 Cloud 版が東京にもできた[1]ということで気になっている Grafana の Grafana Cloud Incident Response & Management (IRM) の OnCall サービスをためしてみようと思います。

Grafana Cloud Incident Response & Management (IRM)[2]

概要

Grafana OnCall と Grafana Incident という 2 つのサービスを持つインシデントワークフローを効率化するためのツールらしいです。Cloud の場合はそれがフルマネージドで提供されます。
OnCall は担当者のスケジュールや通知、アラートからのインシデント起票などをおこない、Incident はタスク・進捗・状況を管理・Slack や GitHub との自動連携などを提供しています。


https://grafana.com/ja/products/cloud/irm/

料金

月間 3 アクティブユーザまでは無料ではじめることができ、超えた場合は月額 $20 ずつユーザごとに課金されます[3]。100 人いたら 97 人分課金で、293,673 円 (151.38 円/USD) ほどでしょうか。

IRM のアクティブユーザーとは何ですか?

アクティブな IRM ユーザーとは、OnCall のスケジュールやエスカレーションチェーンに含まれているか、次のいずれかの操作を行ったユーザーのことです。

  • アラートグループや OnCall の設定のステータスを変更した
  • ページを受信した、または他のユーザーにページを送信した
  • インシデントを作成、編集、または更新した

気になるところが、アクティブユーザというところです。IRM を利用しないユーザは Grafana 上にいても課金されないのでダッシュボードしかみないよーってひとがいても財布が痛くなさそうです。
次の記事では Grafana Cloud の IRM へ移行したことで、年間数万ドルを節約をした事例が紹介されていました。
https://grafana.com/blog/2023/09/15/inside-prezis-cost-saving-switch-to-grafana-alerting-grafana-oncall-and-grafana-incident-from-pagerduty/

ちなみにコンプライアンス[4]はひととおりそろっていそうでした。

  • ISO 27001 (ISMS)
  • SOC 2 Type 2 Certification
  • PCI Security Standards Council
  • GDPR
  • Cloud Security Alliance (CSA)

Grafana OnCall を使ってみる

セットアップ

Grafana Cloud へアクセスし、無料トライアルアカウントを作成します。プランごとの違いは Grafana Cloud features から確認できます。ほとんど機能を試すことができそうです。Stack URL と Deployment Region を選んだら利用開始です。

Set up your first Grafana stack

無料は 1 つの Stack を持つことができ、Pro プランでは 3 つの Stack を持てるので本番環境と開発用サンドボックスとしてそれぞれ Stack を作成するような運用ができそうです[5]。利用可能なリージョンは、Grafana Cloud services regional availabilityから確認できます。
作成後の Stack は、「My Account > Manage your Grafana Cloud stack > Details」から確認できます。「Manage your stack > Grafana > Details」を開くと、aws の Tokyo リージョンにデプロイされていることが確認できます。


Grafana Instance Details

通知設定

iOS と Android で OnCall 通知を受け取れる「Grafana IRM」というモバイルアプリが提供されています。Grafana Cloud から 「Profile > IRM > Mobile App Connection」 を開き、QR コードを読み取ると簡単に連携できます[6]


Mobile App Connection

もしも、Mobile App 以外の SMS や Phone Call で通知を受け取るのであれば、「Alerts&IRM > OnCall > Users」 を開き、各ユーザの Edit から通知を設定できます。同じ画面から通常時と重大な通知のときにどんな通知を利用するか、それぞれの通知先を複数設定することもできます。


Alerts&IRM > OnCall > Users


User Info

Slack 連携

Slack と連携することで、通知をおこなったり、Incident の起票や対応チャンネルの自動作成などを行うことができます[7]。「Alerts & IRM > OnCall > Settings」を開いて、ChatOps タブを選択します。Slack Workspace と連携したら、 デフォルトで通知をおこなうチャンネルを選択します。専用のチャンネルを作成することが推奨されていました。今回は事前に grafana-notification というチャンネルを用意しました。


Alerts & IRM > OnCall > Settings > Chat Ops

Integration 設定

Get started with Grafana OnCall を読みながら進めていきます。
「Alerts & IRM > OnCall > Integrations」を開きます。「Add Integration」からどのシステムからのアラートを受け取るか選択できます。候補にない場合は、Webhook を利用することもできます。今回は Webhook を選択します。MyWebhookIntegration という名前で作成します。


New Webhook Integration

作成できたら、とりあえずデモを試してみるため右上の「Send demo alert」からそのまま「Send Alert」をクリックします。「Alerts & IRM > OnCall > Alert Groups」を開き、デモのアラートが確認できます。Slack を開くと、設定していたチャンネルへも投稿が来ていることがわかります。これは Integration の「Unmatched alerts routed to default route」が「Publish to ChatOps」になっているためです。


Slack Notification

Team の作成

通知先にするチームを作成します。「Administration > Users and access」から「Teams」を開きます。「New Team」からMyTeamという名前で今回作成しました。


Administration > Users and access > Teams > MyTeam

Escalation chain 設定

Mobile App で通知を受け取るために Escalation chain を作成します。「Alerts & IRM > OnCall > Escalation chains」を開き、「New escalation chain」から作成します。Important EscalationDefault Escalationという名前で 2 つ作成します。
どちらも Escalation Step で、Notify all team membersを選択します。

  • Important Escalation では Start Important notification
  • Default Escalation では Start Default notification

となるようにします。宛先チームは作成した MyTeam を指定します。


Alerts & IRM > OnCall > Escalation chains > Default Escalation


Alerts & IRM > OnCall > Escalation chains > Important Escalation

Escalation chain を Integration へ追加

作成した Integration を開きます。「Add Route」から「Alerts matched by Template matching」に{{ payload.severity == "critical" }}を追加します。さらに「Trigger escalation chain」で「Important Escalation」を選択します。そして、「Unmatched alerts routed to default route」の「Trigger escalation chain」で「Default Escalation」を追加します。
これで、各ユーザが設定した通知先へアラートを飛ばす準備が整いました。


MyWebhookIntegration with Escalation

デモ実行

「Send demo alert」を再び実行すると、Mobile App に通知がくるはずです。


通常のプッシュ通知

つぎに、"severity": "critical" を payload へ追加して実行します。「Copy as CURL」から以下のように実行してもいいです。マナーモードにしていても、通知が来るはずです。

curl -X POST https://oncall-prod-us-central-0.grafana.net/oncall/integrations/v1/webhook/xxxxxxxxxxxxxxxx/ \
-H 'Content-Type: Application/json' \
-d '{
  "message": "This alert was sent by user for demonstration purposes",
  "severity": "critical"
}'


重大なプッシュ通知

もしも iOS で通知が来ない場合は、設定から「重大な通知」がオンになってるかを確認してみてください。そのほかの設定は Push notifications を確認してみるといいです。


通知設定

Google Cloud と連携

さて、実際にアラートと OnCall を連携してみましょう。こんな感じで Google Cloud から Grafana Cloud へ Webhook 通知をします。メッセージを受け取った Cloud Run Functions が Webhook をたたくだけです。

イメージ図

準備

デプロイする Cloud Run Functions では、incident が open のときのみ Webhook 通知をするような仕組みになっています。通知する際に、incident から必要な情報を引っ張ってきてリクエストします。
https://github.com/sikeda107/tech-blog/blob/ad95ffc0a336c05781e7127c1bbc362340eb130a/grafana-oncall-notifier/src/index.ts#L14-L35

各種リソースを作成していきます。PROJECT_IDGRAFANA_WEBHOOK_URLは自身のものを設定します。

リソース作成コマンド
PROJECT_ID='YOUR PROJECT ID'
gcloud config set project $PROJECT_ID

SERVICE_ACCOUNT='pubsub-grafana-oncall-notifier'
SECRET_ID='grafana-webhook-url'
GRAFANA_WEBHOOK_URL='https://oncall-prod-us-central-0.grafana.net/oncall/integrations/v1/webhook/xxxxxxxxxxxxxxxx/'
TRIGGER_TOPIC='grafana-oncall-notifier'
SERVICE='pubsub-grafana-oncall-notifier'

# Cloud Run Functions で使うサービスアカウント
gcloud iam service-accounts create $SERVICE_ACCOUNT

# Webhook URL を格納する Secret Manager
echo -n "$GRAFANA_WEBHOOK_URL" | gcloud secrets create  $SECRET_ID \
    --replication-policy="automatic" \
    --data-file=-

# Alert 通知先の PubSub Topic
gcloud pubsub topics create $TRIGGER_TOPIC

# サービスアカウントから、シークレットに対してアクセス権限を付与
gcloud secrets add-iam-policy-binding $SECRET_ID \
    --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role='roles/secretmanager.secretAccessor'

# サービスアカウントから、ログを記録する権限を付与
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role='roles/logging.logWriter'

# Docker レジストリを作成
gcloud artifacts repositories create gcf-artifacts \
    --repository-format=docker \
    --location=asia-northeast1

# Cloud Build を使って、Cloud Run Functions のデプロイ
gcloud builds submit --project=$PROJECT_ID \
    --config ./cloudbuild.yaml \
    --substitutions=_SOURCE=.

# PuSub Subscription から Cloud Run Functions へのアクセス権を付与
gcloud run services add-iam-policy-binding $SERVICE \
    --region=asia-northeast1 \
    --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role='roles/run.servicesInvoker'

PROJECT_NUMBER=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)")

# Alert から PubSub Topic に対してメッセージを送るための権限を付与
gcloud pubsub topics add-iam-policy-binding $TRIGGER_TOPIC \
    --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-monitoring-notification.iam.gserviceaccount.com" \
    --role='roles/pubsub.publisher'

Cloud Monitoring の Alert を Alert Test Policy 1Alert Test Policy 2 と 2 つ作ります。1 の Severity は Warning で、2 の Severity を Critical にします。通知先は上で作成したTRIGGER_TOPIC='grafana-oncall-notifier'を使います。全体的な設定は以下のとおりです。

gcloud alpha monitoring policies describe の結果
Alert Test Policy 1
alertStrategy:
  autoClose: 1800s
  notificationRateLimit:
    period: 300s
combiner: OR
conditions:
- conditionMatchedLog:
    filter: |-
      logName:"my-test-log"
      textPayload:"A simple entry Warn"
  displayName: Log match condition
  name: projects/PROJECT_ID/alertPolicies/0000000000/conditions/0000000000
creationRecord:
  mutateTime: 'yyyy-mm-dd'
  mutatedBy: foo@example.com
displayName: Alert Test Policy 1
documentation:
  content: this is test
  mimeType: text/markdown
enabled: true
mutationRecord:
  mutateTime: 'yyyy-mm-dd'
  mutatedBy: foo@example.com
name: projects/PROJECT_ID/alertPolicies/0000000000
notificationChannels:
- projects/PROJECT_ID/notificationChannels/0000000000
severity: WARNING
Alert Test Policy 2
alertStrategy:
  autoClose: 1800s
  notificationRateLimit:
    period: 300s
combiner: OR
conditions:
  - conditionMatchedLog:
      filter: |-
        logName:"my-test-log"
        textPayload:"A simple entry Critical"
    displayName: Log match condition
    name: projects/PROJECT_ID/alertPolicies/000000/conditions/000000000
creationRecord:
  mutateTime: 'yyyy-mm-dd'
  mutatedBy: foo@example.com
displayName: Alert Test Policy 2
documentation:
  content: this is test
  mimeType: text/markdown
enabled: true
mutationRecord:
  mutateTime: 'yyyy-mm-dd'
  mutatedBy: foo@example.com
name: projects/PROJECT_ID/alertPolicies/0000000000
notificationChannels:
  - projects/PROJECT_ID/notificationChannels/0000000000
severity: CRITICAL

Grafana 側 Integration の修正

MyWebhookIntegration の 「Template」を変更します。今回は Web と Mobile push notifications を変更します。修正内容は単純で、payloadをそれぞれ利用するようにするだけです。

MyWebhookIntegration > Templates > Web


MyWebhookIntegration > Templates > Mobile push notifications

また、「Route」の条件もちょっとだけ修正します。小文字criticalを大文字Criticalにします。これは、Cloud Monitoring の Alert に合わせるためです。


MyWebhookIntegration > Routes > if

デモ

2 つのログエントリを順番に実施します。

# Warning 用
gcloud logging write my-test-log "A simple entry Warn"
# Critical 用
gcloud logging write my-test-log "A simple entry Critical"

無事に通知が来ました 📢


Alert groups - Web - Warn Result


Mobile - Warn Result


Alert groups - Web - Critical Result


Mobile - Critical Result

おわりに

Grafana Cloud IRM / OnCall をつかってみました。Webhook 連携をつかえば、だいたいなんとかなりそうなのでいいですね。Datadog も OnCall サービスがでたようなので、Google Cloud も公式ででないかなとか期待してます。

https://prtimes.jp/main/html/rd/p/000000063.000077474.html

脚注
  1. Grafana Labs、日本でのオープンソースオブザーバビリティコミュニティを拡大 Grafana Labs ↩︎

  2. Grafana IRM Grafana Cloud documentation ↩︎

  3. Grafana Pricing Free, Pro, Advanced, Enterprise ↩︎

  4. Security Compliance Grafana Labs ↩︎

  5. Stack architecture recommendations Grafana Cloud documentation ↩︎

  6. Installation and setup Grafana OnCall documentation ↩︎

  7. Slack integration for Grafana IRM Grafana OnCall documentation ↩︎

Discussion