Azure Automationを使用して、Azure Backupを1日に複数回自動実行する②

#背景
　[前回の記事](https://qiita.com/y447093040/items/1774d8ef5a9e71d837c4)と同様にAzure Backupを1日に複数回実行する方法が無いかと試行錯誤した結果、別の方法に思い至ったので記事にすることにしました。今回もAzure Automationを使用します。

#方針
　まずは、実現方針について簡単に説明します。当たり前と言えば当たり前の話なのですが、Azure Backupの検証を進めていると次の点に気づきました。
　一度バックアップアイテムに関連づけたバックアップポリシーについて、バックアップアイテムとバックアップポリシーの関連付けを解除せずにバックアップのスケジュール時刻だけを変更すると、変更後のスケジュールでバックアップが取得されるということです。

　例えば、バックアップポリシーのスケジュールを午前5時に設定し、午前5時～6時の間にスケジュールを午前6時に変更すれば、スケジュール変更を実施した日については午前5時と午前6時の2回バックアップを取得することができます。

　この仕様を利用しバックアップポリシーのスケジュールを変更するPowerShellコマンドをAzure Automationを用いて定期実行することで1日に複数回のバックアップを自動実行することが出来るのではないかと考え検証しました。

　今回の検証の具体的なスケジュールは以下とします。

1.Azure Backupのスケジュールバックアップ：初回は午前0時としその後2時間毎
2.Azure Automation Runbookのスケジュール：初回は午前1時としその後2時間毎

　従って処理開始直後のサイクルは以下となります。

午前0時：スケジュールバックアップ
午前1時：Azure Automationによりバックアップポリシーのスケジュールを午前2時に変更
午前2時：スケジュールバックアップ
午前3時：Azure Automationによりバックアップポリシーのスケジュールを午前4時に変更
午前4時：スケジュールバックアップ

<以後、繰り返し>

#事前準備
　以下のリソースを事前に作成する必要が有ります。今回も前提としてバックアップ対象はAzure仮想マシンとします。

- Revocery Services コンテナー
- バックアップ対象仮想マシン
- Azure Automation Account

　このうち、バックアップ対象仮想マシンについては、Recovery Services コンテナーにてバックアップポリシーを関連付け、自動バックアップが取得される状態にしておく必要が有ります。バックアップポリシーのスケジュールは日単位で午前0時とします。

　以下のようにバックアップポリシーのスケジュールを設定します。
![cap02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531201/b0c07eb0-9f0e-1002-adc3-ce51aebb65f4.png)

　更に、バックアップポリシーにバックアップ対象仮想マシンが関連付けられていることを確認します。
![cap03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531201/d0c069a1-b42d-33e2-5af2-d5b7d0c6afac.png)

#実行コマンド
　続いて、Azure AutomationのRunbookに記載するPowerShellスクリプトを以下に記載します。今回、Azure PowerShellのModuleはAzモジュールとします。(実行コマンドについては、[こちら](https://docs.microsoft.com/ja-jp/azure/backup/backup-azure-vms-automation#change-policy-for-backup-items)を参照しました。)

```
##Azureへログイン
$connectionName = "AzureRunAsConnection"
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         

Login-AzAccount `
        -ServicePrincipal `
        -TenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 

##変数の指定
$vaultName = "<Recovery Services コンテナー名>"
$rgName = "<Recovery Services コンテナーが存在するリソースグループ名>"
$backupPolicy = "<バックアップ対象の仮想マシンに関連付けているバックアップポリシー名>"


##バックアップスケジュールに設定する時刻情報の加工
#現在時刻を取得し1時間加算
$targetTime_temp1 = (Get-Date).AddHours(+1)

#文字列型に変換し"分"以下を消去
$targetTime_temp2 = $targetTime_temp1.ToString("yyyyMMddHH")

#文字列型からDATETIME型に再変換
$targetTime = [DateTime]::ParseExact($targetTime_temp2,"yyyyMMddHH", $null)


##Recovery Services コンテナーの取得
$targetVault = Get-AzRecoveryServicesVault -ResourceGroupName $rgName -Name $vaultName

##バックアップスケジュールの取得
$SchPol = Get-AzRecoveryServicesBackupSchedulePolicyObject -WorkloadType "AzureVM"

##バックアップスケジュールの時刻をUTCで設定
$UtcTime = $targetTime.ToUniversalTime()
$SchPol.ScheduleRunTimes[0] = $UtcTime

##バックアップポリシーの取得
$pol = Get-AzRecoveryServicesBackupProtectionPolicy -Name $backupPolicy -VaultId $targetVault.ID

##バックアップポリシーの更新
Set-AzRecoveryServicesBackupProtectionPolicy -Policy $pol  -SchedulePolicy $SchPol -VaultId $targetVault.ID
```

　以上のスクリプトをRunbookに記載し、Azure Automationでスケジュールを作成してRunbookに関連付ければ作業は終了です。

　スクリプトの時刻情報加工の箇所について補足事項を2点記載します。

- 現在時刻を取得し1時間加算
　Runbook実行時よりも将来の時刻にバックアップスケジュールを変更する必要が有る為、現在時刻を取得し加算する処理としました。今回は1時間加算しましたが、Runbookの実行時刻やバックアップの頻度によって加算する値は変動し得ます。

- 文字列型に変換し"分"以下を消去
　Azure Backupのスケジュールは30分単位で指定する必要が有る為、"分"以下を消去する等の対応が必要です。30分単位で切り上げ切り捨てすることが出来れば問題無いのですが、そのようなことをPowerShellで実現する方法を私が習得していないので若干迂遠な処理となっています。

#注意点
　この方法を採用する上で1点注意事項がございます。Azure Backupの仕様として、「スナップショット 復元ポイント」を同時に18個以上保持することが出来ないという制限があります。今回のように2時間ごとにバックアップを取得するように設定しバックアップポリシーにてスナップショット保持期間を最短の1日とすればスナップショット数は最大で12個のはずですが、厳密に24時間でスナップショットが削除されるわけではないようで、スナップショットが18個以上になるタイミングではバックアップが失敗します。従って、1日に複数回バックアップを実行できるといっても、「スナップショット 復元ポイント」が18個以上にならないように頻度を調整する必要が有ります。

　実際にバックアップが失敗するとAzure Backupのバックアップジョブにて以下のエラーメッセージが出力されます。
「The number of restore points across restore point collections and resource groups for a VM cannot exceed 18」

![cap04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531201/0ff9b8fc-2766-5455-f623-41ed2044f706.png)