はじめに
以前作成した、Azure Automation を利用して VM を自動起動/停止するシステムを構成しました。
今回は、これにエラー通知を実装するする形で紹介しようと思います。
環境
- macOS:
15.0.1
- PowerShell:
7.4.0
実装方法について検討する
ドキュメントなどを確認すると、2種類ほどありそうです。
(他にもありそうですが。)
ざっくりとした手順は下記の通りです。
1. メトリックアラートを利用する方法
- Automation Account 上の「警告」からアラートルールを作成。
- シグナルに
TotalJobs
選択する。 - ディメンションに
Status = Failed
を設定する。 - その他の必要なパラメータを入力する。
2. 診断ログを利用する方法
- Automation Account に診断設定を構成する。
- カテゴリ
JobLogs
を選択し、Log Analytics ワークスペースにログを送信する。 - ログから
ResultStatus = Failed
のジョブを抽出するクエリを実行する - その結果を元にアラートルールを作成する
今回は「2. 診断ログを利用する方法」で実装してみたいと思います。
注意
Azure サービスを利用するため、コストが発生する場合があります。
コストに関しては自己責任でお願いします。
診断設定を構成する
Automation アカウントは作成済として話を進めます。
Log Analytics ワークスペースの作成と診断設定の構成は Bicep を利用して行いたいます。
(この量なら Azure Portal でポチポチしたほうが速そうですが、、、)
Bicep テンプレート
//
// Bicep template to configure diagnostic settings for Azure Automation.
// Created by nownaka.
//
// --------------------------------------------------------------------------------
// Params
// --------------------------------------------------------------------------------
@description('Resource deployment region.')
param location string = resourceGroup().location
@description('Resource name of Azure Automation Account.')
param automationAccountName string
@description('Resource name of Log Analytics Workspace')
param workspaceName string
// --------------------------------------------------------------------------------
// Modules
// --------------------------------------------------------------------------------
/* Azure Automation */
// diagnosticSetting
@description('The confings for diagnosticSetting.')
var _diagnosticSettingConfigs = [{
diagnosticSettingName: 'JobLogs'
logs: [{
category: 'JobLogs'
enabled: true
}]
}]
@description('Diagnostic Setting.')
module diagnosticSettings './modules/diagnosticSettingsWithinAutomationAccount.bicep' = [ for config in _diagnosticSettingConfigs: {
name: 'Deploy-DiagnosticSettings-${config.diagnosticSettingName}'
params: {
scopeResourceName: automationAccountName
diagnosticSettingName: config.diagnosticSettingName
logs: config.logs
workspaceId: workspace.outputs.resourceId
}
}]
/* Log Analytics Workspace */
module workspace './modules/workspaces.bicep' = {
name: 'Deploy-LogAnalyticsWorkspace'
params: {
workspaceLocation: location
workspaceName: workspaceName
}
}
//
// https://learn.microsoft.com/ja-jp/azure/templates/microsoft.operationalinsights/workspaces?pivots=deployment-language-bicep
// Created by nownaka.
//
// --------------------------------------------------------------------------------
// Params
// --------------------------------------------------------------------------------
@description('Resource name of Log Analytics Workspace.')
param workspaceName string
@description('Resource deployment region.')
param workspaceLocation string
@description('Resource tags.')
param tags object = {}
@description('The SKU of the workspace.')
@allowed([
'CapacityReservation'
'LACluster'
'PerGB2018'
'PerNode'
'Premium'
'Standalone'
'Standard'])
param workspaceSkuName string = 'PerGB2018'
// --------------------------------------------------------------------------------
// Resources
// --------------------------------------------------------------------------------
@description('Log Analytics Workspace.')
resource workspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: workspaceName
location: workspaceLocation
tags: tags
properties: {
sku: {
name: workspaceSkuName
}
}
}
// --------------------------------------------------------------------------------
// Outputs
// --------------------------------------------------------------------------------
@description('Resource name of Log Analytics Workspace.')
output workspaceName string = workspace.name
@description('Resource Id of Log Analytics Workspace.')
output resourceId string = workspace.id
//
// Reference: https://learn.microsoft.com/ja-jp/azure/templates/microsoft.insights/diagnosticsettings?pivots=deployment-language-bicep#metricsettings-1
// Created by nownaka.
//
// --------------------------------------------------------------------------------
// Params
// --------------------------------------------------------------------------------
@description('Name of the scoped resource')
param scopeResourceName string
@description('')
param diagnosticSettingName string
@description('The resource Id for the event hub authorization rule.')
param eventHubAuthorizationRuleId string?
@description('The name of the event hub. If none is specified, the default event hub will be selected.')
param eventHubName string?
@description('A string indicating whether the export to Log Analytics should use the default destination type.')
@allowed(['Dedicated'])
param logAnalyticsDestinationType string?
@description('The list of logs settings.')
param logs {
category: string?
categoryGroup: string?
enabled: bool
retentionPolicy: {
days: int
enabled: bool
}?
}[] = []
@description('The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.')
param marketplacePartnerId string?
@description('The list of metric settings.')
param metrics {
category: 'string'
enabled: bool
retentionPolicy: {
days: int
enabled: bool
}
timeGrain: 'string'
}[] = []
@description('The service bus rule Id of the diagnostic setting. This is here to maintain backwards compatibility.')
param serviceBusRuleId string?
@description('The resource ID of the storage account to which you would like to send Diagnostic Logs.')
param storageAccountId string?
@description('The full ARM resource ID of the Log Analytics workspace to which you would like to send Diagnostic Logs. ')
param workspaceId string?
// --------------------------------------------------------------------------------
// Resources
// --------------------------------------------------------------------------------
// Replace {resource type} according to the scoped resource.
@description('Scoped resource')
resource scope 'Microsoft.Automation/automationAccounts@2023-11-01' existing = {
name: scopeResourceName
}
@description('diagnosticSettings.')
resource diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: diagnosticSettingName
scope: scope
properties: {
eventHubAuthorizationRuleId: eventHubAuthorizationRuleId
eventHubName: eventHubName
logAnalyticsDestinationType: logAnalyticsDestinationType
logs: logs
marketplacePartnerId: marketplacePartnerId
metrics: metrics
serviceBusRuleId: serviceBusRuleId
storageAccountId: storageAccountId
workspaceId: workspaceId
}
}
// --------------------------------------------------------------------------------
// Outputs
// --------------------------------------------------------------------------------
output scope string = scope.id
依存関係:
パラメータの設定
値は適宜青木換えて利用します。
using './main.bicep'
param automationAccountName = '{your automation account name}'
param workspaceName = 'your new automation account name'
リソースデプロイ
下記コマンドを実行してリソースをデプロイします。
コマンド実行は各種ファイルが存在するルートディレクトリで行ってください。
変数の設定:
# 変数の設定
resourceGroupName={your resource group name} # デプロイするリソースグループの名前
Azure ログイン:
# ログイン
az login
デプロイ:
# デプロイ
az deployment group create \
--name 'Deploy_VMAutoStartStop' \
--resource-group $resourceGroupName \
--template-file './main.bicep' \
--parameters './main.bicepparam'
デプロイ結果:
下記のようになっていればOKです。
アラートの構成
アラートルールも Bicep でできそうでしたが、力尽きたのでこれは Azure Portal から設定していきます。
ログ検索を実行する
まずは失敗したログを抽出するクエリを実行します。
(この時点では何も表示されなくてもOKです。)
クエリ:
AzureDiagnostics
| where Category == 'JobLogs'
| where ResultType == 'Failed'
[監視] > [ログ] で実行できます。
右上の [新しいアラートルール] からアラートルールを作成していきます。
アラートルール作成
[条件] にさきほどのクエリが反映されています。
今回はしきい値は「0」に設定します。
アクショングループなど通知先の設定は適宜行ってください。
以上で実装は完了です!
実際に試してみる
テスト用 Runbook の作成
ローカルに Test-Alert.ps1
を作成し、Automation Account にインポートします。
スクリプト:
# ============================================================================
# アラート通知設定を確認するためスクリプト
# Created by nownaka.
# ============================================================================
# エラーを発生させるかどうかのフラグ
param(
[Parameter(Mandatory=$true)]
[Boolean]$isError
)
Write-Output "Start!"
if($isError -eq $true) {
throw "Error!"
}
Write-Output "Successful!"
インポート手順:
[プロセスオートメーション] > [Runbook] > [Runbook のインポート]
インポートが完了したら、発行(公開)します。
テスト用 Runbook の実行
先ほど作成した Runbook を実行します。
エラーを吐かせるため、入力パラメータは True
を選択します。
通知確認
下記のようなメールが通知さればOKです。
さいごに
Azure Automation でジョブ失敗時に通知を受け取る方法を紹介しました。
Bicep を使ってかえって時間がかかってしまったような気がしますがやりたいことはできたので良しとします。
最後まで見ていただきありがとうございました。
誰かの役に立てば幸いです。
参考