AzureVMで死活監視を実装してみた(DCRとAzure Monitor アラート)

Azure AzureMonitor
この記事は約16分で読めます。

AzureVMで死活監視を実装してみました。

AzureMonitorAgentを利用して死活監視するのが主流ですが、具体的にどう設定すればいいのかMicrosoftのドキュメントを読んでもパッと分からなかったので実際に設定してみました。

データ収集ルール(DCR)Azure Monitor アラートを組み合わせることで死活監視を実装できます。

広告

1.AzureVMで死活監視を実装する

1-1.準備

まず以下のリソースを作成しておきます。

  • 仮想マシン(AzureVM)
  • LogAnalytics

仮想マシンはWindowsOSで作成してheartbeatログを出す用途で利用します。

LogAnalyticsはログの確認に利用します。

それぞれのリソースはAzureCLIで簡単に作成できます。

1-2.データ収集ルール(DCR)を作成する

Azureポータルでも作成できますが、ここではAzureCLIを利用して作成します。

今回は死活監視でheartbeatログを出力させたいのでWindowsのイベントログを収集するルールを作成します。

1-2-1.DCRのJSON定義ファイルの準備

まずDCR作成用のJSONの定義ファイルを準備します。

下記にサンプルを用意したので以下の2項目だけ修正して保存します。

  • workspaceResourceId
  • workspaceId

この2項目は az monitor log-analytics workspace show で取得した項目の idcustomerId に該当します。

 # ID情報取得コマンドの例
$ws_info = az monitor log-analytics workspace show -g $rg_name -n $ws_name | ConvertFrom-Json
$ws_rid = $ws_info.id  ## → workspaceResourceId
$ws_id = $ws_info.customerId  ## → workspaceId
{
    "properties": {
        "dataSources": {
            "windowsEventLogs": [
                {
                    "streams": [
                        "Microsoft-Event"
                    ],
                    "xPathQueries": [
                        "Application!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]",
                        "Security!*[System[(band(Keywords,13510798882111488))]]",
                        "System!*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)]]"
                    ],
                    "name": "eventLogsDataSource"
                }
            ]
        },
        "destinations": {
            "logAnalytics": [
                {
                    "workspaceResourceId": "<ワークスペースのリソースID>",
                    "workspaceId": "<ワークスペースID>",
                    "name": "LogAnalytics"
                }
            ]
        },
        "dataFlows": [
            {
                "streams": [
                    "Microsoft-Event"
                ],
                "destinations": [
                    "LogAnalytics"
                ],
                "transformKql": "source",
                "outputStream": "Microsoft-Event"
            }
        ]
    }
}

1-2-2.DCRを作成する

JSONの準備ができたらDCRを作成します。

JSONファイルがあるパスの情報だけ適宜書き換えます。

また、コマンドの最後で対象VMに対して AzureMonitorWindowsAgent の拡張機能をインストールします。

AzureCLIでDCRを作成すると自動でAgentがインストールされないからです。
 ※AzureポータルでDCRを作成してVMと関連付けた場合にはVMに自動でインストールされます。

 # パラメータの定義
$dcr_name = "test-dcr"
$association_name = "test_as"
$file_path = "<JSONファイルのパス>"

 #DCRの作成 
az monitor data-collection rule create `
 -g $rg_name `
 --location "japaneast" `
 --name $dcr_name `
 --rule-file $file_path

 # DCRのID取得(DCR作成後)
$dcr_info = az monitor data-collection rule show -g $rg_name -n $dcr_name | ConvertFrom-Json
$dcr_id = $dcr_info.id

 # VMのID取得
$vm_name = "VM-Test-Windows"
$vm_info = az vm show -g $rg_name -n $vm_name | ConvertFrom-Json
$vm_id = $vm_info.id

 # DCRの関連付け
az monitor data-collection rule association create `
 -n $association_name `
 --resource $vm_id `
 --rule-id $dcr_id

 # VMに対して拡張機能のインストール
az vm extension set `
 --subscription TestSub02 `
 --resource-group $rg_name `
 --vm-name $vm_name `
 --name AzureMonitorWindowsAgent `
 --publisher Microsoft.Azure.Monitor
参考ドキュメント(コマンドリファレンスなど)

1-2-3.Heartbeatログの出力確認

LogAnalyticsでHeartbeatログを確認します。

$ws_info = az monitor log-analytics workspace show -g $rg_name -n $ws_name | ConvertFrom-Json
$ws_id = $ws_info.customerId

 # クエリ実行コマンド 
$result = az monitor log-analytics query -w $ws_id  --analytics-query "Heartbeat | where TimeGenerated >= ago(30m)" | ConvertFrom-Json
$result | Format-Table -Property TimeGenerated, Computer
実行結果(Heartbeatログの確認)
PS C:\> $result = az monitor log-analytics query -w $ws_id  --analytics-query "Heartbeat | where TimeGenerated >= ago(30m)" | ConvertFrom-Json
PS C:\> $result | Format-Table -Property TimeGenerated, Computer

TimeGenerated                Computer
-------------                --------
2025-08-26T07:01:08.6538434Z VM-Test-Windows
2025-08-26T07:02:08.6606775Z VM-Test-Windows
2025-08-26T07:00:08.6441802Z VM-Test-Windows
2025-08-26T07:03:08.6689546Z VM-Test-Windows
2025-08-26T07:04:08.6770638Z VM-Test-Windows
2025-08-26T07:05:08.6933919Z VM-Test-Windows


PS C:\>

これでLogAnalyticsにHeartbeatログが出るようになりました。

[参考] AzureMonitorAgentインストールの通信要件

AzureポータルでDCRを作成した際に自動でインストールされる、もしくはAzureCLIで能動的にインストールするVMエージェントは、NSGで送信をAlldenyにしてた状態でもインストールはできました。

なのでAzureポータルの操作に制限がかかっていない限りはインストールはできそうです。

※「Azureポータルの操作に制限」とはIAMの権限不足や、Azureポータルを操作している端末自体にURLフィルタがかかっており、デプロイができない状態のことを指しています。

1-3.Azure Monitor アラートを作成する

次に死活監視のAzure Monitor アラートを作成します。

今回は、5分間heartbeatがログで出ていなければ指定したメールアドレス宛に通知する というアラート設定にします。

 # パラメータの定義
$rg_name = "RG-Test-VM"
$ws_name = "Test-la"
$ws_info = az monitor log-analytics workspace show -g $rg_name -n $ws_name | ConvertFrom-Json
$ws_rid = $ws_info.id
$actiong_name = "testactiongroup"
$condition = "count 'result' > 0"
$email = "hogehoge@hogehoge.com"
$alert_name = "AliveMonitoring"

 # アクショングループの作成
az monitor action-group create `
 -n $actiong_name `
 -g $rg_name `
 --action email admin $email

 # アクショングループのリソースID取得
$ag_info = az monitor action-group show -n $actiong_name -g $rg_name | ConvertFrom-Json
$ag_id = $ag_info.id

 # アラートの作成
az monitor scheduled-query create `
    --name $alert_name `
    --resource-group $rg_name `
    --scopes $ws_id `
    --action-groups $ag_id `
    --window-size 60m `
    --evaluation-frequency 5m `
    --severity 0 `
    --condition $condition `
    --condition-query result="Heartbeat | where Computer == 'VM-Test-Windows' | extend JapanTimeStamp = TimeGenerated + 9h | summarize Lastcall = max(JapanTimeStamp) by Computer | where Lastcall <= (ago(15m) + 9h)"

アラート作成が完了すれば死活監視の設定完了です。

参考ドキュメント(コマンドリファレンス)

1-4.アラートメールを受領する

仮想マシンが停止すると「Alert ’・・・’ was fired」というメールが届きます。
 ※今回は仮想マシンをAzureポータル上から停止してアラートが来るかどうかを試しました。

アラートの条件(死活監視)を満たしたときに届くアラートメール

復旧したときには「Alert ’・・・’ was resolved」という復旧メールも届きます。

仮想マシンが復旧したときに届くアラートメール

通知されるメールの件名はカスタマイズできなさそうでした。

2.[参考] 通信要件について

AzureMonitorAgentを利用してAzureVMを死活監視する際の通信要件についてもまとめてみました。

受信の制限はなさそうなので、仮想マシンに対する送信制限の観点で調べました。

2-1.NSGで送信制限をかけている場合

NSGで送信制限をかけている場合には、サービスタグでの許可設定が必要です。

必要なサービスタグは2つです。

  • AzureMonitor
  • AzureResourceManager

AzureMonitor の他に AzureResourceManager も必要になることに注意です。

: Azure Monitor エージェントの場合、AzureResourceManager も必要です。 

https://learn.microsoft.com/ja-jp/azure/virtual-network/service-tags-overview#available-service-tags

必要ポートについてはMicrosoftのドキュメントを見ても特に明確に定義されていないように見えますので、可能であればanyで開け、絞りたいのであれば 80,443 だけを許可して様子を見るのが良いと思います。

以下、AzureMonitorAgentの通信要件に関して参考となるMicrosoftのドキュメントです。

Azure Monitor エージェントのネットワーク構成 - Azure Monitor
ネットワーク設定を定義して、Azure Monitor エージェントのネットワークの分離を有効にする方法について説明します。
Azure Monitor エンドポイントのアクセスとファイアウォールの構成 - Azure Monitor
ファイアウォール規則を構成し、エンドポイント のアクセス要件を理解することで、Azure リソースが Azure Monitor に接続できることを確認します。

2-1-1. 必要なポートについての補足(80,443許可のみでログは出るようになる)

今回は80,443のみを許可して設定しましたが、正常にログがAzureMonitorに連携され、LogAnalyticsでログ検索できることを確認しました。

サービスタグのAzureMonitorとAzureResourceManagerを送信ルールで許可する

しかし、プロキシを通るように設定した仮想マシンで試したところ、プロキシで全ての通信をDenyしてもLogAnalyticsでheartbeatログが確認できたので、Agentの通信経路や何のプロトコルで通信されているのかは分かりませんでした。

詳細に調査する場合には、AzureFWなどで通信をすべて見る、そして制御もAzureFWで実施するしかないと思います。

[参考] AzureCLIでのサービスタグの設定追加コマンド(NSGの送信規則にルール追加)

参考までにNSGで AzureMonitorAzureResourceManager の通信要件を追加するコマンドも載せておきます。

 # パラメータの定義
$rg_name = "RG-Test-VM"
$nsg1_name = "NSG-Test-Windows"
$nsgrule_name_monitor = "AllowToAzureMonitorOutBound"
$nsgrule_name_ARM = "AllowToAzureResourceManagerOutBound"

 # NSGのルール追加(サービスタグ)
az network nsg rule create `
 -g $rg_name `
 --nsg-name $nsg1_name `
 -n $nsgrule_name_monitor `
 --destination-address-prefixes "AzureMonitor" `
 --destination-port-range "*" `
 --direction "Outbound" `
 --priority 300

az network nsg rule create `
 -g $rg_name `
 --nsg-name $nsg1_name `
 -n $nsgrule_name_ARM `
 --destination-address-prefixes "AzureResourceManager" `
 --destination-port-range "*" `
 --direction "Outbound" `
 --priority 310

2-2.プロキシを利用している場合

上記で述べた通り、AzureMonitorAgentの通信がそもそもプロキシを経由しないように見えるため、プロキシでの制御はできない可能性が高いです。

制御するのであれば、ルートテーブルで全ての通信をAzureFWなどのNW機器に集約して全ての通信を制御する必要がありそうです。