Azure Automation: チェックポイントを活用して、信頼性の高いフォールト トレラントな Runbook を実行
このポストは、9 月 3 日に投稿した Azure Automation: Reliable, Fault-Tolerant Runbook Execution Using Checkpoints の翻訳です。
Azure Automation の Runbook を作成する際は、エラーや例外、ネットワーク障害、クラッシュの発生などの予期しない事態でも Runbook が確実に実行されるようにしたいと考える方が多いかと思います。このような場合には、Azure Automation が有効です。Azure Automation は Windows PowerShell ワークフローの上に構築されており、チェックポイント機能をサポートしています。この機能でワークフローの状態を永続化させることにより、処理が中断したときにも、中断した時点またはその付近から処理を再開できます。チェックポイント機能は、Automation の Runbook を活用するうえで非常に便利な機能です。この機能をうまく利用することで、信頼性を確保しつつ実行時間の長い処理を自動化したり、ネットワークで接続されている他のシステムに安定してアクセスしたり、やり直すべきではない (やり直すことで結果が変わってしまう) 処理やコストのかかる処理の再実行を防止したり、手動の手順を含めることで意図的に処理を中断したりできます。
この記事では、Automation の Runbook でチェックポイント機能を使用する理由、タイミング、および方法について説明します。PowerShell ワークフローのチェックポイント機能に関する記事 (英語) が公開されていますので、こちらも併せてお読みいただくと、この機能をさらに詳しくご理解いただけます。
チェックポイント機能の概要
チェックポイントとは Runbook のジョブの特定時点でのスナップショットであり、その時点での変数の値、出力内容、およびその他のシリアル化可能な状態の情報が含まれます。各チェックポイントは Storage に保存されます。意図的であるかどうかにかかわらず、Runbook の処理が中断された場合は、その後再開されるときにワークフロー エンジンが最新のチェックポイントのデータを使用して Runbook を復元し、処理を再開します。
Azure Automation でのチェックポイントの作成
Azure Automation で Runbook のジョブを永続化すると、チェックポイントが作成され、Azure Automation データベースに保存されます。データベースに保存されるのは各ジョブの最新のチェックポイントのみで、新たにチェックポイントが保存されるときに前回のデータは削除されます。Runbook の処理が中断され、その後再開される場合、保存されているチェックポイントを使用して Runbook の復元と再開が行われます。
PowerShell ワークフローではワークフロー セッションをホストしているコンピューターのハード ディスク ドライブにチェックポイントを保存しますが、Azure Automation ではチェックポイントを Azure Automation データベースに保存します。このため、Runbook を実行している Worker ロールがクラッシュした場合、同じ Worker ロールで再開する場合と他の Worker ロールがジョブを引き継ぐ場合のどちらでも、データベースに保存されている最新のチェックポイントを使用してジョブが再開されます。
チェックポイント機能を使用する理由
Runbook でチェックポイント機能を使用する理由としては、次のようなものがあります。
- 特定の処理が再び実行されないようにする
- チェックポイント機能は、Runbook がクラッシュして (または中断されて) その後再開されたときに、やり直すわけにはいかない (やり直すことで結果が変わってしまう) 処理を確実に実行されないようにする場合に便利です。その例として、VM 作成直後に Runbook のチェックポイントを作成すると、Runbook のジョブが中断され再開されたときに重複して VM が作成されないようにすることができます。
- 実行時間の長いタスクを保護する
- 現実世界では、エラーの発生を防ぐことはできません。複数のステップを含む実行時間の長いタスクは、ネットワークの問題、コンピューターの再起動やクラッシュ、タイムアウト、停電などで処理が中断されることに対して脆弱です。コストのかかる処理がやり直されるのを回避するために、重要なポイントで Runbook のチェックポイントを作成し、Runbook が再開されるときにその処理が再実行されないようにします。
- 実行時間の長い Runbook を確実に最後まで実行する
- Azure Automation には「fairshare (フェアシェア)」という機能があり、実行時間が 30 分を超える Runbook は、他の Runbook を実行できるようにアンロードされます。アンロードされた Runbook は最終的には再び読み込まれ、その Runbook の最新のチェックポイントから再開されます。このため、Runbook を確実に最後まで実行するには、30 分未満の間隔でチェックポイントを追加する必要があります。こちらのフォーラムの記事 (英語) でその例をご覧いただけます。
- 計画的な中断または手動による中断を可能にする
- 実行中の Runbook を意図的に中断する場合があります。たとえば、処理を続行するかどうかの確認を待つ場合や、予期しないまたは予定されているシステム上の問題により Runbook のジョブを中断する場合などです。
チェックポイントを Runbook に追加する方法
Checkpoint-Workflow アクティビティ
Checkpoint-Workflow アクティビティ (Persist と同等) は標準的な PowerShell ワークフロー アクティビティです。特定の位置でチェックポイントを作成するときに Runbook で使用します。チェックポイントは、Runbook で Checkpoint-Workflow アクティビティが発生したときに作成されます。
…
Download-Updates
Reboot-VM
Checkpoint-Workflow
Email-Team
Checkpoint-Workflow
…
アクティビティの共通パラメーター -PSPersist
アクティビティを呼び出すときには、毎回、共通ワークフロー パラメーターである –PSPersist を含めることができます。このパラメーターを含めると、アクティビティ完了後すぐにチェックポイントが強制的に作成されます。
…
Download-Updates
Reboot-VM –PSPersist $True
Email-Team –PSPersist $True
…
ワークフローの Preference 変数 $PSPersistPreference
Runbook に $PSPersistPreference = $True という文を挿入すると、この文の後のアクティビティが終了するごとにチェックポイントが作成されます。Runbook の最初でこれを設定すると、Runbook のすべてのアクティビティごとにチェックポイントが作成されます。$PSPersistPreference = $False (Runbook の既定の設定) という文を挿入すると上記の設定は無効化され、以降はチェックポイントの自動作成は実行されなくなります。
パフォーマンスと戦略の両面から、アクティビティごとにチェックポイントを作成するのは最良の方法とは限りません。各チェックポイントで、ワークフローの状態をシリアル化しデータベースに保存する処理が必要になるからです。また、Runbook が中断されたときに特定のアクティビティは再度実行したい場合 (後でその例を紹介します) もあります。このようなときには、すべてのアクティビティでチェックポイントを作成する方法はお勧めできません。
…
Download-Updates
Reboot-VM –PSPersist $True
Email-Team –PSPersist $True
…
Suspend-Workflow アクティビティ
Runbook で Suspend-Workflow アクティビティを使用すると、すぐに Runbook のチェックポイントが作成され、そこで処理が中断されます。このアクティビティは、Runbook で何らかの処理を行った後に継続するかどうかを確認する場合などに使用します。この確認で「許可」が得られると、Runbook のジョブが再開されます。
…
Download-Updates
# 更新を適用する許可を得る
Suspend-Workflow
# 再開された場合は継続
Reboot-VM –PSPersist $True
Email-Team –PSPersist $True
…
チェックポイントを追加する位置
一般的には、ワークフローを永続化する位置は明確に示すことが推奨されます。$PSPersistPreference 変数を設定して各アクティビティの後に永続化を行うよりも、永続化する適切な位置を慎重に考え、ワークフローの中で Checkpoint-Workflow や Suspend-Workflow のアクティビティ、または –PSPersist パラメーターを効果的に使用するほうが賢明です。次に示す例のように、明らかにワークフローの永続化を行う必要のある場所と、まったく行う必要のない場所があります。また、ワークフローを永続化する際にはシステムで処理が実行されるため、ワークフローのパフォーマンスが一定の影響を受けることにも留意してください。
ベストプラクティス : 次のような位置に、ワークフローでチェックポイントを作成するとよいでしょう。
- 再度実行しないようにする (再実行することで結果が変わる) アクティビティの後。
- 実行時間の長いアクティビティやコストのかかるアクティビティなど、やり直すと実行コストが高いアクティビティの後。
- 実行時間が 30 分を超える Runbook の中。30 分が経過すると、他の Runbook の処理を実行できるように、「fairshare (フェアシェア)」機能が割り込み、Runbook の処理を一時的にアンロードします。その後、システムが Runbook を再度読み込み、最新のチェックポイントから処理を再開します。チェックポイントを作成しなかった場合は、Runbook が最初から処理をやり直し、再びfairshare (フェアシェア) 機能の制限を受けます。これが繰り返し発生するため、Runbook の処理が永久に終わらなくなります。
- 通常よりも問題が発生する可能性が高く、不具合のためにワークフローが中断されることが考えられるアクティビティの前。アクティビティが確実に完了するように、ワークフローの再開時にアクティビティが再実行されるようにします。たとえば、ネットワーク障害により中断される可能性のある、リモート システムにアクセスするアクティビティの場合などです。
ベストプラクティス : 次のような位置には、チェックポイントを作成しないようにします。
- ワークフローが中断して再開するときに、再度やり直す処理の後。
- 再実行しても結果が変わらない処理の後や、チェックポイントを作成するよりもやり直したほうがコストが低い処理の後。
- InlineScript ブロック内 (許可されていません)。
実例的なシナリオ: VM の更新
- Windows Update で最新の修正プログラムをダウンロードする
- VM を再起動して修正プログラムを適用する
- チェックポイントを作成する
- 更新が適用されたことをチームのメンバーに通知する電子メールを送信する
- チェックポイントを作成する
- …
このシナリオでは、手順 1 はやり直しても結果が変わらないため再実行しますが、手順 2 と手順 3 はやり直さないため、これらの後にチェックポイントを作成する必要があります。すべてのアクティビティの後にチェックポイントを作成しても構いませんが、手順 1 の後に作成する必要はなく、システムにとって無駄な処理を増やすことになります。
実例的なシナリオ: ユーザーへの通知
- データベースからユーザーのリストを取得する
- ユーザーに新しいポリシーを電子メールで通知する
- チェックポイントを作成する
- ユーザーに送信された電子メールを管理する
- チェックポイントを作成する
- …
アクティビティ グループのアクティビティがすべて正常に完了したときのみ、処理をやり直さないようにしたい場合があります。このシナリオでは、手順 1 と手順 2 は常に両方とも実行し、電子メールを送信するときには必ず取得されたユーザーのリストが最新の状態であるようにします。そのため、Runbook を実行している Worker ロールが手順 2 (ユーザーに電子メールを送信する) の前にクラッシュした場合、Runbook のジョブを再開する際は手順 1 (ユーザー リストの取得) から実行されるようにします。しかし、手順 3 の直前でクラッシュや中断が発生した場合は、手順 2 の再実行を確実に防止する (電子メールが重複して送信されない) ようにします。
ベストプラクティス : ワークフロー内の InlineScript ブロックや関数の中にはチェックポイントを追加できないので注意が必要です。これは、InlineScript ブロックおよび関数が PowerShell ワークフロー スクリプトではなく PowerShell スクリプトとして実行されるためです。ワークフローでチェックポイントを作成するためには、Runbook のコードを複数のモジュール化されたアクティビティに分割して、アクティビティの合間でチェックポイントを作成できるようにします。InlineScript が必要な場合は、複数の InlineScript ブロックを使用して、その合間でチェックポイントを作成します。
Runbook の中断と再開
チェックポイントの作成と Runbook の中断/再開は、互いに密接に関係しています。Runbook にチェックポイントを追加すると、Runbook が中断されたときに最新のチェックポイントから処理を再開することができます。
Azure Automation の Runbook のジョブは、次のような状況で中断されます。
- Azure Automation ポータルの UI からユーザーが意図的に行う
- Azure Automation ポータルの UI から、実行中の Runbook のジョブを中断することができます。
- ジョブはその後のチェックポイントで中断されます。Runbook でチェックポイントが作成されていない場合、最後まで処理が実行されます。その間、状態は “Suspending” と表示されます。
- Runbook で Suspend-Workflow を使用してユーザーが意図的に行う
- Runbook に Suspend-Workflow アクティビティを追加します。
- ジョブでチェックポイントが作成され、Suspend-Workflow が呼び出された位置で処理が中断されます。
- Suspend-AzureAutomationJob コマンドレットを使用してユーザーが意図的に行う
- PowerShell のスクリプトまたはワークフローでは、Suspend-AzureAutomationJob (英語) コマンドレットで Azure Automation の Runbook のジョブを中断することができます。
- ジョブはその後のチェックポイントで中断されます。Runbook でチェックポイントが作成されていない場合、最後まで処理が実行されます。その間、状態は “Suspending” と表示されます。
- Runbook が 30 分間以上実行されたときに Azure Automation ワークフロー エンジンによって意図的に行われる
- ジョブの実行時間が 30 分を超えると「fairshare (フェアシェア)」機能が割り込み、Runbook を一時的にアンロードします。このとき、ジョブの状態は “Running, Waiting for Resources” に設定されます。その後 Runbook が再度読み込まれ、最新のチェックポイントから処理が再開されます。
- Runbook の例外により Azure Automation ワークフロー エンジンによって意図せず行われる
- 実行中のジョブで例外が発生した場合、ジョブが Runbook の Worker ロールからアンロードされ、状態が “Suspended” に設定されます。
- Runbook の Worker ロールのクラッシュにより意図せず行われる
- Runbook の Worker ロールがクラッシュした場合、その Worker ロールで実行されているジョブは即座に終了します。このとき、データベースのジョブの状態は “Running” のままとなります。同一または代替の Worker ロールが稼動状態になったら、ジョブが引き継がれて最新のチェックポイントから続行されます。
Azure Automation の Runbook のジョブは、次のような状況で再開されます。すべての場合において、ジョブは最新のチェックポイントから再開されます。ただし、チェックポイントがない場合は最初から実行されます。
- Azure Automation ポータルの UI から手動で行う
- Azure Automation ポータル UI を使用すると、中断されているジョブを再開することができます。
- Resume-AzureAutomationJob コマンドレットを使用して行う
- PowerShell のスクリプトまたはワークフローでは、Resume-AzureAutomationJob (英語) コマンドレットを使用して中断されているジョブを再開できます。
- Runbook の Worker ロールのクラッシュ後、自動的に引き継がれる
- Worker ロールが稼動状態に復帰するか、または他の Worker ロールが代替として割り当てられると、データベース内のジョブが検索されます。状態が “Running” で、Worker ロールで実行されていないジョブがある場合、Worker ロールが自動的に最新のチェックポイントから再開します (前述の中断される状況の 6 番目と同一のシナリオ)。
Runbook が再開された場合、中断前とは別の Worker ロールで実行されることがあるため、注意が必要です。このため、Runbook が実行される可能性のあるローカル マシンの状態は、作成し直す必要があります。つまり、Runbook のチェックポイントより後の任意の時点で Azure に接続する必要がある場合は、Connect-Azure、Add-AzureAccount、Select-AzureSubscription、Set-AzureSubscription など、ローカル ファイルに状態を設定するコマンドレットを各チェックポイントの後で再度呼び出す必要があります。
まとめ
以上のように、この PowerShell ワークフローの重要な機能を活用して中断に強い Runbook を作成するには、Runbook にチェックポイントを追加することが重要です。チェックポイントを追加するのは簡単です。Runbook を作成するときに少し先のことを考慮することで、実行時間の長いタスクやコストのかかるタスクを予期しない中断から保護し、真に堅牢で信頼性の高い Runbook を作成することができます。