インフラストラクチャがドリフトしたとき:修正すべきか受け入れるべきかの判断基準
月曜の朝、インフラダッシュボードを開く。一見するとすべて正常に見える。しかし、ふと気づく。データベースインスタンスのサイズが、Terraformコードで定義したものと異なっている。誰かが週末にクラウドコンソールから変更を加えたのだ。パイプラインは実行されていない。コードはある状態を宣言しているが、実際のインフラは別の状態にある。
これがドリフトだ。ほとんどのチームが認めたがる以上に頻繁に発生する。インシデント対応中に誰かが手動で変更を加える。クラウドプロバイダーがリソースプロパティを自動的に更新する。同僚がセキュリティグループルールを直接変更する——迅速に対応する必要があったからだ。原因は何であれ、コードが宣言する状態と実際のインフラの状態の間にギャップが生じている。
問題はドリフトが発生するかどうかではない。必ず発生する。本当の問題は、それを検出した後にどう対処するかだ。
3つの調整パス
調整(リコンシリエーション)とは、インフラをコード定義に沿った状態に戻すプロセスだ。しかし、唯一の正しい方法があるわけではない。最適なアプローチは、状況、リスク、そして変更の背景によって異なる。
以下の判断ツリーを使って、状況に合ったパスを素早く特定しよう:
パス1:パイプラインの再適用
最も単純な選択肢は、コードを一切変更せずにパイプラインを再実行することだ。既存のInfrastructure as Code(IaC)をそのまま維持し、applyステップを実行する。Terraform、Pulumi、AWS CloudFormationなどのツールは、ステートファイルと実際のリソースを比較し、コードが定義する状態に戻すために必要な調整を行う。
これは、ドリフトが偶発的に発生した場合に有効だ。誰かがパイプラインを迂回していることに気づかずにコンソールからインスタンスサイズを変更した。開発者がデバッグのために一時的にセキュリティグループのポートを開放し、閉じるのを忘れた。別のチームのスケジュールジョブがリソースのタグを変更した。こうしたケースでは、パイプラインの再適用はクリーンで安全だ。コードが意図された状態を表しており、インフラがそれに追いつく必要があるだけだ。
この場合のリスクは低い。変更が意図的ではないからだ。誤りを修正しているのであり、意図的な決定を上書きしているわけではない。
パス2:ドリフトの採用
時には、手動での変更が実際には正しい判断だったこともある。本番インシデントの最中に、運用チームがトラフィックスパイクに対処するためにデータベースをスケールアップした。その変更によってアプリケーションは稼働を続けた。インシデント後、新しいキャパシティが現在のワークロードにより適していることに気づく。コード内の古い値はもはや時代遅れだ。
この場合、古いコードに戻すのは誤りだ。システムを稼働させ続けた修正を元に戻すことになる。代わりに、新しい状態を反映するようにIaCを更新する。これがドリフトの採用だ。実際に動作しているものにコードを合わせ、パイプラインを実行してすべてが一致していることを確認する。
ドリフトを採用することで、パイプラインを唯一の真実源として維持しつつ、有用であることが証明された変更を保持できる。ただし、慎重な評価が必要だ。なぜ変更が行われたのか、テストされたのか、副作用がないのかを理解する必要がある。レビューなしにドリフトを採用すると、IaCが文書化されていない決定の寄せ集めになってしまう。
パス3:手動修正
自動化されたパイプラインを実行するにはリスクが高すぎる状況もある。ドリフトしたリソースがライブトラフィックを処理している。セキュリティグループの変更がクリティカルなエンドポイントを保護している。ロードバランサーの設定がインスタンス間でリクエストを分散している。パイプラインが自動的に変更を適用すると、短時間の中断や完全な停止を引き起こす可能性がある。
こうしたケースでは、手動修正の方が安全だ。クラウドコンソールやサーバーにアクセスできる担当者が変更を一つひとつ確認し、慎重に元に戻し、リアルタイムで影響を監視する。時間と手間はかかるが、各変更の順序とタイミングを制御できる。
手動修正は自動化の失敗ではない。一部のリソースは復旧時に人間の判断を必要とするという認識だ。重要なのは、何をなぜ行ったかを文書化することだ。同じドリフトが次に発生したときに、修正を自動化するかどうかを判断できるようにするためだ。
誰が判断すべきか
調整は純粋に技術的な判断ではない。背景が必要だ。ドリフトはミス、インシデント、それとも記録されなかった実験によって引き起こされたのか?その答えが、どのパスを取るべきかを決定する。
判断には、変更とその影響を理解している人々が関与すべきだ。それは、インシデントに対応した運用チーム、手動修正を行った開発者、システムの動作を監視するプラットフォームエンジニアかもしれない。一人で判断すると、状況を誤認しやすい。
シンプルな経験則:ドリフトが発生した理由がわからないなら、自動的に調整してはいけない。まず調査する。変更が意図的でないと確信できる場合のみ再適用する。変更が有益だと確信できる場合のみ採用する。どちらも確信が持てない場合は手動で修正する。
調整判断のための実践的チェックリスト
ドリフト検出アラートに対応する前に、以下の質問を確認しよう:
- 誰がなぜこの変更を行ったか把握しているか?
- この変更はインシデント中または時間的制約の下で行われたか?
- ドリフトしたリソースは現在本番トラフィックを処理しているか?
- この変更を元に戻すと既知の問題が発生するか?
- この変更の記録がチケット、チャット、ランブックに残っているか?
最初の質問の答えが「いいえ」なら、行動ではなく調査から始める。リソースがトラフィックを処理しているなら、自動適用よりも手動修正を優先する。変更がインシデント中に行われたなら、適切なレビュー後にドリフトの採用を検討する。
調整で終わりではない
調整が完了しても、作業は終わっていない。調整によって新たな問題が発生していないことを確認する必要がある。クリティカルなセキュリティ修正を元に戻す自動適用は、システムを脆弱なままにする。テストなしで採用された手動変更は、不安定性をもたらす可能性がある。
目標はドリフトを排除することではない。目標は、システムの信頼性を維持し、コードを意味のあるものに保つ方法でドリフトに対処することだ。すべてのドリフトイベントは、プロセスを改善する機会でもある。同じドリフトが繰り返し発生するなら、パイプラインにガードレールが必要かもしれない。手動変更が頻繁すぎるなら、インシデント対応プロセスにインシデント後のコード更新のための明確なパスが必要かもしれない。
具体的な教訓
ドリフトはインフラが壊れていることを示すものではない。パイプラインの外で何かが発生したことを示すものだ。適切な対応は、ドグマではなく状況に依存する。変更が偶発的なら再適用する。変更が有用なら採用する。リスクが高いなら手動で修正する。そして常に、次に何をするかを決める前に、なぜドリフトが発生したのかを理解する。