インフラ変更を適用する前に計画すべき理由

ファイアウォール設定ファイルの1行を変更するプルリクエストをレビューしているとします。その変更は、ポート443をパブリックトラフィックに対して開放するものです。単純な変更ですよね?

しかし、その1行が予期せぬ結果を招く可能性があります。別のルールと競合するかもしれません。そのポートが6ヶ月前にセキュリティ上の理由で意図的に閉じられていたとしても、誰もその理由を覚えていないかもしれません。あるいは、そのポートを開放することで、別のポートを経由してルーティングされていたデータベース接続が壊れるかもしれません。変更が適用され、何かが動かなくなるまで、これらのことはわかりません。

まさにこのような状況を防ぐために設計されたのが、計画→レビュー→適用(Plan-Review-Apply)ワークフローです。

直接適用の問題点

インフラ変更を直接適用する場合、手探りで作業していることになります。コードは目の前にあるかもしれませんが、コードだけでは、それが本番環境で実行されたときに実際に何が起こるかはわかりません。インフラの実際の状態は、コードが想定している状態と異なる可能性があります。先週、誰かが手動で変更を加えたかもしれません。以前のデプロイメントで、予期しない状態が残っているかもしれません。コードには「このルールを追加」と書いてあっても、システムが「既存のルールをすべてこれに置き換える」と解釈するかもしれません。

直接適用は、すべての変更をギャンブルに変えてしまいます。負けたかどうかは、物事が壊れて初めてわかります。

Plan-Review-Applyの仕組み

このワークフローには3つの段階があり、それぞれに固有の目的があります。

以下の図はその流れを示しています。

flowchart TD A[開始: コード変更] --> B[計画: 差分を生成] B --> C[レビュー: 人間が計画を確認] C -->|承認| D[適用: 変更を実行] C -->|却下| B D --> E[終了]

計画(Plan) は、現在のインフラ状態とコードが作成しようとしている状態との間の詳細な比較を生成します。追加、変更、削除される内容が正確に示されます。これは要約や推測ではありません。インフラの正確な、機械生成による差分です。

レビュー(Review) は、人間がその計画を精査する段階です。驚きがないか確認します。計画が変更の意図と一致しているか検証します。「このセキュリティグループの削除が本番サーバーに影響する」といったことを、誰かが適用ボタンを押す前に発見します。

適用(Apply) は、計画された変更を実行します。計画はすでに検証されているため、適用段階での予期しない結果のリスクは大幅に低減されます。もはや推測ではありません。既知の変更セットを実行しているのです。

計画の実際の姿

計画は漠然とした説明ではありません。それは具体的な操作のリストです。例えば、計画には次のように表示されます。

  • ポート443用の新しいセキュリティグループルールを追加
  • 既存のロードバランサーリスナーを変更して新しい証明書を使用
  • 参照されなくなったデータベースサブネットグループを削除

各操作には、リソース識別子、現在の値、新しい値が含まれます。このレベルの詳細により、問題が発生する前に発見できます。計画が、使われていないと思っていたリソースを削除しようとしていることや、別のチームが依存している設定を変更しようとしていることに気づくかもしれません。

計画を必須要件にする

最も効果的なチームは、計画を譲れないステップとして扱います。パイプラインは、計画が生成されていない場合、または計画がレビューおよび承認されていない場合に停止するように設定されています。これは、プルリクエストをマージする前にコードレビューを必須にすることのインフラ版です。レビューされていないコードを本番環境にマージすることはないでしょう。なぜ、レビューされていないインフラ変更を適用するのでしょうか?

このガードレールは、最も一般的な障害パターン、つまり誰かが小さな変更を安全だと思い込んで確認せずに適用してしまうことを防ぎます。パイプラインはまず計画を生成するよう強制し、それによって予期していなかった何かが明らかになることがよくあります。

監査証跡としての計画

計画には、問題が発生した際に重要となる第二の目的があります。すべての計画をパイプラインのアーティファクトとして保存できます。これにより、何が変更されたか、いつ変更されたか、誰が承認したかという、すべてのインフラ変更の履歴が作成されます。

本番インシデントが発生した場合、その記録は非常に貴重です。誰が何を変更したかを尋ねて回る代わりに、計画アーティファクトを確認します。問題が発生する直前に適用された正確な差分を確認できます。これにより、インシデント調査が推測から証拠に基づく分析へと変わります。

計画が保存されていなければ、手動のログ、チャットメッセージ、記憶に頼ることになります。これらは、午前2時に本番障害をデバッグしようとしているときには、どれも信頼できません。

同時変更の処理

同じインフラストラクチャで作業するチームは、別の課題に直面します。それは、競合する変更です。2人の人物が同時にネットワーク設定ファイルを変更します。どちらの変更も単独では問題ありません。しかし、組み合わさると、接続を切断する可能性のある競合が発生する可能性があります。

計画ステップはこれをキャッチします。2人目の人物が計画を生成すると、変更が適用される前に競合が表示されます。チームは、本番環境ではなくコード内で競合を解決できます。これは、両方の変更を適用して、悪影響を及ぼし合わないことを願うよりもはるかに安全です。

計画では解決できないこと

Plan-Review-Applyは強力ですが、限界もあります。コードが示す内容と、インフラが現在報告している内容を比較することしかできません。パイプラインの外部で誰かが手動で変更を加えた場合、計画はすべての不整合を捕捉できない可能性があります。インフラプロバイダーにバグや予期しない動作がある場合、計画は実際に実行される内容とは異なるものを示す可能性があります。

これらのエッジケースはワークフローを無効にするものではありません。つまり、ドリフト検出や、コードと実際のインフラ間の定期的な調整など、追加のプラクティスが併せて必要になるということです。

実践的なチェックリスト

パイプラインにPlan-Review-Applyを実装する前に、以下の点を考慮してください。

  • マージされたプルリクエストごとに自動的に計画を生成する。オンデマンドだけでなく
  • すべての計画をタイムスタンプと承認メタデータとともにパイプラインアーティファクトとして保存する
  • 計画が存在しない場合、または計画がレビューされていない場合は適用をブロックする
  • 承認する前に、計画に驚きがないかレビューする。正確性だけでなく
  • インシデント調査中に計画を最初の情報源として使用する。最近の変更について

核となる考え方

Plan-Review-Applyは、インフラ変更を盲目的なギャンブルから、計算され検証された操作へと変えます。計画は、何が起こるかを事前に示します。レビューは、問題が本番環境に到達する前に捕捉します。適用は、検証されたものだけを実行します。このワークフローはすべてのリスクを排除するわけではありませんが、完全な影響を知らずに変更を適用するリスクを排除します。

もしあなたのチームがまだインフラ変更を直接適用しているなら、まずは1つのシンプルなルールから始めてください。最初に計画を生成し、それを読み、それから適用するかどうかを判断する。この習慣だけで、ほとんどの監視ツールよりも多くの本番環境の問題を防ぐことができます。