Test Automation

テスト自動化とか品質とか勉強会とかやってるエンジニア(Automation Architect)のブログです。

手動の運用手順書と自動スクリプトのレビュー

 先日、「手動の運用手順書を書いたのでレビューして下さい」と後輩に頼まれたのでレビューした。といっても、僕の専門はテストと自動化なので正直な話、手動の運用手順書のレビュー経験がない(笑)。しょうがないので「自動スクリプト」としてレビューするよと断りをつけてレビューした。

 実際、レビューしてみると手動の運用手順書と自動運用スクリプトのレビュー観点やその方法は共通する部分も多いが、その一方で前提や観点の違いから気をつけないといけないと感じた事も多かった。

共通する点

レビューの目的

 本番運用フェーズに入っているシステム上でシステム変更を実施する事は、システム上で予期しない変更をもたらし障害を引き起こすリスクを伴う。このリスクは手動でも自動化でも変わらない。システム変更に関するレビューの一番大事な目的は、 システム変更に伴うリスクが管理可能になっているかを確認する事だと思う。

 一般的に以下の点については、手動の運用手順書でも自動運用スクリプトでも、明確に記載されているか、その考え方が分かるように表現されているべきだと思う。

  • システムの変更箇所 (例 機能A
  • 影響範囲 (例 機能B
  • リスクのリスト (例 機能Bがデータの不整合により動作しなくなる事
  • リスクが顕在化する事なく、システムへの変更が終了した事を確認する方法 (例 機能AとBが期待通りに動作する事
  • リスクが顕在化した事を確認する方法 (例 機能Bのログファイルにエラーログが出ている事
  • リスクが顕在化した場合の対応方法 (例 データの不整合の解消

 これらを事前に明確にしリスクを管理可能にする事で、手動の運用手順書も自動運用スクリプトもその信頼性が向上する。

ロールバック

 システム停止を伴うシステム変更は、短い運用作業時間、少ないシステム停止回数で行う事が一般的に求められる。なので、複数のシステム変更を一度に実施する事は多い。ここで気をつけなければならない事は、複数のシステム変更はロールバック不可能な状況を引き起こす場合がある事だ。

 例えば変更A,変更B,変更Cを行う時に、変更Aと変更Bの後にはまだロールバック可能だが、変更Cの後にロールバック不可能になる事はしばしば起こる。

  • 一回のシステム変更で実施: [変更A → 変更B → 変更C] (ロールバック不可能)
  • 複数のシステム変更で実施: [変更A] (ロールバック可能)→ [変更B] (ロールバック可能) → [変更C]  (ロールバック不可能)

 ロールバックはデプロイに際しリスクを回避するための重要かつシンプルな手段だ[1][2]。だから、そのロールバックのポリシーが適切であるかをレビューで確認する事は重要だ。

異なる点

エラーに対する対応方法

 実行したコマンドに対して期待と異なる挙動が返って来た場合、手動の運用ではその場で人間による柔軟な対応が可能だが、自動スクリプトでは事前に定義した対応方法しか機械は実行出来ない。手動の運用ではエラーケースへの対応方法が手順書には表現されていなくても暗黙知として共有されていれば十分な場合があるが、自動スクリプトではすべて形式知化していく必要がある。

 ネガティブテストとそれらのテストで失敗した場合の対応方法が十分に定義されていない自動スクリプトは、悲惨な結果をもたらしかねない。自動運用は信頼性が低いと一部で指摘される理由はここにあるだろう。

 ただ、このあたりはもうすでに何年も前に解かれている問題だとも思う。例えばJavaでは、期待と異なる状況が起きた時には適切なExceptionを投げ、プログラムの適切な場所でCatchし対応を行う。JUnitではテスト実行中にExceptionが発生しても後処理を確実に実行するフレームワークを提供する。

システムの状態に関する前提

 もうすでに何年も前に解かれている問題であると言っても、実際にすべてのエラーケースを事前に網羅的に定義して行く事は難しい。システムの設定が複雑になるとテストすべきポイントは増える[4]。 特にシステムの状態について複数のケースを考慮しなければいけない場合や、コマンドを複数回行った場合に得られる結果が異なる場合等には、考慮すべきエラーケースの数が爆発的に増加する。

 この問題を解決するための考え方が、"Immutable Infrastructure", "Infrastructure as Code", "冪等性"だ[3]。システムの状態を適切にバージョン管理し、なりうる状態に制約を入れる事で、システムの事前状態をコントロール可能にする事が出来る。また、システム変更を実施する前にシステムの事前状態を確認し、適切な事前状態の時のみに変更を実施する事もエラーケース数の爆発を抑えることに役立つ。

 手動運用の場合も、もちろんこれらの考え方を適用する事は可能だが、その一方で手順書の効率化等から暗黙知化されていたり、逆に職人芸と化した手順書となっていたりする。手順書レビューでは、明確に表現されていないシステムの事前状態がないかの注意が必要だ。

 レビューとテストの使い分け

 僕が今回のレビューで一番戸惑った部分がここだ。自動スクリプトでは殆どの場合、自動テストも一緒に書かれる。自動テストがあると、テストとレビューそれぞれでカバーしたい範囲について簡単に議論が出来るのでそれぞれの役割が明確になりやすい。例えば、ファイルをコピーするコマンドと、コマンドの実行結果を確認するテストがある場合、自動テストを実行するだけでコマンドの正しさを確認する事が出来る。

 手動の手順書でも"#テスト済み"などとコメントを書く事で 、ある程度テストとレビューの役割を区別する事が可能かもしれないが、自動テストがないために、ついついコマンドの正しさが気になってしまう。

 レビューでは人間にしか確認出来ない事に集中する事が大切だ。コマンドの実行結果の正しさのような自動化する事で機械でも確認出来る観点ならばそちらに任せてしまった方がいい[5]。"レビューの目的"の項でも挙げた「システム変更に伴うリスクが管理可能であるかを確認する」といった人間にしか確認出来ない観点に集中しやすいという点においては自動スクリプトに分があると思う。

まとめ

 システム変更に関するレビューにおいて、手動の運用手順書と自動スクリプトで、

  • システム変更に伴うリスクが管理可能になっているかを確認する事という目的は共通

であるが、

  • エラーに対する対応方法やシステムの事前状態に関する前提が異なるため、気をつけるべきポイントが異なる

事について述べた。

 今回、それぞれの手段でのレビューに共通、異なるポイントという切り口で書いたが、これらのポイントは手動運用手順書を自動化する際の切り口として扱う事も出来る。これらのポイントを適切に解いて行く事で、より幸せな運用自動化が実現可能になると考えている。

参考文献