好奇心の足跡

飽きっぽくすぐ他のことをしてしまうので、忘れないため・形にして頭に残すための備忘録。

Azureのサービス正常性アラートを、LogicAppsを経由していい感じにSlackに通知させる

こんにちは!今日は Azure Advent Calendar 2020 - Qiita の6日目の記事として、サービス正常性アラート(Service Health Alert) をSlackに通知させてみた話をしたいと思います。

はじめに

サービス正常性アラート(Service Health Alert)とは、Azure内のサービスに障害が起こったときに通知してくれる仕組みで、メール通知やWebHookなど、いろいろな通知方法が選べます。

今回、アラートはSlackに集約させたかったので、Slackに通知するようにしたのですが、情報をわかり易く加工して表示させたかったので LogicApps を通すことにしました。

f:id:kusuwada:20201121062603p:plain

なんとこれ、公式ドキュメントにやり方がそのまま載ってるんですよね!

docs.microsoft.com

これでいいじゃん!ってやってみたんですけど、結果こんな感じ。

Before:
f:id:kusuwada:20201119055650p:plain

これを

After:
f:id:kusuwada:20201119055653p:plain

こうしたという話。

これ結構やりたい人多そうなのと、LogicApps、ちゃちゃっとできるやろと思ってた割には躓いたところが多かったので、少し丁寧目に設定やテスト方法を書いていこうと思います。
LogicAppsの最終設定だけ見たい方は サービス正常性アラート用のLogicApps実装 に飛んでください!

※ 今回は全部AzurePortalから作業します
※ AzurePortalは日本語になっている前提です。適宜読み替えてください。

[基本] サービス正常性アラート用のResourceGroup、LogicApps作成

※対象のResourceGroup、LogicAppsがある場合はこの手順を飛ばしてください。

リソースグループの作成

  • AzurePortalにLoginし、画面一番上の検索窓で "resource" を検索、出てきた "リソースグループ" メニューを選択します。
  • 追加 > サブスクリプションの選択、リソースグループ名の入力、リージョンの選択、をします。
    • 今回はリソースグループ名を rg-service-health-japan としました。
    • リソースグループのリージョンは、リソースグループのメタ情報をどこに置くかという選択で、どのリージョンのリソースも傘下に入れることができます。つまり、システム情報を置くRegion縛りが特にない場合は、あまり気にしなくてよいということです。
  • 確認及び作成、でリソースグループが作られます。

LogicApps(ロジックアプリ)の作成と設定

Azure Monitor アラートによって複雑なアクションをトリガーする方法 - Azure Monitor | Microsoft Docs

の手順通り実施します。
今回はロジックアプリ名を la-service-health-japan としました。

途中の

手順 8 で、HTTP 要求トリガーに次のサンプル ペイロードを使用します。

の部分で、2020/11/19現在では

"impactedServices": "[{"ImpactedRegions"}]",

ここがjsonとして壊れてしまっているので、貼付け時に

"impactedServices": "[{\"ImpactedRegions\"}]",

に修正しておいてあげます。

手順 11 から 14 では、次の手順に従います

手順11以降は通知条件の追加とTeams連携なので実施しません。
代わりに、Slack通知の設定をしてあげます。

  • HTTP要求の受信時、の下に表示される +新しいステップ ボックスを選択します。
  • 操作の検索boxで "Slack" と検索します。

f:id:kusuwada:20201119063211p:plain

  • アクションの方に出てくる "投稿メッセージ" を選択します。
  • Slackに接続するためのサインインボタンなどが出てくるので、連携したいSlackにサインイン、権限などを確認して許可を与えます。
  • その後は、通知したい内容を適宜こんな感じで設定していきます

f:id:kusuwada:20201119121849p:plain

一番下のパラメータ追加を選択すると、Slack上でのボット名やアイコンを設定できます。

これで一旦基本的な設定は完了。

[基本] アクション(Action)の設定

  • AzurePortalの上部の検索窓からから、"Monitor"を検索、"モニター"を選択
  • 左のメニューから、"アラート"を選択
  • 上部のタブメニューから、"アクションの管理"を選択
  • 上部のタブメニューから、"アクショングループの追加"を選択
  • サブスクリプション、リソースグループの選択
  • アクショングループ名、表示名の設定
    • 今回はそれぞれag-service-health-japan, svc-health-jとしました
  • 次へ > 通知の設定をします
    • メールやSMSなどの設定をしたい場合はここで設定してください
    • 今回はスキップしました
  • 次へ > アクションの設定をします
    • アクションの種類: ロジックアプリを選択
    • 右側にロジックアプリの選択フレームが出てくるので、先程選択したロジックアプリを選択します
    • 共通の警告スキーマをプロジェクトに合わせて設定してください
      • 今回は "いいえ" を選択しました
    • 名前を設定します
      • 今回は service-health-to-slack としました
  • 確認および作成を選択、確認画面をチェックして "作成" を選択

[基本] サービス正常アラートの設定と通知先の設定

今度はLogicAppsのトリガーに情報を渡すための設定をします。

  • AzurePortalの上部の検索窓からから、サービス正常性を検索、選択
  • 左のメニューの一番下、 アラート > 正常性アラート を選択
  • サービス正常性アラートの追加 を選択
  • 対象のサブスクリプションとサービス、リージョン、通知対象のイベントを選択
    • 今回は、日本リージョンのアラートのみを拾う設定にしました
    • 東日本 (Japan East) と 西日本 (Japan West)
  • アクション > アクション グループの選択 から、先程作成したアクショングループを選択
  • アラートルールの詳細 から、ルール名、説明、リソースグループを選択
  • "アラート ルールの作成" をクリック

f:id:kusuwada:20201119130403p:plain

これで、設定したサービス・イベント・リージョンに対するサービス正常性アラートが発行された時、先ほど作成したロジックアプリが発動、Slackに通知されるようになりました!
これで冒頭に紹介した Before の状態になります。

あれ、通知された Region おかしくない?

設定してしばらく、早速アラートが飛んできました!
Before の Region を確認すると、オーストラリア!?
サービス正常性のAzurePortalから、アラートの履歴を確認しても、「リージョン」の列には Australia Central とか Australia East ばかり並んでいます。おかしい。

あまり深く考えずサポートに問い合わせると、「SQLの先頭に引っかかった体と思われます」「SQLのクエリを見直してください」とのこと。クエリを書いてるのはAzureの中だと思うんだけどなー?と思いつつ、この言葉をヒントにもう一度届いたアラートを見てみると、

Services: [{"ImpactedRegions":[{"RegionName":"Australia Central"},{"RegionName":"Australia Central 2"},{"RegionName":"Australia East"},{"RegionName":"Australia Southeast"},{"RegionName":"Brazil South"},{"RegionName":"Canada Central"},{"RegionName":"Canada East"},{"RegionName":"Central India"},{"RegionName":"Central US"},{"RegionName":"Central US EUAP"},{"RegionName":"East Asia"},{"RegionName":"East US"},{"RegionName":"East US 2"},{"RegionName":"East US 2 EUAP"},{"RegionName":"France Central"},{"RegionName":"Japan East"},{"RegionName":"Japan West"},{"RegionName":"Korea Central"},{"RegionName":"Korea South"},{"RegionName":"North Central US"},{"RegionName":"North Europe"},{"RegionName":"South Central US"},{"RegionName":"Southeast Asia"},{"RegionName":"South India"},{"RegionName":"UAE Central"},{"RegionName":"UAE North"},{"RegionName":"UK South"},{"RegionName":"UK West"},{"RegionName":"West Central US"},{"RegionName":"West Europe"},{"RegionName":"West India"},{"RegionName":"West US"},{"RegionName":"West US 2"}],"ServiceName":"API Management"}]

お!このimpactedServicesを表示させた部分の配列に、影響があったRegionが全て入っているみたい。
ということは、アラートの中の region は、どうやら影響のあったRegionの中から適当に選ばれている(サポートの回答から推測するに、クエリで引っかかったやつの先頭?)ので、正しく影響を受けたRegionを拾うには正しくなさそう。
このimpactedServicesから、Regionの配列を抜くのが正解っぽい。

もしくは、実際に送られてきたアラートのSchemaをみると、上記サイトには書いていなかったけど impactedServicesTableRows というフィールドがある。
サービス正常性アラートのメール通知を利用していると、いい感じに影響を受けたRegionがテーブルで表示されているので、おそらくこれを使っているんでしょう。

今回は、日本Regionの情報だけ欲しかったので、自分が利用している「東日本」か「西日本」どちらで起きているか(もしくは両方)の情報だけSlackに通知するようにしたい。

サービス正常性アラート用のLogicApps実装

Regionをいい感じに通知するようLogicApps実装しました。
こんな感じ。

f:id:kusuwada:20201121055153p:plain

では Before の状態からアクションを追加していきます。

  • HTTP要求の受信時、の下に新しいステップを作成します
  • 検索窓に json とうつと、アクションの項目に JSONの解析 が現れるので、これを選択します
  • コンテンツには、"HTTP要求の受信時" から取ってこれる動的なコンテンツから、impactedServicesを入力します
  • スキーマは、下記のサンプルペイロードを使って生成してみてください
[{"ImpactedRegions":[{"RegionName":"Australia Central"},{"RegionName":"Australia Central 2"},{"RegionName":"Australia East"},{"RegionName":"Australia Southeast"},{"RegionName":"Brazil South"},{"RegionName":"Canada Central"},{"RegionName":"Canada East"},{"RegionName":"Central India"},{"RegionName":"Central US"},{"RegionName":"Central US EUAP"},{"RegionName":"East Asia"},{"RegionName":"East US"},{"RegionName":"East US 2"},{"RegionName":"East US 2 EUAP"},{"RegionName":"France Central"},{"RegionName":"Japan East"},{"RegionName":"Japan West"},{"RegionName":"Korea Central"},{"RegionName":"Korea South"},{"RegionName":"North Central US"},{"RegionName":"North Europe"},{"RegionName":"South Central US"},{"RegionName":"Southeast Asia"},{"RegionName":"South India"},{"RegionName":"UAE Central"},{"RegionName":"UAE North"},{"RegionName":"UK South"},{"RegionName":"UK West"},{"RegionName":"West Central US"},{"RegionName":"West Europe"},{"RegionName":"West India"},{"RegionName":"West US"},{"RegionName":"West US 2"}],"ServiceName":"API Management"}]

※ Before の状態で通知された impactedRegions のサンプルになります。2020年11月時点のものです

f:id:kusuwada:20201121055329p:plain

さらにもう一つ、すぐ下にステップを追加します。

  • 今度は "変数" で検索し、アクションから "変数を初期化する" を選択
  • 名前に regions、種類を 文字列、値は空のままにします

f:id:kusuwada:20201121055430p:plain

ここで作成した変数に、Regionを追加していくステップを追加します。

  • "制御" や "for each" で検索し、For eachのアクションを選択
  • 以前の手順から出力を選択 の項目に、動的コンテンツから JSONの解析 > ImpactedRegions を選択します
    • ※自動で2重ループになりますが、そのまま
  • 一番内側の For eachを開き、アクションを追加

f:id:kusuwada:20201121055530p:plain

  • "条件" で検索し、"条件(制御)" を選択
  • 図のように 動的コンテンツよりRegionName, 次の値を含む, Japan を入れる

f:id:kusuwada:20201121055617p:plain

※条件はお好みで変更してください

  • True boxにアクション "文字列変数に追加" を選択
  • 名前: regions(さっき作成した変数), 値: 動的コンテンツよりRegionName

f:id:kusuwada:20201121055741p:plain

Before のときに作成した、Slackに投稿するステップを編集します。

  • Slackの投稿メッセージのステップを開きます
  • Region: region となっていたのを、 Region: regions(さっき作成した変数) に変更

f:id:kusuwada:20201121055836p:plain

これで設定は完了です。保存して終了してください🙌

[おまけ] LogicAppsにテストデータを設定して流したい

このLogic、折角作ったけど次にAzureに障害があるまで作動しない = テストできないじゃん!と気づき、LogicAppsのテスト方法を探してみました。

docs.microsoft.com

これも公式ドキュメントあるやん!MS様親切…!
と、手順通りにやってみようと思ったのですが…

f:id:kusuwada:20201121060009p:plain

!?
対応してない!?

ここに入れられないと、結局Slack投稿時に選択した動的コンテンツが無効になってしまうので、あまりテストにならない…。
困った。

苦肉の策ですが、動作確認用に別のテスト用LogicAppsを作成して、テスト用コンテンツを流すようにしました。
正常性アラート発行のトリガの次に、テスト用データのJSONを流し込むためのステップを挿入、ここでのJSON解析済み入力をその下のステップで使うようにします。

詳細は次の章に載せますが、もしもっといいやり方があれば是非ご教示ください…!

ちなみに、一度でもサービス正常性からアラートが飛んできていれば、対象のロジックアプリの概要画面の下の方の "実行の履歴" から履歴を見ることができ、好きな履歴を選択して「再送信」をすることで同じトリガのペイロードから現在のロジックをテストすることができます。

[おまけ] テスト用のLogicApps実装

全体像

f:id:kusuwada:20201121060542p:plain

LogicAppsはコピー機能がないようなので、まずは上で作成したLogicAppsと同じものをポチポチ作成してください。

新しく作成したTest用のLogicAppsで、HTTP要求の受信時の下に、テストデータの挿入ステップを追加します。

  • JSONの解析を選択
  • コンテンツ、に下記を貼り付け
{
  "body": {
    "data": {
      "context": {
        "activityLog": {
          "channels": "Admin",
          "correlationId": "cf009240-bd00-4cfc-b277-34d591b4c7f8",
          "description": "Active: API Management - Operation delays/timeouts - Applying Mitigation",
          "eventDataId": "482de12d-987e-4cd5-3293-3983050bbb43",
          "eventSource": "ServiceHealth",
          "eventTimestamp": "2020-10-26T19:21:27.7191193+00:00",
          "level": "Warning",
          "operationId": "cf009240-bd00-4cfc-b277-34d591b4c7f8",
          "operationName": "Microsoft.ServiceHealth/incident/action",
          "properties": {
            "communication": "<p>Starting at approximately 21:00 UTC on 21 Oct 2020, you were identified as a customer using API Management who may experience increased response times or timeouts for API Management operations. Retries may be successful for some customers.</p><p><strong>Current status:</strong> We have identified a recent deployment as the root cause, and we are actively rolling back the deployment to mitigate the issue. The rollback is expected to complete by 30 Oct 2020. The next update will be provided in 24 hours, or as events warrant.</p>",
            "communicationId": "11000054259645",
            "defaultLanguageContent": "<p>Starting at approximately 21:00 UTC on 21 Oct 2020, you were identified as a customer using API Management who may experience increased response times or timeouts for API Management operations. Retries may be successful for some customers.</p><p><strong>Current status:</strong> We have identified a recent deployment as the root cause, and we are actively rolling back the deployment to mitigate the issue. The rollback is expected to complete by 30 Oct 2020. The next update will be provided in 24 hours, or as events warrant.</p>",
            "defaultLanguageTitle": "API Management - Operation delays/timeouts - Applying Mitigation",
            "impactStartTime": "2020-10-21T21:00:00.0000000Z",
            "impactedServices": "[{\"ImpactedRegions\":[{\"RegionName\":\"Australia Central\"},{\"RegionName\":\"Australia Central 2\"},{\"RegionName\":\"Australia East\"},{\"RegionName\":\"Australia Southeast\"},{\"RegionName\":\"Brazil South\"},{\"RegionName\":\"Canada Central\"},{\"RegionName\":\"Canada East\"},{\"RegionName\":\"Central India\"},{\"RegionName\":\"Central US\"},{\"RegionName\":\"Central US EUAP\"},{\"RegionName\":\"East Asia\"},{\"RegionName\":\"East US\"},{\"RegionName\":\"East US 2\"},{\"RegionName\":\"East US 2 EUAP\"},{\"RegionName\":\"France Central\"},{\"RegionName\":\"Japan East\"},{\"RegionName\":\"Japan West\"},{\"RegionName\":\"Korea Central\"},{\"RegionName\":\"Korea South\"},{\"RegionName\":\"North Central US\"},{\"RegionName\":\"North Europe\"},{\"RegionName\":\"South Central US\"},{\"RegionName\":\"Southeast Asia\"},{\"RegionName\":\"South India\"},{\"RegionName\":\"UAE Central\"},{\"RegionName\":\"UAE North\"},{\"RegionName\":\"UK South\"},{\"RegionName\":\"UK West\"},{\"RegionName\":\"West Central US\"},{\"RegionName\":\"West Europe\"},{\"RegionName\":\"West India\"},{\"RegionName\":\"West US\"},{\"RegionName\":\"West US 2\"}],\"ServiceName\":\"API Management\"}]",
            "impactedServicesTableRows": "<tr>\r\n<td align='center' style='padding: 5px 10px; border-right:1px solid black; border-bottom:1px solid black'>API Management</td>\r\n<td align='center' style='padding: 5px 10px; border-bottom:1px solid black'>Australia Central<br>Australia Central 2<br>Australia East<br>Australia Southeast<br>Brazil South<br>Canada Central<br>Canada East<br>Central India<br>Central US<br>Central US EUAP<br>East Asia<br>East US<br>East US 2<br>East US 2 EUAP<br>France Central<br>Japan East<br>Japan West<br>Korea Central<br>Korea South<br>North Central US<br>North Europe<br>South Central US<br>Southeast Asia<br>South India<br>UAE Central<br>UAE North<br>UK South<br>UK West<br>West Central US<br>West Europe<br>West India<br>West US<br>West US 2<br></td>\r\n</tr>\r\n",
            "incidentType": "Incident",
            "isHIR": "false",
            "region": "Australia Central",
            "service": "API Management",
            "stage": "Active",
            "title": "API Management - Operation delays/timeouts - Applying Mitigation",
            "trackingId": "9T9F-DD0",
            "version": "0.1.1"
          },
          "status": "Active",
          "submissionTimestamp": "2020-10-26T19:21:34.5031653+00:00",
          "subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        }
      },
      "properties": {},
      "status": "Activated"
    },
    "schemaId": "Microsoft.Insights/activityLogs"
  },
  "headers": {
    "Connection": "Keep-Alive",
    "Content-Length": "4214",
    "Content-Type": "application/json; charset=utf-8",
    "Expect": "100-continue",
    "User-Agent": "IcMBroadcaster/1.0"
  }
}
  • ※ 2020年11月時点のスキーマのサンプルです
  • ※ 実際に正常系アラートからLogicAppsに届いたことのあるデータを使用しています

  • スキーマは、上記と同じペイロードを使って、「サンプルのペイロードを使用してスキーマを生成する」を実施

  • 名前を「テストデータ挿入(JSONの解析)」に変更しておく

次に、もともと実装していた JSONの解析 のコンテンツを、「HTTP要求の受信時」から取ってきていた動的コンテンツimpactedServicesから、今作成した「テストデータ挿入」由来のimpactedServicesに変更します。
スキーマは変更の必要はありません。

最後に、Slackへのメッセージ投稿を、「HTTP要求の受信時」から取ってきていた動的コンテンツから、全部「テストデータ挿入」由来のものに変更します。
(Regionだけそのまま)

泥臭いですが、これでサービス正常性アラートから送られてくるコンテンツをそのまま使うところはなくなり、自分が好きに入力したサンプルのペイロードでテストすることができるようになりました👍