CloudFormation のドリフト検出はどこまで見ているのか - 手動変更を追跡する仕組みと限界
CloudFormation のドリフト検出が内部でどのようにリソースの現在状態とテンプレートの期待状態を比較しているのか、検出できる変更と検出できない変更の境界、ドリフト修復の戦略を解説します。
ドリフトとは何か - テンプレートと現実の乖離
CloudFormation のドリフトとは、スタックのテンプレートで定義された期待状態と、リソースの実際の状態が異なっている状態です。たとえば、テンプレートで EC2 インスタンスのインスタンスタイプを t3.medium と定義しているのに、誰かがコンソールから t3.large に変更した場合、ドリフトが発生しています。ドリフトは、Infrastructure as Code (IaC) の根本的な課題です。テンプレートでインフラを管理していても、コンソールや CLI で手動変更が行われると、テンプレートと現実が乖離します。次にスタックを更新する際、手動変更が上書きされて意図しない動作が発生したり、テンプレートの変更が手動変更と競合してエラーになったりします。ドリフト検出は 2018 年に導入された機能で、この乖離を検出して可視化します。
ドリフト検出の内部動作
ドリフト検出を実行すると、CloudFormation はスタック内の各リソースについて以下の処理を行います。第 1 に、テンプレートから期待状態を読み取ります。テンプレートに定義されたプロパティの値が期待状態です。第 2 に、各リソースの実際の状態を AWS API で取得します。EC2 インスタンスなら DescribeInstances、S3 バケットなら GetBucketPolicy や GetBucketEncryption など、リソースタイプごとに適切な API を呼び出します。第 3 に、期待状態と実際の状態をプロパティ単位で比較します。差異があるプロパティは MODIFIED として報告されます。テンプレートに定義されていないプロパティが追加されている場合は ADD、テンプレートに定義されているプロパティが削除されている場合は REMOVE として報告されます。ドリフト検出は非同期処理です。大規模なスタック (数百のリソース) では、すべてのリソースの状態を取得するのに数分かかることがあります。各リソースの API 呼び出しにはスロットリングの制約があるため、並列度を制御しながら順次処理されます。
検出できる変更と検出できない変更
ドリフト検出には重要な制約があります。第 1 に、すべてのリソースタイプがドリフト検出をサポートしているわけではありません。2024 年時点で約 500 のリソースタイプのうち、ドリフト検出をサポートしているのは約 300 です。サポートされていないリソースタイプは、ドリフト検出の対象外となり、NOT_CHECKED として報告されます。第 2 に、テンプレートに明示的に定義されたプロパティのみが比較対象です。テンプレートで省略してデフォルト値が適用されたプロパティは、手動で変更されてもドリフトとして検出されません。たとえば、テンプレートで EC2 インスタンスの Monitoring プロパティを省略した場合 (デフォルト: false)、コンソールから詳細モニタリングを有効にしてもドリフトとして検出されません。第 3 に、リソースの削除は検出できますが、スタック外で作成されたリソースは検出できません。誰かがスタックとは無関係に手動で EC2 インスタンスを起動しても、CloudFormation はそれを知りません。スタック外のリソースの検出には AWS Config が必要です。
ドリフトの修復戦略
ドリフトが検出された場合、修復には 3 つのアプローチがあります。第 1 に、手動変更を元に戻す方法です。テンプレートの定義が正しく、手動変更が誤りである場合、スタックを更新 (テンプレートは変更せず、パラメータも変更せず) すれば、CloudFormation がリソースをテンプレートの状態に戻します。ただし、一部のプロパティの変更はリソースの置換 (Replace) を伴うため、注意が必要です。第 2 に、テンプレートを現実に合わせる方法です。手動変更が正当なもの (緊急対応で変更した設定など) である場合、テンプレートを更新して現実の状態を反映させます。CloudFormation のインポート機能を使用すれば、手動で作成されたリソースをスタックに取り込むこともできます。第 3 に、ドリフトを許容する方法です。一部のプロパティ (Auto Scaling Group の DesiredCapacity など) は、運用中に動的に変更されることが前提です。これらのプロパティのドリフトは正常な動作であり、修復の必要はありません。
ドリフトを防止する仕組み
ドリフトを検出するよりも、そもそもドリフトを発生させない仕組みを構築する方が効果的です。CloudFormation のスタックポリシーは、特定のリソースの更新を禁止するポリシーです。ただし、スタックポリシーはスタック更新時にのみ適用され、コンソールや CLI からの直接変更は防止できません。IAM ポリシーで、CloudFormation 以外からのリソース変更を禁止する方法が最も確実です。たとえば、EC2 インスタンスの ModifyInstanceAttribute アクションを、CloudFormation のサービスロールからの呼び出しのみ許可し、ユーザーからの直接呼び出しを拒否するポリシーを設定します。AWS Config のルールを使用して、ドリフトを継続的に監視することも有効です。cloudformation-stack-drift-detection-check ルールは、定期的にドリフト検出を実行し、ドリフトが検出されたスタックを非準拠として報告します。Config の修復アクション (Remediation Action) と組み合わせれば、ドリフトの自動修復も可能です。IaC の運用を体系的に学ぶには、専門書籍 (Amazon)が参考になります。