AzureのLogic AppsとOpsgenieを組み合わせてオンコールやアラートの管理を行う


はじめに

できるだけコストをかけずに運用監視の仕組みを整えたく、AzureのLogic AppsとOpsgenieの組み合わせでの運用監視について試してみました。

Opsgenieとは

OpsgeniePagerDutyと同様のオンコールやアラートの管理ができるサービスです。

OpsgenieもPagerDutyもフリープランが用意されていて、いずれも5ユーザまでは無料で使えるので、小さなチームで利用するのであればどちらのサービスを選択してもある程度の運用監視であればコストをかけずにできそうです。

どちらのサービスでも、モバイルアプリが提供されているところや、月100通までSMSを送信できるところなどは同じ感じでしたが、有料プランと比べた際の細かな制約についてはそれぞれで異なる感じでした。

無料プラン同士の機能比較や、将来的な有料版へのアップグレードを見据えた上での機能やコスト比較によっては、PagerDutyを選択した方が良いケースもあるかと思いますが、Atlassianが提供している「小さなチームの大きな夢をかなえる無料サービス」で他のサービスも併せて利用するのであれば、Opsgenieで揃えておいても良いのかなと思いました。

Logic Appsとは

Azureが提供しているノーコードでワークフローを作成できるサービスです。Logic Appsは従量課金なので、オンコールやアラート管理で使用するだけであれば、こちらも、ほぼコストがかからないと思います。

Logic AppsはトリガーとしてHTTP Requestを受け付けることができ、POSTで送信されたbodyに含まれる文字列で簡単な振り分けを行ってHTTP Requestを送信するような使用が可能となります。

今回は、前段のアプリケーション側からのエラー通知や、チャットサービスへの通知をLogic Appsで受け取り、特定の条件下でOpsgenieにアラートを通知させる用途で使用します。

やってみる

Opsgenieの設定

まず、Opsgenieのサイトより登録を行い、SMSの設定やモバイルアプリのインストールを行っておきます。

Opsgenieの管理コンソールにログインし、「Teams」からチームを作成します。今回はmy_teamという名前でチームを作成しています。

作成したチームを選択して設定画面に移動し「Add Integration」ボタンを押してAPIを追加します。

Logic Appsから呼び出す際にAPI Keyが必要となるのでコピーしておきます。

この段階で一度アラートが来るか試してみます。({API_KEY}には上記のAPI Keyを設定します。)

curl -X POST "https://api.opsgenie.com/v2/alerts" \
  -H "Content-Type: application/json" \
  -H "Authorization: GenieKey {API_KEY}" \
  -d '{
    "message": "A test alert message",
    "description":"Test alert needs a description",
    "responders":[
      {"name":"my_team", "type":"team"}
    ],
    "priority":"P1"
  }'

設定したメールやSMS、モバイルアプリにアラートが来たら成功です。

Logic Appsの設定

今回はMyGroupというリソースグループに対してLogic Appsの設定を行います。設定は、下記のtemplate.jsonをデプロイします。

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "api_key": {
        "type": "SecureString"
    },
    "workflows_opsgenie_name": {
        "defaultValue": "opsgenie",
        "type": "String"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Logic/workflows",
      "apiVersion": "2017-07-01",
      "name": "[parameters('workflows_opsgenie_name')]",
      "location": "japaneast",
      "properties": {
        "state": "Enabled",
        "definition": {
          "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "triggers": {
            "request": {
              "type": "Request",
              "kind": "Http",
              "inputs": {
                "schema": {}
              }
            }
          },
          "actions": {
            "condition": {
              "runAfter": {},
              "type": "If",
              "expression": {
                "and": [
                  {
                    "contains": [
                      "@string(triggerBody())",
                      "error"
                    ]
                  }
                ]
              },
              "actions": {
                "HTTP": {
                  "runAfter": {},
                  "type": "Http",
                  "inputs": {
                    "body": {
                      "message": "A test alert message",
                      "description": "@{triggerBody()}",
                      "priority": "P1",
                      "responders": [
                        {
                          "name": "my_team",
                          "type": "team"
                        }
                      ]
                    },
                    "headers": {
                      "Authorization": "[concat('GenieKey ', parameters('api_key'))]",
                      "Content-Type": "application/json"
                    },
                    "method": "POST",
                    "uri": "https://api.opsgenie.com/v2/alerts"
                  }
                }
              }
            }
          },
          "outputs": {}
        },
        "parameters": {}
      }
    }
  ],
  "outputs": {
    "postUrl": {
      "type": "string",
      "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows/', parameters('workflows_opsgenie_name')), '/triggers/request'), '2017-07-01').value]"
    }
  }
}

上記のテンプレートは、POSTしたbodyにerrorという文字列が含まれていた場合に、Opsgenieで設定したmy_teamにアラートのリクエストを送るテンプレートになります。

デプロイは下記のazコマンドで行います。({API_KEY}にはOpsgenie側で発行されたAPI Keyを設定します。)

az deployment group create --resource-group MyGroup --template-file ./template.json --parameters api_key='{API_KEY}' --query properties.outputs.postUrl.value --output tsv

デプロイが成功すると、Logic Apps側でのリクエストを受け付けるURLが出力されるので、そのURLに対して、errorという文字列を含むbodyを送信してテストを行います。

curl -X POST "{出力されたURL}" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "[error] server is down..."
  }'

設定したメールやSMS、モバイルアプリにアラートが来たら成功です。

さいごに

間にLogic Appsを挟むことで、例えばerrorとwarnでアラートを変えたり、infoではアラート自体を行わなかったりなど柔軟に対応することができそうです。また、OpsgenieからPagerDutyに変更することになってしまった場合などにもLogic Appsの変更だけで良さそうです。

Opsgenieでは、フリープランでもオンコールの担当をローテーションしたり、SMSで通知を行ったりなど、最低限のことは行えそうなので、コストをかけずに小さいチームで運用監視していく場合などに利用できそうかなと思いました。