IaCを導入しても、コンソールでの手動変更ひとつでコードと実態は乖離していきます。この乖離「ドリフト」を検知し、放置せず是正し、そもそも起きにくくする仕組みを、一次情報に沿って整理します。

Infrastructure as Code(IaC)を導入すると、インフラの「あるべき姿」はコードに書かれます。ところが現実には、コンソールからの緊急対応や、別チームの手動操作によって、実際のインフラはコードから少しずつずれていきます。この乖離をドリフト(drift)と呼びます。ドリフトを放置すると、次のapplyで意図しない変更が走ったり、そもそもコードを信頼できなくなったりします。本記事では、なぜドリフトが起きるのか、どう検知し、どう是正し、そしてどう起きにくくするかを、一次情報に沿って整理します。

01なぜドリフトは起きるのか

ドリフトの発生源は、突き詰めるとほぼ一つです。IaCのワークフローを経由しない変更が加わることです。具体的には、次のような場面で起こります。

HashiCorpの定義でも、ドリフト検知とは「リソースがTerraformのワークフロー外で変更されたかどうかを判定すること」とされています。つまりドリフトは事故ではなく、複数人・複数チームで運用する以上、構造的に必ず発生するものです。だからこそ「起きない前提」ではなく「起きる前提で検知・是正する」設計が要になります。

現場のコツ:「誰が手動変更したか」を責める運用は長続きしません。障害対応で手を入れること自体は正当です。重要なのは、手動変更を後からコードへ取り込むフロー(下流の是正)と、そもそもコンソール変更を絞る仕組み(上流の抑止)を、両輪で用意することです。

02terraform planによる検知の基本

Terraform/OpenTofuでの検知の起点はterraform planです。HashiCorpの公式ドキュメントは「既定では、Terraformはterraform planまたはterraform applyを実行するたびに、ステートファイルと実インフラを比較する」と述べています。planはまずリフレッシュ(実インフラの現状取得)を行い、そのうえでコード・ステート・実態の三者を突き合わせます。

ただし通常のplanは「コードに合わせて何を変更するか」を示すため、ドリフトと本来の差分が混在します。ドリフトだけを純粋に見たい場合はterraform plan -refresh-onlyを使います。公式チュートリアルでは、この-refresh-onlyは「ステートファイルへの変更内容を確認する」ものであり、「インフラをコードに合わせて変更しようとはせず、ステートファイル上のドリフトをレビュー・追跡する選択肢を与えるだけ」と説明されています。-refresh-onlyはTerraform 0.15.4で導入され、古いterraform refreshサブコマンドより安全な確認手段として推奨されています。

ステート管理そのものの設計は検知の前提になります。ステートの分割やロック、バックエンド選定についてはStateファイルの管理と分割戦略もあわせてご確認ください。

03定期drift検知を自動化する

手元でplanを叩くだけでは、ドリフトは「気づいたときには手遅れ」になりがちです。実務では定期的な自動検知に落とし込みます。代表的な手段は二つです。

検知結果は、必ず人が気づくチャネル(チャット通知やチケット起票)に流します。アラート設計の考え方は監視とアラート設計の記事も参考になります。CIパイプライン全体の組み方はIaCのCI/CDパイプライン設計で扱っています。

定期スケジュール (日次cron等) plan -refresh-only 実インフラと ステートを比較 差分なし 正常(記録のみ) 差分あり 通知・起票 是正フローへ (セクション06)
図:定期ドリフト検知のフロー。refresh-only planで差分を判定し、差分ありのときだけ通知・起票して是正フローへつなぐ。

04GitOpsの継続的調整と自己修復

Kubernetesの世界では、ドリフトへの向き合い方が一歩進んでいます。GitOpsツール(Argo CD、Flux)は、Gitの宣言と実クラスタの状態を継続的に調整(reconcile)し続ける仕組みだからです。

Argo CDの公式ドキュメントによれば、自動同期(automated sync)は「Gitのマニフェストとクラスタ状態に差分を検知したときに自動で同期する」機能です。さらにself-healを有効にすると「実クラスタの状態がGitで定義された状態から逸脱したとき」に自動同期がかかります。つまり、誰かがkubectlで直接クラスタを変更しても、Argo CDがドリフトを検知してGitの状態へ戻します。self-healの再試行間隔は既定で5秒で、argocd-application-controller--self-heal-timeout-secondsフラグで制御されます。

ただし公式が明記するとおり、自動同期は既定ではリソースを削除しません。Gitから消えたリソースまで消したい場合はpruneを明示的に有効にする必要があります。また自動同期は対象アプリがOutOfSyncのときだけ走り、Syncedやエラー状態では試行されません。GitOpsの詳細はGitOpsとArgo CD / Fluxで扱っています。

現場のコツ:self-healとpruneは強力ですが、いきなり全アプリで有効にすると、障害対応中の手当てまで即座に巻き戻され現場が混乱します。まずは検知(OutOfSync表示)だけ有効にして運用に慣れ、対象を絞って段階的にself-heal・pruneへ広げるのが安全です。

05そもそも手動変更を起こさせない(SCP/権限)

検知と是正は「起きた後」の話です。より効くのは手動変更をそもそも起こさせない上流の抑止です。AWSでは、Service Control Policies(SCP)が代表的な手段になります。

AWSの公式ドキュメントによれば、SCPは組織内のIAMユーザー・ロールが持ちうる最大の権限の範囲を中央から制御します。SCPでDenyされたアクションは、そのアカウント内のどのエンティティも実行できず、個別のIAMポリシーでAllowされていても覆せません。この性質を使い、次のような設計が可能です。

ここでの狙いは「人間が手で変えられる余地を、意図的に狭める」ことです。IaC実行ロールにのみ変更権限を集約すれば、変更は必ずコードとパイプラインを通ります。SCPを使ったガードレール設計はマルチアカウント統制Organizations SCPによるガードレールで詳しく扱っています。最小権限の実務的な落とし込みはIAM最小権限の現実解もご覧ください。

06検知後の是正フロー

ドリフトを検知したら、機械的にapplyで潰すのは危険です。HashiCorpも「ドリフトの修正は手動プロセスである。なぜならTerraform外で加えられた変更を残すのか、上書きするのかを判断する必要があるから」と明言しています。是正は判断を伴う分岐です。検知した差分ごとに、次のいずれかを選びます。

重要なのは、この分岐判断を属人化させず記録に残すことです。ドリフト検知チケットに「破棄/取り込み/import」のどれを選び、なぜそうしたかを書く。これを積み重ねると、頻発するドリフトの発生源が可視化され、上流(SCPやモジュール設計)の改善につながります。

現場のコツ:「取り込む」を選んだ手動変更は、放置すると次の担当者にとって「なぜこうなっているか不明な設定」になります。取り込みの際は必ずコード側にコメントかコミットメッセージで背景を残し、コードを一次情報として維持してください。

07組織能力としてのドリフト対策

ドリフト対策は、ツール導入だけで完結しません。バージョン管理された宣言をソース・オブ・トゥルースとして維持できるか、という組織能力の問題でもあります。DORA(State of DevOps)は、バージョン管理を「再現性とトレーサビリティを担保し、変更速度が上がるほど重要になるセーフティネット」と位置づけています。ドリフト検知は、まさにこのセーフティネットが破れていないかの継続的な点検にあたります。

実務への落とし込みとしては、次の順序をおすすめします。まず(1)検知を定期自動化してドリフトを可視化する。次に(2)是正フローを分岐判断込みで運用に定着させる。そのうえで(3)上流の抑止(SCP・権限集約・GitOpsのself-heal)で発生頻度そのものを下げていく。この順で進めると、現場に無理なく定着します。

まとめ

ドリフトは、複数チームで運用する以上、構造的に必ず発生します。だからこそ「起きない前提」ではなく、terraform plan -refresh-onlyによる検知、定期自動化、GitOpsの継続的調整、そしてSCPによる上流の抑止を組み合わせ、「起きても素早く気づき、判断して是正する」設計に落とし込むことが要になります。是正では機械的な上書きを避け、破棄・取り込み・importの判断を記録に残すことで、コードを一次情報として維持し続けられます。EMWでは、この検知・是正・抑止のフローを、既存の運用体制に無理なく組み込むところまで伴走します。関連する導入事例もあわせてご覧ください。

参考(一次情報)

ドリフト検知の定期実行や、手動変更を抑止するガードレール設計でお困りの際は、お問い合わせください。現場の運用フローに落とし込むところまで伴走します。

相談する
← ブログ一覧へ戻る