Microsoft Defender for Cloud / Azure Policy のエラーをチェックする

# 1. はじめに
前回、[**「Microsoft Defender for Cloud / Azure Policy が何時動作しているのかを見極める」編**](https://qiita.com/hisnakad/items/cdc3f54e10efae50e63d)で Azure Policy が何時動作しているのか、記録をチェックする方法を紹介しましたが、Azure Policy のエラーについて取り上げられなかったので、追加で投稿したいと思います。

# 2. Azure Policy のエラーとは？
Microsoft Defender for Cloud では、コンプライアンスチェックの動作(推奨事項や規制コンプライアンス）において、Azure Policy が活用されていますが、エラーが生じる可能性もあります。
Azure Policy のエラーについては、公式ドキュメントに記載があります。

 - [Azure Policy の使用に関するエラーをトラブルシューティングする]
(https://docs.microsoft.com/ja-jp/azure/governance/policy/troubleshoot/general)

エラーが発生する可能性としては、ポリシーの割り当て拒否（権限など）や、テンプレートの構文エラーなどが有りそうです。
これらの検知を Microsoft Defender for Cloud がアラートなどで挙げてくれば良いのですが、MDfC 側ではあくまで「非準拠」のアラート通報に特化しているため、Azure Policy にエラーが発生していないかどうかの確認は運用では別途検討した方が良さそうです。

# 3. どうやって確認するのか？ - LogAnalytics でエラーをクエリーしてみる
Azure Policy のステータスは LogAnalytics に出力される Azure Activity Log にて出力されます。
前回も取り上げましたが、Azure Policy が定期的にチェックされて問題が無い場合 (Audit) は、Activity Log には出力されません。
新規に追加されたリソースや、構成変更が発生したリソースについては Activity Log に出力される仕様となっています。
LogAnalytics ワークスペースより、Kusto クエリーを用いて確認してみましょう。

## 3.1 Azure Policyでフィルタする
LogAnalytics より、Azure Policy のアクティビティをフィルタしてみます。

```KQL
AzureActivity | where CategoryValue == "Policy"
```

![20210816_LogAnalytics_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/d7315933-0f18-f27e-3d6c-9c1966b31f07.png)

Azure Policy の Activity Log への出力結果が分かります。
Activity Log の各種カラムの説明は公式ドキュメントに記載があります。
- [AzureActivity](https://docs.microsoft.com/en-us/azure/azure-monitor/reference/tables/azureactivity)

ステータス情報として活用できるフィールドとして、`ActivityStatusValue` が使えるようです。

| カラム | タイプ | 内容 |
| ---- | ---- | ---- |
|ActivityStatusValue|string|Status of the operation in display-friendly format. Common values include **Started, In Progress, Succeeded, Failed, Active, Resolved.**|

## 3.2 ActivityStatusValue で Group 化する
Kusto クエリーを用いて、Azure Policy のステータスを Group By してみます。
ActivityStatusValue は JSON フィールド `Properties` に含まれているため、parse_json で抽出します。

```sql
AzureActivity | where CategoryValue == "Policy" 
| extend d=parse_json(Properties) // parse_json で読み込み
| extend activityStatusValue = tostring(d["activityStatusValue"]), resource = tostring(d["resource"]), resourceProviderValue = tostring(d["resourceProviderValue"])
| extend policyDefinitionDisplayName_ = tostring(parse_json(tostring(Properties_d.policies))[0].policyDefinitionDisplayName)
| summarize Total=count() by policyDefinitionDisplayName_,activityStatusValue
```
![20210816_LogAnalytics_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/fe2c3d27-09ef-41f3-f059-0dc07630463e.png)

このクエリーでは、Azure Policyで用いているポリシー名も抽出してグループ化することで、どのポリシーがどのようなステータスになっているかを表示しています。ここで `ActivityStatusValue`が **Failure** になっているものが無いか確認してみましょう。

## 3.3 ActivityStatusValue が Failure になっているルールを抽出する
フィルタ条件を使って、Failure になった Azure Policy を抽出してみます。
ここでは errorMessage フィールドを用いて Failure になった際の情報を抽出し、対象のリソースなどを JSON 部分から抜いています。

```sql
AzureActivity | where CategoryValue == "Policy" 
| extend d=parse_json(Properties) // parse_json で読み込み
| extend e=parse_json(Properties_d) // parse_json で読み込み
| extend activityStatusValue = tostring(d["activityStatusValue"]), resource = tostring(d["resource"]), resourceProviderValue = tostring(d["resourceProviderValue"])
| extend policyDefinitionDisplayName_ = tostring(parse_json(tostring(Properties_d.policies))[0].policyDefinitionDisplayName)
| extend errorMessage = tostring(e["errorMessage"])
| where activityStatusValue == "Failure"
| project TimeGenerated,policyDefinitionDisplayName_,activityStatusValue,errorMessage,resource,resourceProviderValue
```
![20210816_LogAnalytics_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/54829e4d-7fbe-f8ae-6f77-cb2e29dac7ff.png)

ここで errorMessage を解読すると、`auditifNotExits`エフェクトによって、Audit を実施しようとしたものの、GET のパーミッションが無いためエラーになったようです。この対象のリソースなどを追って、原因を確認することができるようになりました。

いかがでしょうか？ `errorMessage` が分かると、Policy が適用できなかった原因が確認し易くなると思います。
ここまでくれば、実際に Azure Policy が失敗した際の理由、対象リソースなどを LogicApp などを用いて通知を行い、運用チェックなどに用いることが出来そうですね。

# 4. まとめ
Microsoft Defender for Cloud や、Azure Policy などでセキュリティ運用を始めた際に、エラーチェックなどを気にされている方は Azure Activity Log を用いてエラーチェックする手法でした。どなたかの参考になれば幸いです。

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。