6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Azure】Bicepを用いてAzureVMをお手軽に死活監視する。

Posted at

1. はじめに

1-1 ご挨拶

初めまして、井村と申します。
AzureのBicepをもちいてAzureVMのお手軽死活監視を作成しました。

お手軽の意味としては診断設定を利用するのではなく、AzureVMを構築後、自動で取得するVM可用性メトリックを利用します。その為、必須コンポーネントはAzureVMのみになります。
※動作確認用でメール通知しますが、それについてはアラートルール&アクショングループ作ります。

公式ドキュメントにてポータルからポチポチする手順がありますので、それをIaC化しますよって話です。

1-2 対象読者

  • Azureに興味がある
  • Bicepに興味がある

2. 構築

2-1 フォルダ構成

今回作成したBicepファイルは階層型にしています。「main.bicep」ファイルにパラメーターを記述し「module」フォルダ配下にある各モジュールファイルへパラメーターを渡します。

.
├── main.bicep
└── modules
    ├── ag.bicep
    ├── ar.bicep
    └── vm.bicep

2-2 main.bicep構成

利用するBicepテンプレートは以下になります。
Githubにあげてます。

main.bicep
bicep

     1  targetScope = 'subscription'
     2
     3  // Parameters for common
     4  param location string = 'japaneast'
     5  param systemCode string = 'imura5'
     6  param env string = 'dev'
     7
     8  // Parameters for resorce group
     9  param resourceGroupName string = 'rg-${systemCode}-${env}'
    10
    11  // Parameters for virtual machine
    12  param adminUsername string = 'azureuser'
    13  @minLength(12)
    14  @secure()
    15  param adminPassword string
    16
    17  // Parameters for action groups
    18  param emailAddress string = '${systemCode}@sample.com'
    19  param emailReceiversName string = '${systemCode}-${env}'
    20
    21  // deploy resource groups.
    22  resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = {
    23    name: resourceGroupName
    24    location: location
    25  }
    26
    27  // deploy virtual machine.
    28  module vmModule 'modules/vm.bicep' = {
    29    scope: rg
    30    name: 'Deploy_Virtual_machine'
    31    params: {
    32      location: location
    33      systemCode: systemCode
    34      env: env
    35      adminUsername: adminUsername
    36      adminPassword: adminPassword
    37    }
    38  }
    39
    40  // deploy action groups.
    41  module agModule 'modules/ag.bicep' = {
    42    scope: rg
    43    name: 'Deploy_action_groups'
    44    params: {
    45      emailAddress: emailAddress
    46      emailReceiversName: emailReceiversName
    47      env: env
    48      systemCode: systemCode
    49    }
    50  }
    51
    52  // deploy alert rule.
    53  module alModule 'modules/ar.bicep' = {
    54    scope: rg
    55    name: 'Deploy_alert_rule'
    56    params: {
    57      location: location
    58      env: env
    59      systemCode: systemCode
    60      resourceId: vmModule.outputs.id
    61      actionGroupId: agModule.outputs.id
    62    }
    63  }

補足は以下の通りです。

  • 1行目の「target.scope」について今回のファイルはリソースグループを作成するため変更しています。
  • 4行目から19行目の「param」でパラメーターを定義します。
  • 22行目の「resource」でリソースグループを作成します。
  • 28行目以降の「module」で「modules」フォルダの各ファイルへパラメーターを渡します。

2-3 ag.bicep構成

利用するBicepテンプレートは以下になります。
「ag.bicep」ファイルはアクショングループを作成するファイルになります。
今回はメール通知するメールアドレスの設定をします。

ag.bicep
bicep

     1  @description('System code')
     2  param systemCode string
     3
     4  @description('Environment')
     5  param env string
     6
     7  @description('Name of action groups')
     8  param agName string = 'ag-${systemCode}-${env}'
     9
    10  @description('Short name of action groups')
    11  @minLength(1)
    12  @maxLength(12)
    13  param groupShortName string = 'ag-${systemCode}'
    14
    15  @description('Name of email Address')
    16  param emailAddress string
    17
    18  @description('Name of email Receivers')
    19  param emailReceiversName string
    20
    21  resource actionGroup 'Microsoft.Insights/actionGroups@2022-06-01' = {
    22    name: agName
    23    location: 'Global'
    24    properties: {
    25      enabled: true
    26      groupShortName: groupShortName
    27      emailReceivers: [
    28        {
    29          emailAddress: emailAddress
    30          name: emailReceiversName
    31          useCommonAlertSchema: true
    32        }
    33      ]
    34
    35    }
    36  }
    37
    38  @description('action group id')
    39  output id string = actionGroup.id

補足は以下の通りです。

  • 4行目から19行目の「param」でパラメーターを定義します。
  • 21行目の「resource」でアクショングループを作成します。
  • 39行目の「output」でアクショングループのidを「main.bicep」へ渡します。渡す理由としては「ar.bicep」であるアラートルール作成時で利用するためです。

2-4 vm.bicep構成

利用するBicepテンプレートは以下になります。
「vm.bicep」ファイルは仮想マシンを作成するファイルになります。
公式ドキュメントから引用していますが、検証するうえで不要なリソースを削除し、低スペックに置き換えています。

  • 不要なリソース:NSG、パブリックIPアドレス、診断設定用のストレージアカウント、仮想マシンのデータディスク等
  • スペック変更:VMサイズ、OSディスクの種類
vm.bicep
bicep

     1  @description('Location for all resources.')      
     2  param location string
     3
     4  @description('System code')
     5  param systemCode string
     6
     7  @description('Environment')
     8  param env string
     9
    10  @description('Username for the Virtual Machine.')
    11  param adminUsername string
    12
    13  @description('Password for the Virtual Machine.')
    14  @minLength(12)
    15  @secure()
    16  param adminPassword string
    17
    18  @description('The Windows version for the VM. This will pick a fully patched image of this given Windows ver
    19  @allowed([
    20    '2022-datacenter'
    21    '2022-datacenter-azure-edition'
    22    '2022-datacenter-azure-edition-core'
    23    '2022-datacenter-azure-edition-core-smalldisk'
    24    '2022-datacenter-azure-edition-smalldisk'
    25    '2022-datacenter-core'
    26    '2022-datacenter-core-g2'
    27    '2022-datacenter-core-smalldisk'
    28    '2022-datacenter-core-smalldisk-g2'
    29    '2022-datacenter-g2'
    30    '2022-datacenter-smalldisk'
    31    '2022-datacenter-smalldisk-g2'
    32  ])
    33  param OSVersion string = '2022-datacenter-azure-edition-core-smalldisk'
    34
    35  @description('Size of the virtual machine.')
    36  @allowed([
    37    'Standard_B1s' // 02/04/2023 $12.85/month
    38    'Standard_B1ms' // 02/04/2023 $22.78/month
    39    'Standard_B2s' // 02/04/2023 $45.55/month
    40    'Standard_F1' // 02/04/2023 $79.55/month
    41    'Standard_B2ms' // 02/04/2023 $85.41/month
    42  ])
    43  param vmSize string = 'Standard_B1s'
    44
    45  @description('managedDisk Type of osDisk.')
    46  @allowed([
    47    'PremiumV2_LRS'
    48    'Premium_LRS'
    49    'Premium_ZRS'
    50    'StandardSSD_LRS'
    51    'StandardSSD_ZRS'
    52    'Standard_LRS'
    53    'UltraSSD_LRS'
    54  ])
    55  param storageAccountType string = 'Standard_LRS'
    56
    57  @description('Name of the virtual machine.')
    58  param vmName string = 'vm-${systemCode}-${env}'
    59
    60  @description('Name of the network interface.')
    61  var nicName = 'nic-${systemCode}-${env}'
    62
    63  var addressPrefix = '10.0.0.0/16'
    64  var subnetName = 'Subnet'
    65  var subnetPrefix = '10.0.0.0/24'
    66  var virtualNetworkName = 'vnet-${systemCode}-${env}'
    67
    68  resource vn 'Microsoft.Network/virtualNetworks@2021-02-01' = {
    69    name: virtualNetworkName
    70    location: location
    71    properties: {
    72      addressSpace: {
    73        addressPrefixes: [
    74          addressPrefix
    75        ]
    76      }
    77      subnets: [
    78        {
    79          name: subnetName
    80          properties: {
    81            addressPrefix: subnetPrefix
    82          }
    83        }
    84      ]
    85    }
    86  }
    87
    88  resource nic 'Microsoft.Network/networkInterfaces@2021-02-01' = {
    89    name: nicName
    90    location: location
    91    properties: {
    92      ipConfigurations: [
    93        {
    94          name: 'ipconfig1'
    95          properties: {
    96            privateIPAllocationMethod: 'Dynamic'
    97            subnet: {
    98              id: resourceId('Microsoft.Network/virtualNetworks/subnets', vn.name, subnetName)
    99            }
   100          }
   101        }
   102      ]
   103    }
   104  }
   105
   106  resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
   107    name: vmName
   108    location: location
   109    properties: {
   110      hardwareProfile: {
   111        vmSize: vmSize
   112      }
   113      osProfile: {
   114        computerName: vmName
   115        adminUsername: adminUsername
   116        adminPassword: adminPassword
   117      }
   118      storageProfile: {
   119        imageReference: {
   120          publisher: 'MicrosoftWindowsServer'
   121          offer: 'WindowsServer'
   122          sku: OSVersion
   123          version: 'latest'
   124        }
   125        osDisk: {
   126          createOption: 'FromImage'
   127          managedDisk: {
   128            storageAccountType: storageAccountType
   129          }
   130        }
   131      }
   132      networkProfile: {
   135            id: nic.id
   136          }
   137        ]
   138      }
   139      diagnosticsProfile: {
   140        bootDiagnostics: {
   141          enabled: true
   142        }
   143      }
   144    }
   145  }
   146
   147  @description('virtual machine id')
   148  output id string = vm.id

補足は以下の通りです。

  • 2行目から66行目の「param」でパラメーター、「var」で変数を定義します。
  • 68行目の「resource」で仮想ネットワークを作成します。
  • 88行目の「resource」でネットワークインターフェースを作成します。
  • 106行目の「resource」で仮想マシンを作成します。
  • 39行目の「output」で仮想マシンのidを「main.bicep」へ渡します。渡す理由としては「ar.bicep」であるアラートルール作成時で利用するためです。

2-5 ar.bicep構成

利用するBicepテンプレートは以下になります。
「ar.bicep」ファイルはアラートルールを作成するファイルになります。
今回は仮想マシンのVM可用性メトリックの値が1以下の場合に登録メールアドレスにメール通知をする設定になります。

ar.bicep
bicep

     1  @description('Location for all resources.')
     2  param location string
     3
     4  @description('System code')
     5  param systemCode string
     6
     7  @description('Environment')
     8  param env string
     9
    10  @description('Name of alert rule')
    11  param alName string = 'vm-${systemCode}-${env} is down'
    12
    13  @description('Description of alert')
    14  param alertDescription string = 'This is a metric alert'
    15
    16  @description('Severity of alert {0,1,2,3,4}')
    17  @allowed([
    18    0
    19    1
    20    2
    21    3
    22    4
    23  ])
    24  param alertSeverity int = 1
    25
    26  @description('Specifies whether the alert is enabled')
    27  param isEnabled bool = true
    28
    29  @description('Full Resource ID of the resource emitting the metric that will be used for the comparison. For example /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroups/ResourceGroupName/providers/Microsoft.compute/virtualMachines/VM_xyz')
    30  @minLength(1)
    31  param resourceId string
    32
    33  @description('Period of time used to monitor alert activity based on the threshold. Must be between five minutes and one hour. ISO 8601 duration format.')
    34  @allowed([
    35    'PT1M'
    36    'PT5M'
    37    'PT15M'
    38    'PT30M'
    39    'PT1H'
    40  ])
    41  param windowSize string = 'PT1M'
    42
    43  @description('how often the metric alert is evaluated represented in ISO 8601 duration format')
    44  @allowed([
    45    'PT1M'
    46    'PT5M'
    47    'PT15M'
    48    'PT30M'
    49    'PT1H'
    50  ])
    51  param evaluationFrequency string = 'PT1M'
    52
    53  @description('the flag that indicates whether the alert should be auto resolved or not. The default is true.')
    54  param autoMitigate bool = true
    55
    56  param targetResourceType string = 'Microsoft.Compute/virtualMachines'
    57
    58  @description('action group id')
    59  param actionGroupId string
    60
    61  resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
    62    name: alName
    63    location: 'global'
    64    properties: {
    65      criteria: {
    66        'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
    67        allOf: [
    68          {
    69            name: '1st criterion'
    70            metricName: 'VmAvailabilityMetric'
    71            dimensions: []
    72            operator: 'LessThan'
    73            threshold: 1
    74            timeAggregation: 'Average'
    75            criterionType: 'StaticThresholdCriterion'
    76          }
    77        ]
    78      }
    79      description: alertDescription
    80      enabled: isEnabled
    81      evaluationFrequency: evaluationFrequency
    82      scopes: [
    83        resourceId
    84      ]
    85      severity: alertSeverity
    86      windowSize: windowSize
    87      autoMitigate: autoMitigate
    88      targetResourceType: targetResourceType
    89      targetResourceRegion: location
    90      actions: [
    91        {
    92          actionGroupId: actionGroupId
    93        }
    94      ]
    95    }
    96  }

補足は以下の通りです。

  • 2行目から59行目の「param」でパラメーターを定義します。
  • 61行目の「resource」でアラートルールを作成します。
  • 39行目の「output」でアクショングループのidを「main.bicep」へ渡します。渡す理由としては「ar.bicep」であるアラートルール作成時で利用するためです。
  • 67行目から77行目の「allOf」でVM可用性メトリックの値(平均値)の閾値が1以下の場合的な事を記述しています。
  • 82行目のスコープでリソースidを指定します。このidは仮想マシンになります。
  • 90行目のアクションでアクショングループidを指定します。このidはアクショングループになります。

3. 検証

3-1 リソースの構築

下記コマンドを実行します。仮想マシンのログインユーザ名とロケーションを変更します。仮想マシンのログインパスワードを求められますので記述すると構築完了です。

cmd (Azure CLI)
$ ls
main.bicep  modules

$ az login

$ az deployment sub create --template-file main.bicep --parameters adminUsername=<VM login account> --location <Your location>

しばらくすると登録したメールアドレス宛にアクショングループに追加された旨のメールが来ます。

AddActionGroup.png

3-2 動作確認

VM可用性メトリックの値が1であることを確認し、仮想マシンをシャットダウンさせます。

StopVM.png

条件にした閾値を下回ると以下のメールが来ます。
件名や本文中のDescriptionは「ar.bicep」ファイルで指定できます。

Fied1.png

Fied2.png

最後に仮想マシンを起動させ、VM可用性メトリックの値が1に戻ると以下メールが来ます。

Resolved1.png

Resolved2.png

以上で検証は終わりになります。

4. おわりに

本記事を最後まで読んで頂きましてありがとうございます。
設定項目がわかりやすく、とりあえず試してみたい方にはお勧めできるかなと思いました。
ですが実運用するには要注意です。

  • 2023/02/07現在、プレビュー機能であること。
  • アプリのログ、ゲストOS上のパフォーマンス、イベントログは取得できない。

これからも色々と試してみようと思います。

5. 参考記事

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?