インフラ変更もアプリケーションコードと同様にコードレビューが必要だ

本番環境でサーバーが稼働している。チームの誰かが監視ツールのために新しいポートを開ける必要がある。その人物はクラウドコンソールにログインし、セキュリティグループを探し出し、ルールを追加して保存する。この変更を知る者は他に誰もいない。3日後、セキュリティチームが監査を実施し、あるべきではないポートが開いているのを発見する。誰がなぜ開けたのか、誰も覚えていない。

このシナリオは、インフラ変更をアプリケーションコード変更とは異なる方法で扱っているチームで頻繁に発生する。アプリケーションのたった1行のバグ修正にプルリクエスト、ピアレビュー、承認を要求する同じチームが、誰かにSSHでサーバーにログインさせ、設定ファイルを直接変更させる。この不整合がリスク、混乱、そして不必要な炎上対応を生み出す。

インフラ変更に同じ厳格さが必要な理由

インフラをコードとして記述する場合、サーバー設定、ネットワークルール、データベース設定、デプロイ定義をGitに保存する。これらのファイルは、インフラがどうあるべきかを正確に記述する。これらのファイルへの変更は、アプリケーションコードへの変更と同じくらい深刻な結果をもたらす可能性がある。

ファイアウォールルールを誰かが変更した場合を考えてみよう。1つのポート設定ミスで、顧客データがインターネットに露出する可能性がある。間違ったデータベースインスタンスサイズは、パフォーマンス低下や予期せぬコスト増加を引き起こす。誤ったロードバランサー設定は、アプリケーション全体をオフラインに追い込む。これらは仮定のリスクではない。インフラ変更のレビュープロセスをスキップするチームで日常的に発生している。

問題は人がミスをすることではない。誰でもミスはする。問題は、レビューなしでインフラ変更が行われた場合、何かが壊れるまでミスが気づかれないことだ。そして何かが壊れたとき、何が変更されたのか、誰が変更したのか、なぜ変更したのかの記録が残っていない。

インフラにおけるプルリクエストの仕組み

インフラがGitでコードとして定義されていれば、レビュープロセスはアプリケーションコードとまったく同じように機能する。誰かがブランチを作成し、インフラファイルに変更を加え、プルリクエストを開く。他のチームメンバーが変更をレビューし、コメントを残し、改善を要求し、または変更を承認する。承認されると、変更はメインブランチにマージされ、パイプラインがそれを適用する。

このプロセスは新しいものでも複雑なものでもない。開発チームが何年も使ってきたのと同じワークフローだ。唯一の違いは、何をレビューするかである。アプリケーションロジックをレビューする代わりに、設定定義をレビューする。

インフラレビューでチェックすべき項目

インフラのプルリクエストをレビューするとき、いくつかの点を確認する。

第一に、変更が要件に対して妥当かどうか。誰かがポートを開けようとしている場合、そのポートは本当に必要か?より安全な代替手段はないか?変更はチームの合意と一致しているか?

第二に、設定は正しいか。構文を確認する。ポート番号、インスタンスサイズ、ネットワークCIDRブロックが正確であることを検証する。許可が広すぎるセキュリティルールがないか確認する。0.0.0.0/0からポート22へのトラフィックを許可するルールは、ほとんどの場合危険信号だ。

第三に、変更は他の環境と一貫性があるか。ステージング環境が特定のインスタンスタイプやデータベースサイズを使用している場合、本番環境が文書化された理由なしに突然まったく異なるものを使うべきではない。環境間の不整合は、デプロイメント問題の一般的な原因である。

第四に、変更はチームの命名規則とタグ付け標準に従っているか。一貫した命名により、リソースの目的と所有者を理解しやすくなる。タグはコスト配分とリソース管理に役立つ。

履歴記録

承認されマージされたすべてのプルリクエストは、何が変更され、誰が変更し、いつ変更したかの永続的な記録となる。この履歴の追跡は、問題が発生したときに非常に貴重だ。

朝起きて本番アプリケーションにアクセスできないことに気づいたとしよう。インフラリポジトリの最近の変更を確認すると、2時間前にロードバランサー設定を変更したプルリクエストが見つかる。何が変更されたかをすぐに確認でき、変更を行った人物と議論し、ロールバックするか修正するかを判断できる。

この記録がなければ、推測するしかない。チーム内で聞き回り、チャットログを確認し、クラウドコンソールのアクティビティログを調べる必要がある。このプロセスは時間がかかり、信頼性も低い。プルリクエストの履歴は直接的な答えを与えてくれる。

スピードに関する懸念への対応

一部のチームは、インフラレビューが作業を遅くすると考えて抵抗する。特にインシデントや緊急アップデートの際には、インフラ変更を迅速に行う必要があると主張する。

現実には、レビューに費やす時間は、レビューなしの変更が本番を壊した後の復旧時間よりもほぼ常に短い。5分のレビューで2時間の障害を防げる。計算は単純だ。

インシデント中の緊急変更については、プロセスを適応させることができる。一部のチームは、まず変更を適用してサービスを復旧させ、その後でプルリクエストを作成してレビューする、インシデント後レビューモデルを使用する。重要なのは、レビューが依然として行われ、変更が文書化されることだ。プロセスは緊急時には柔軟に対応するが、消えてなくなるわけではない。

レビューの後に来るもの

インフラ変更がレビューを通過してマージされた後も、作業は終わらない。パイプラインは、適用前に実際に何が変更されるかを示す必要がある。これがプランステップだ。パイプラインはコードで定義された望ましい状態と現在のインフラ状態を比較し、差分を表示する。プランをレビューして正しいことを確認した後でのみ、パイプラインは変更の適用に進む。

このプランステップは重要だ。徹底的なコードレビューを行っても、プランは予期しない影響を明らかにすることがある。コード上では正しく見える変更でも、リソースを削除して再作成するプランが生成され、ダウンタイムを引き起こす可能性がある。プランは、問題が本番に到達する前にキャッチする最後のチャンスを与えてくれる。

インフラプルリクエストの実用的チェックリスト

  • 変更は実際の要件やリクエストと一致しているか?
  • すべての値は正しいか(ポート、インスタンスサイズ、CIDR範囲)?
  • セキュリティルールは、必要なトラフィックを許可しつつ、可能な限り制限的か?
  • 変更は他の環境と一貫性があるか?
  • 命名規則とタグ付け規則に従っているか?
  • 適用前に何が変更されるかを示すプラン出力があるか?

まとめ

インフラ変更は、アプリケーションコード変更と同じレビュープロセスに値する。悪いインフラ変更の結果は、悪いコード変更よりも深刻で診断が難しいことが多い。プルリクエストは、ミスを発見し、標準を強制し、履歴記録を維持するための構造化された方法を提供する。インフラ変更のレビューに投資する時間は、レビューなしの設定変更によって引き起こされる本番障害のデバッグに費やす時間を節約する。インフラコードをアプリケーションコードと同じ注意深さで扱えば、本番環境はそれに応えてくれる。