Appearance
RBSU Monitor — 24ノードの手作業をWorkflowにした
発端
Securebootの証明書切れの対応で、ASHノードのRBSUに入ってKeyをリセットする必要がでた
2つのリージョン、合計24台のノードで実施・・??
だるすぎる。Excelの手順書作りたくない
💡よし、ワークフローにしよう
公式手順よりやることは以下で確定
HPE Azure Stack Hub Solutions – Secure Boot Certificate Expiration and Update
| フェーズ | 手作業 |
|---|---|
| 切り離し | ASH Admin Portalから対象ノードをDrainし、Maintenanceに遷移確認 |
| 停止 | ASH Admin Portalから対象ノードをShutdownし、Power Offに遷移確認 |
| Key更新 | RBSUでReset All Keys to Platform Defaultsを実行する |
| 再設定 | 再起動後、Secure Bootを再度有効化し、再起動 |
| 確認 | Secure Boot有効を確認し、Shutdown、Power Offを確認 |
| 起動 | ASH Admin PortalからNodeをStartし、Power Onに遷移確認 |
| 組み込み | ASH Admin Portalから対象ノードをResumeし、Runningに遷移確認 |
| 確認 | クラスタとVolumeの正常性を確認する |
何を作ったのか
Windowsならデフォルトで入っているPowershell 5.1を使ったWorkflowエンジン
| 項目 | 内容 |
|---|---|
| UI | PowerShell TUI |
| 接続先 | ASH Admin API / PowerShell、HPE iLO Redfish API |
| Workflow | 18 STEP、状態保存、Retry、再開対応 |
| 承認 | 3か所のApproval GateでNodeNameを入力 |
Workflowの全体像
こんな感じ。青色はWorkflowが決定論的に自動実行するところ、赤色は人間が承認するところ
同じ番号のコネクタへ続く。
全体のアーキテクチャ
Powershellのモジュール構造は以下。状態管理にDBは使わずstate.jsonファイルをSoTとする
| モジュール | 役割 |
|---|---|
| Launcher | 各モジュールを読み込み、State、接続、Inventory、TUIを初期化する |
| Config | Region選択、認証情報、ASH Admin接続を扱う |
| Inventory | Node、BMC Address、Volumeの状態を取得する |
| TUI | 状態表示、Node Lock、DryRun / Exec切替、キー入力を扱う |
| Workflow | 18 STEP、次の処理、Approval Gate、進捗保存を制御する |
| Adapters | ASH Admin APIとiLO Redfish APIの操作と状態確認を行う |
| State | phase、currentStep、エラー、Inventory、ログを永続化する |
TUIはこんな感じ
18 STEPの決定論的Workflow
選択したノードに対して以下のフローを順次実行。2、3、15はApproval Gateによる人間の承認が発生
| # | STEP | 実行内容 | 完了条件 |
|---|---|---|---|
| 1 | ResetAllKeysToDefault | iLO RedfishでPlatform Defaultへリセット | HTTP 200 |
| 2 | ASH Node drain | Disable-AzsScaleUnitNodeを実行 | ASHがMaintenance |
| 3 | ASH Shutdown | Admin REST APIでShutdown | HTTP 200 / 202を受理 |
| 4 | Power Off confirmed | iLOをポーリング | PowerState=Off |
| 5 | RBSU Once設定 | Boot OverrideをBiosSetup / Onceへ変更 | HTTP 200 |
| 6 | iLO Power On | Redfishで電源ON | Power On要求正常終了 |
| 7 | Secure Boot Disabled確認 | RBSU到達状態をポーリング | 2回連続RBSU到達を確認 |
| 8 | Power Off before staging | 安全条件を再確認してForceOff | PowerState=Off |
| 9 | SecureBootEnable=true | 電源OFF状態でSecure Bootを有効化 | SecureBootEnable=true |
| 10 | 2回目のRBSU Once設定 | Boot Overrideを再設定 | PATCH正常終了 |
| 11 | iLO Power On | Redfishで電源ON | HTTP 200 |
| 12 | Secure Boot Enabled確認 | RBSU到達状態をポーリング | 2回連続RBSU到達を確認 |
| 13 | Power Off after RBSU | 安全条件を再確認してForceOff | PowerState=Off |
| 14 | Normal boot確認 | Onceを確認し、必要な場合だけPATCH | BootSourceOverrideEnabled=Disabled |
| 15 | ASH Start | 通常起動を開始 | HTTP 200 |
| 16 | ASH Start confirmed | ASH状態をポーリング | Maintenance / Running |
| 17 | ASH Resume | Enable-AzsScaleUnitNodeを実行 | HTTP 200 |
| 18 | 最終正常性確認 | Nodeと全Volumeをポーリング | NodeがRunning / Running、全VolumeがHealthy / OK |
各STEPの動き
各STEPはRetry耐性強化を目的に、基本的に3つのGateを状態遷移の単位とする
| Gate | 内容 |
|---|---|
| Pre-Check Gate | どの状態ならSTEPを開始してもよいかのGate |
| Execute Gate | 設定変更等の処理を行うGate |
| Post-Check Gate | 処理が完了し、後続STEPに引き渡せる状態か確認するGate |
以下イメージ
| 操作 | Pre-check Gate | Execute Gate | Post-check Gate |
|---|---|---|---|
| Drain | Maintenanceになっていない | Disable | Maintenanceになっている |
| ForceOff | RBSUに到達している | ForceOff | PowerState=Offになっている |
Approval Gate
サービス影響が出る可能性のある作業(ASHのNode Drain、Shutdown、Start等)については、人間の承認をもって実行することにする
| Approval Gate | 人間が判断する理由 |
|---|---|
| Drain | 対象NodeやRegionを誤ると、予期しないサービス影響が起きる |
| Shutdown | Drain済みで、安全に停止できる対象かを確定する |
| Start | 対象Nodeを本当に起動してよいかを確定する |
実際のApproval Gateでは、対象Nodeと実行コマンドを表示し、NodeNameの完全一致入力を求める。
text
Target: NODE-01
Action: ASH Node drain
Command to execute:
Disable-AzsScaleUnitNode -Location region_a -Name NODE-01 -Force -Confirm:$false
If this is correct, type the exact NodeName to continue:
> NODE-01NodeNameとRegionはサンプル値。
NodeName入力を承認にした理由
対象のノードであること、対象のリージョンであることの最終確認ポイントとするために、NodeNameを入力させるようにしました。
実際に使ってみてどうだったか
1ノードあたり15分程度の時短を得ることができた。時間ベースでみると些細なものだが・・
人間が手を動かす点を最小限とし、Nodenameを確認して入力するというところに集中させることができた。
夜間実施ということもあり、手作業と比較しても安全に実施できたのではないかと思っている
| 観点 | 手作業 | RBSU Monitor |
|---|---|---|
| RBSU操作 | Remote Consoleで操作 | Redfish APIで実行 |
| 状態確認 | 画面を監視して判断 | APIをポーリングして期待値を検証 |
| 中断 | 手順書と記憶から現在地を復元 | Stateと実機状態から再開 |
| 人間の入力 | 各工程の操作と監視 | 3つのApproval Gate |
| 1 Nodeの経過時間 | 約60分 | 約45分 |
| 実績 | - | 8時間で12 Node、全24 Nodeに使用 |
あとがき
Codex+GPT5.6 Solを使ってこのWorkflowを作成しました。散歩している時に思いついてから1日でプロトタイプが完成、翌日には検証環境で回してみて動作を検証できた。
今まではツール化よりも手順書書く方が時短だったかもしれないが、やはり速い。 決定論的な実装ができるならコーディングエージェントを使ったツール化は有効かも。
このツールで得たものは作業時間の圧縮じゃなくて、Approval Gateの承認に人間の作業を集中させることで自動処理中に監視をする必要がなくなったこと。
実際にWorkflowが進んでいる間は上長、作業者を含めて雑談しながら待つということができたことから考えると、単に作業時間が短くなったことが効能ではなく、
普段仕事中に時間をとってまでできないような話ができる時間を生み出したという点について価値のあるものになったのではないかなと思いました。
AI活用が賑わっていますが、LLM活用ではなくコーディングエージェントとして使ってみた話でした
実装は結構頑張って考えたのですが・・誰も興味がないようで・・全然コメントないので・・
悲しくなってここに供養することにしました。
Appendix: State.jsonについて
STEPが正常終了した時
json
{
"schemaVersion": 1,
"region": "region_a",
"updatedAt": "2026-08-20T18:10:42+09:00",
"nodes": [
{
"id": 1,
"name": "NODE-01",
"status": "completed",
"phase": "resume_confirmed",
"currentStep": "",
"iloIp": "192.0.2.10",
"ashStatus": "Running",
"powerState": "Running",
"iloStatus": "OK",
"lastError": "",
"updatedAt": "2026-08-20T18:10:42+09:00"
}
],
"volumes": [
{
"label": "InfrastructureVolume-01",
"healthStatus": "Healthy",
"operationalStatus": "OK",
"repairStatus": ""
}
],
"logs": [
{
"timestamp": "2026-08-20T18:10:42+09:00",
"level": "INFO",
"nodeName": "NODE-01",
"message": "Workflow completed."
}
]
}STEPが異常終了した時
json
{
"schemaVersion": 1,
"region": "region_a",
"updatedAt": "2026-08-20T15:42:18+09:00",
"nodes": [
{
"id": 1,
"name": "NODE-01",
"status": "failed",
"phase": "shutdown",
"currentStep": "power_off_confirmed",
"iloIp": "192.0.2.10",
"ashStatus": "Maintenance",
"powerState": "Stopping",
"iloStatus": "OK",
"lastError": "Timed out waiting for iLO PowerState=Off.",
"updatedAt": "2026-08-20T15:42:18+09:00"
}
],
"volumes": [],
"logs": [
{
"timestamp": "2026-08-20T15:42:18+09:00",
"level": "ERROR",
"nodeName": "NODE-01",
"message": "Step failed: Timed out waiting for iLO PowerState=Off."
}
]
}