LogAnalyticsのログアラートAPIを切り替える

# はじめに
こんにちは。
今回は、普段使っているLogAnalyticsのログアラート用のARMテンプレートを
ApplicationInsightsなどと同じScheduledQueryRulesAPIを使用するように書き換えます。

# TL;DR;
* [従来の Log Analytics Alert API](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/api-alerts)は 3 レベルのリソースを作成する必要があった
* ApplicationInsightsのアラートで使用していた、[ScheduledQueryRules API](https://docs.microsoft.com/ja-jp/rest/api/monitor/scheduledqueryrules)が LogAnalyticsにも対応した（半年くらい前？）
* APIを切り替える利点
    * クロス ワークスペース ログ検索が可能
    * リテンションが最大48時間に拡張
    * 単一リソースで構築がシンプルに
    * 今後の新機能は`ScheduledQueryRules API`に実装される
* [新旧APIを使ったARMTemplateのサンプルはこちら](https://github.com/HiroyukiSakoh/QiitaAttachments/tree/master/2019/03/LogAlertARMTemplate)
* そろそろ LogAnalyticsAlertAPIはディスコン？

# Log Analytics Alert API
以前はLogAnalyticsのログ検索からアラートを作成すると、
`Log Analytics Alert API`を使用したアラートリソースが作成されていました。
OMSからAzureに拡張された際にもこの仕様を引きずっており、ややこしい構成になっています。

また、[azure-rest-api-specs](https://github.com/Azure/azure-rest-api-specs/tree/master/specification/operationalinsights/resource-manager/Microsoft.OperationalInsights)も更新止まってて、ARMExplorerでも(savedSearchesしか)呼べず、不便です。

具体的に作成されるリソースは以下の3種類です。
## Microsoft.OperationalInsights/workspaces/savedSearches
保存された検索 [Saved Searches](https://docs.microsoft.com/en-us/rest/api/loganalytics/savedsearches/get)

```
GET /subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search?api-version=2017-04-26-preview
```

```json:response
{
  "id": "subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search",
  "etag": "W/\"datetime'2019-03-31T05%3A06%3A12.1905695Z'\"",
  "properties": {
    "Category": "AlertIbiza",
    "DisplayName": "qiita201903-dev-je-waf",
    "Query": "AzureDiagnostics | where ResourceProvider == 'MICROSOFT.NETWORK' and ResourceType == 'APPLICATIONGATEWAYS' and Category == 'ApplicationGatewayFirewallLog'",
    "Version": 2
  }
}
```

## Microsoft.OperationalInsights/workspaces/savedSearches/schedules
スケジュール

```
GET /subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search/schedules/qiita201903-dev-je-waf-schedule?api-version=2017-04-26-preview
```

```json:response
{
  "id": "subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search/schedules/qiita201903-dev-je-waf-schedule",
  "etag": "W/\"datetime'2019-03-31T05%3A06%3A12.7012932Z'\"",
  "properties": {
    "Interval": 30,
    "QueryTimeSpan": 30,
    "Enabled": true,
    "NearRealTime": false
  }
}
```

## Microsoft.OperationalInsights/workspaces/savedSearches/schedules/actions
アクション

リソース名とリソースIDが異なって気持ち悪いです。
リソース名:`qiita201903-dev-je-waf-alert`
リソースID:`qiita201903-dev-je-waf-search|qiita201903-dev-je-waf-schedule|qiita201903-dev-je-waf-alert`

```
GET /subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search/schedules/qiita201903-dev-je-waf-schedule/actions/qiita201903-dev-je-waf-alert?api-version=2017-04-26-preview
```
```json:response
{
  "id": "subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics/savedSearches/qiita201903-dev-je-waf-search/schedules/qiita201903-dev-je-waf-schedule/Actions/qiita201903-dev-je-waf-search|qiita201903-dev-je-waf-schedule|qiita201903-dev-je-waf-alert",
  "etag": "W/\"datetime'2019-03-31T05%3A06%3A17.2153531Z'\"",
  "properties": {
    "Type": "Alert",
    "Name": "qiita201903-dev-je-waf-alert",
    "Description": "WAFアラート(SavedSearch)",
    "Threshold": {
      "Operator": "gt",
      "Value": 0
    },
    "AzNsNotification": {
      "GroupIds": [
        "/subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/microsoft.insights/actionGroups/dev-je-actiongroup1"
      ]
    },
    "Severity": "warning",
    "ScheduleTypeSpecified": false,
    "Version": 1
  }
}
```

# Scheduled Query Rules API
こちらが新しいScheduledQueryです。
最新の仕様がDocsに記載されています[Scheduled Query Rules - Get](https://docs.microsoft.com/en-us/rest/api/monitor/scheduledqueryrules/get)。
また、ARMExplorerにはまだ取り込まれていませんが、[azure-rest-api-specs](https://github.com/Azure/azure-rest-api-specs/tree/2dd3a6d4e37d9a21d5af078b13156ba1e8733be5/specification/monitor/resource-manager/Microsoft.Insights/stable/2018-04-16)もすでに公開されています。

```
GET https://management.azure.com/subscriptions/<subscriptionId>/resourcegroups/qiita201903-dev-je/providers/microsoft.insights/scheduledQueryRules/qiita201903-dev-je-waf-alert?api-version=2018-04-16
```
```json:response
{
  "id": "/subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/microsoft.insights/scheduledqueryrules/qiita201903-dev-je-waf-alert",
  "name": "qiita201903-dev-je-waf-alert",
  "type": "microsoft.insights/scheduledqueryrules",
  "location": "japaneast",
  "tags": {
    "hidden-link:/subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics": "Resource"
  },
  "kind": null,
  "etag": "\"0300020b-0000-0000-0000-5ca04ce50000\"",
  "properties": {
    "description": "WAFアラート(ScheduledQuery)",
    "displayName": "qiita201903-dev-je-waf-alert",
    "enabled": "true",
    "lastUpdatedTime": "2019-03-31T05:15:15.442094Z",
    "provisioningState": "Succeeded",
    "source": {
      "query": "AzureDiagnostics | where ResourceProvider == 'MICROSOFT.NETWORK' and ResourceType == 'APPLICATIONGATEWAYS' and Category == 'ApplicationGatewayFirewallLog'",
      "dataSourceId": "/subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/Microsoft.OperationalInsights/workspaces/qiita201903-dev-je-loganalytics",
      "queryType": "ResultCount"
    },
    "schedule": {
      "frequencyInMinutes": 30,
      "timeWindowInMinutes": 30
    },
    "action": {
      "severity": "3",
      "aznsAction": {
        "actionGroup": [
          "/subscriptions/<subscriptionId>/resourceGroups/qiita201903-dev-je/providers/microsoft.insights/actionGroups/dev-je-actiongroup1"
        ],
        "emailSubject": null,
        "customWebhookPayload": null
      },
      "trigger": {
        "thresholdOperator": "GreaterThan",
        "threshold": 0
      },
      "odata.type": "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.Microsoft.AppInsights.Nexus.DataContracts.Resources.ScheduledQueryRules.AlertingAction"
    }
  }
}
```
# 自動で変換する&LogAnalytics AlertAPIをブロックする
LogAnalyticsワークスペースに対して、`ScheduledQueryRules`を強制するオプションが用意されています。

現時点では、REST APIのみが提供されているようです。

```
PUT /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.OperationalInsights/workspaces/<workspaceName>/alertsversion?api-version=2017-04-26-preview
```
```json:requestbody
{
    "scheduledQueryRulesEnabled" : true
}
```

scheduledQueryRulesEnabledをtrueにしたタイミングで、
`LogAnalyticsAlertAPI`が`ScheduledQueryRules`に変換され、
以降の`LogAnalyticsAlertAPI`の呼び出しがブロックされます。

また、一度ONにした後、OFFとすることはできず、ワークスペースを再作成するしかないようです。

ポータルからアラートを作成する際はすでに`ScheduledQueryRules`を使用しているので、
テンプレートやスクリプトなどで作成する方がシステム側に変換してもらいたいときに使う程度でしょうか。

システム側で変換された`ScheduledQueryRules`は名前が非常に気持ち悪いです。
リソースID:`qiita201903-dev-je-loganalytics|qiita201903-dev-je-waf-search|qiita201903-dev-je-waf-schedule|qiita201903-dev-je-waf-alert`

削除→再作成したほうがきれいな名前が付けられます。


# ARMテンプレート
GitHubにあげてます。

* [リソース類](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/template.json)、[パラメタ](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/parameters.json)
* [Log Analytics Alert API](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/template-SavedSearch.json)、[パラメタ](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/parameters-SavedSearch.json)
* [Scheduled Query Rules API](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/template-ScheduledQuery.json)、[パラメタ](https://github.com/HiroyukiSakoh/QiitaAttachments/blob/master/2019/03/LogAlertARMTemplate/parameters-ScheduledQuery.json)
    * ApplicationInsightsとLogAnalyticsのログアラートが、単一のリソースタイプで記述できて、気持ち良いです。

# ポータルでの見分け方
同じアラートルール名を使えるので、アラートルール一覧では区別がつきません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/260166/38eabf1e-e317-5be4-d50d-ad5c9679de3f.png)

アラート詳細画面に飛ぶと、Descriptionや条件、重要度で区別できると思います。
重要度が3段階のもの(左)はLog Analytics Alert API、5段階のもの(右)はScheduled Query Rules API(右)です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/260166/8149eaaa-798a-054a-a868-3d9e87b2a6f7.png)

# おわりに
アラート周りの仕様もそろそろ落ち着いた気がするので、
使いまわしのきくテンプレートや、スクリプトなどを整備してみてはいかがでしょうか。