【Azure】ApplicationGatewayバックエンドプールで異常が発生した際にどのバックエンドに異常が発生したのかわかるようにする

# 1.はじめに

タイトルが長いっ！！！

ApplicationGateweayは負荷分散装置ですが、バックエンドプールに異常が発生した場合、メトリックを監視しておくことでアラートを出すことができます。
ただし、アラートでは__どのバックエンドプールに異常があったか__はわかるのですが、__具体的にどのバックエンドに異常があったのかはわかりません。__
そのため、調査をしようとすると、バックエンドのログを調べないとわからず、調査に時間がかかります。~~VMにログインするのだるい~~

はい、というわけで、ApplicationGatewayで異常が発生した場合、メトリック監視でアラートを出し、合わせてバックエンド正常性をログとして記録します。


#2.一言で書くと

- ApplicationGatewayはメトリックで不通になったバックエンド情報をもっていないので不便。どのバックエンドプールに異常があったのかはわかるが、具体的にはわからない
- メトリック[UnHealthy host count]が増加したタイミングで、Automationでバックエンド正常性を取得、ストレージアカウントに格納。

# 3.Application Gatewayの正常性監視

ApplicationGateweayでは、Potal上やコマンドでバックエンドの正常性を確認することができます。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/1b610760-d03c-bf76-f22f-5e44d8a4a740.png)|
|:--|

サーバー(バックエンドプール):バックエンドに登録したあるサーバなど。
ポート(HTTP設定):利用しているポート。
状態:バックエンドの状態を示す。
詳細:そのバックエンドの状態の詳細。エラー時は何故エラーになっているか表示される。

しかしながら、これはメトリックとしては保存できず、その場その場でのみのデータです。
メトリックとしては、__「どのバックエンドプールに異常があったか」__のみ記録されます。
バックエンドプールは同じ分散を行うバックエンドをグループ化したものなので、具体的にどのバックエンドなのかまではわかりません。

深夜にApplicationGateweayのバックエンドで異常が発生する　⇒　アラートが発報される　⇒　すぐに解決する　⇒　次の日どのVMに異常があったかわからない　⇒　あたりをつけて調査
っていうことになってしまいます。

そこで、__アラートをトリガーとしてAutomationを動かし、バックエンド正常性の項目を出力しストレージアカウントにログとして保存します__。
これでログを見れば、具体的にどのバックエンドなのかわかるようになります。

# 4.構成

今回の構成はこんな感じ。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/ecb8c8ca-4efd-947c-20fc-c585986512db.png)
|:--|

①ApplicationGatewayのバックエンドが異常状態になると、
②ApplicationGatewayのメトリック監視で、[UnHealty host count]が増加したタイミングにアラートを出します。③アラートに合わせて、メールを送付します。
③アラートをトリガーにしてAzureAutomationを実行し、④ApplicationGatewayの正常性監視結果を取得します。
⑤その後、ストレージアカウントに書き込んだログファイルを格納します。

# 5.Azure Automationの設定
すでにApplication GateweayとApp Serviceとストレージアカウントはすでに構築されているものとして、まずAutomationの設定を行います。
__「Automation アカウント」__を開き、適当にAutomationアカウントを作成します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/822744e8-0607-c307-b391-8c025f3d183e.png)|
|:--|

「モジュール」を開き、モジュールのバージョンを更新します。
また、合わせて__「Az.Accounts」「Az.Network」「Az.Storage」__をインポートします。
(更新のやり方とAZモジュールのインポート方法はこちら⇒[https://qiita.com/motomiya_hikaru/items/ecc080c61c8b185af2de] に。)

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/36735214-d874-9886-90e8-c83fa229c898.png)|
|:--|

Runbookの作成を選択し、PowerShellのRunbookを適当に作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/3cb76f50-90a3-82b9-1e1f-e5e99a2af161.png)

編集画面が開くので、次のPowerShellコマンドを入れます。
アカウント認証部分は、
https://qiita.com/sakamichihassin/items/736f07c53f86f76b1263 の記事に記載されていた内容を使わせてもらいました。ありがとうございます。

```PowerShell
# Automationアカウントの接続名(既定名の場合)
$connectionName = "AzureRunAsConnection"

# AzureRMContextでセッションが残っているとAzコマンドが使えないため念の為セッション継続を無効にしておく
Disable-AzContextAutosave –Scope Process

$conn = Get-AutomationConnection -Name $connectionName
Connect-AzAccount -ServicePrincipal -Tenant $conn.TenantID `
-ApplicationId $conn.ApplicationID -CertificateThumbprint $conn.CertificateThumbprint

$AzureContext = Select-AzSubscription -SubscriptionId $conn.SubscriptionID

#Applicationgatewayのバックエンドヘルスの監視結果を取得。
$agwhealth = Get-AzApplicationGatewayBackendHealth `
                -Name "Applicationgateway" `
                -ResourceGroupName "Applicationgateway"

#日付・ファイル名設定
$todaydate = Get-Date -Format yy-MM-dd-HH-mm-ss
$filename = "ApplicationgatewayHealth-$todaydate.log" 
$LogItem = New-Item -ItemType File -Name $filename

$agwhealth | Out-File -FilePath $filename -Append

#ストレージアカウントのアクセスキーを取得
$storagekey = (Get-AzStorageAccountkey `
                  -ResourceGroupName "Applicationgateway" `
                  -Name "agwhealth").Value[0]

#コンテキストの作成
$storageContext = New-AzStorageContext `
                     -StorageAccountName "agwhealth" `
                     -StorageAccountKey $storagekey

#ストレージアカウント(のApplicationgatewayという名のコンテナ)に格納
Set-AzStorageBlobContent `
   -File $filename `
   -Container "applicationgateway" `
   -BlobType "Block" `
   -Context $storageContext `
   -Verbose

```
できたら公開します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/3204a7e8-2e92-e143-3350-c0456820e3a3.png)|
|:--|

# 6.アラートの設定

次にアラートを設定していきます。
「モニター」　⇒　「アラート」を開き、__「新しいアラートルール」__を選択。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/22a4d489-3186-8177-1551-dcd3caceb106.png)|
|:--|

スコープをApplicationgatewayにし、__「UnHealthy host count」が1以上の場合にアラートを出すように設定します。__

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/87dfe217-25c4-3137-803f-4cb9bd0399f9.png)|
|:--|

アクションとして、自分にメールを出すのと、先ほど作成した__「ApplicationgatewayHealthcheck」__のRunbookを実行するように指定します。
アラートルールなどを設定し、作成します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/3e7623b7-2bcf-4187-e7f8-fe8408607e82.png)|
|:--|


これで設定完了です！

# 7.動作確認

では早速動作確認。
Applicationgatewayのバックエンドで、強制的にエラーを出してみます。
今回は、正常性プローブのポート設定を、「80」から「81」に変更しました。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/1948f7ac-4443-f7eb-e82f-1eab67f39621.png)|
|:--|

バックエンド正常性を確認すると…

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/78772931-bb94-7053-b82c-4f7c66039d38.png)|
|:--|

はい、ちゃんと__「異常」__になってますね。

すると、アラートが飛びます。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/522459cd-8bf4-a531-345f-9986cf65f34c.png)|
|:--|

同時にAutomationが走り…ストレージアカウントを見てみると、ちゃんとログファイルが保存されていました！

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/519789e2-c3fd-adfe-c5d5-0e1037975d52.png)|
|:--|

ダウンロードして中身を見てみると、ちゃんとバックエンド情報が記録されていました！

```log
BackendAddressPools     : {Microsoft.Azure.Commands.Network.Models.PSApplicationGatewayBackendHealthPool}
BackendAddressPoolsText : [
                            {
                              "BackendAddressPool": {
                                "Id": "/subscriptions/                         /resourceGroups/Applicationgat
                          eway/providers/Microsoft.Network/applicationGateways/Applicationgateway/backendAddressPools/po
                          ol"
                              },
                              "BackendHttpSettingsCollection": [
                                {
                                  "BackendHttpSettings": {
                                    "TrustedRootCertificates": [],
                                    "Id": "/subscriptions/                        /resourceGroups/Applicatio
                          ngateway/providers/Microsoft.Network/applicationGateways/Applicationgateway/backendHttpSetting
                          sCollection/http"
                                  },
                                  "Servers": [
                                    {
                                      "Address": "agw-test.azurewebsites.net",
                                      "Health": "Unhealthy"
                                    }
                                  ]
                                }
                              ]
                            }
                          ]

```

>"Address": "agw-test.azurewebsites.net",
>"Health": "Unhealthy"

と記載されているので、__「"agw-test.azurewebsites.net"が"Unhealthy"なんだなー」__ということがわかります。

# 9.おわりに

今回はApplicationgatewayの正常性チェックが少し足りないので、自分で足してみた、という感じでした。
~~めんどくさがらずに~~SendGirdを設定すればAutomationでMailを送ることもできます！

AzureAutomationを触り始めたときはこんなの実装できないんじゃないか？と思ったものですが、3日ぐらい考えたらいけました。
Azureは頑張れば結構なんでもできますね。

## 参考
[Azモジュールを使ったAzure Automation Runbookの記述方法](https://qiita.com/sakamichihassin/items/736f07c53f86f76b1263)
https://qiita.com/sakamichihassin/items/736f07c53f86f76b1263

[Runbook からメールを送信する](https://docs.microsoft.com/ja-jp/azure/automation/automation-send-email)
https://docs.microsoft.com/ja-jp/azure/automation/automation-send-email

[Azure Automation Runbook をトリガーするアラートを使用する](https://docs.microsoft.com/ja-jp/azure/automation/automation-create-alert-triggered-runbook)
https://docs.microsoft.com/ja-jp/azure/automation/automation-create-alert-triggered-runbook

[Application Gateway のバックエンドの正常性および診断ログ](https://docs.microsoft.com/ja-jp/azure/application-gateway/application-gateway-diagnostics)
https://docs.microsoft.com/ja-jp/azure/application-gateway/application-gateway-diagnostics