Dev Study
AWSサービスの内部原理 コース

119. ドリフトは宣言と現実のずれである — 検出という照合作業とスタックポリシーという安全柵

CloudFormationのテンプレートに「こうあるべき」と書いた状態と、いま実際にAWS上にある状態がずれる問題を、検出の仕組みと防止の仕組みの両面から図で追っていきます。

① ドリフトとは「宣言」と「実体」のずれである

テンプレート(宣言)期待される状態
「InstanceTypeはt3.microのはず」
誰かがEC2コンソールから直接 t3.large に変更(CFnの外側の操作)
実際のリソース(実体)デプロイ直後は宣言=実体で一致
DRIFTED実体が宣言から漂流した
宣言: t3.micro / 実体: t3.large
  • 「Users can change those resources outside of CloudFormation... by using the underlying service that created the resource」
  • 「a stack's actual configuration differs, or has drifted, from its expected configuration」
  • 変更は事故のこともあれば、緊急対応で意図的なこともある。どちらでも、外側の変更はその後のスタック更新・削除を複雑にする。

ドリフトとは「テンプレートに書いた期待状態」と「いま実際にある状態」のずれのこと。CloudFormationの外側でリソースを直接変更すると発生し、後続のスタック操作を難しくする。

② 検出は「期待値」と「実測値」の照合である

テンプレート+パラメータ期待値を算出
現在のリソース実測値を取得
一致 / 不一致・削除で分岐
照合expected ?= actual
IN_SYNC漂流していない
DRIFTED不一致または削除あり
  • 「CloudFormation determines the expected resource property values, as defined in the stack template and any values specified as template parameters ... then compares those expected values with the actual values」
  • 「A resource is considered to have drifted if any of its actual property values differ from the expected property values. This includes if the property or resource has been deleted.」

検出は「テンプレート+パラメータから求めた期待値」と「実在する実測値」のプロパティ単位の照合。可観測性編のアラームが期待の範囲と実測を比べたのと同じreconciliationを、設定値の世界でやっている。

③ ステータスはスタック→リソース→プロパティの3階層

ADD配列/リストに値が追加
REMOVEプロパティが削除された
NOT_EQUAL値が期待値と異なる
1つでもリソースがDRIFTED → スタックもDRIFTED
MODIFIED期待構成と異なる
DELETEDリソースごと消滅
IN_SYNC一致
NOT_CHECKED未照合
DRIFTED
IN_SYNC
NOT_CHECKED
  • ADD=配列/リスト型のプロパティに値が追加された / REMOVE=プロパティが現在の構成から削除された / NOT_EQUAL=現在の値がテンプレート上の期待値と異なる(公式の定義)
  • リソースのDELETED=リソースそのものが削除されている / MODIFIED=期待構成と異なる
  • 「A stack is considered to have drifted if one or more of its resources have drifted.」

状態はプロパティ差分(ADD/REMOVE/NOT_EQUAL)→リソース(MODIFIED/DELETED/IN_SYNC/NOT_CHECKED)→スタック(DRIFTED/IN_SYNC/NOT_CHECKED)とボトムアップに集約される。下位のドリフトが上位へ伝播する。

④ 検出の盲点 — 「明示的に書いた」ものだけが照合される

テンプレートに書いたか?
ほかにも判定されないものがある
明示的に設定照合対象・ドリフト判定される
デフォルト値任せ照合対象外=盲点
追跡したければデフォルト値でも明示的に書く
未サポートリソースNOT_CHECKEDになる
ネストされた子スタック親の検出に非包含・個別に検出を実行
  • 「CloudFormation only determines drift for property values that are explicitly set ... This doesn't include default values ... explicitly set the property value, even if you are setting it to the default value.」
  • 「When detecting drift on a stack, CloudFormation does not detect drift on any nested stacks ... you can initiate a drift detection operation directly on the nested stack.」
  • 検出可能なスタック状態: CREATE_COMPLETE / UPDATE_COMPLETE / UPDATE_ROLLBACK_COMPLETE / UPDATE_ROLLBACK_FAILED
  • スタックレベルのタグもドリフト判定の対象。

照合されるのは明示的に宣言したプロパティだけ。デフォルト任せのプロパティ・未サポートのリソース・ネストされた子スタックはドリフト判定されない。追跡したい値はデフォルトと同じでも明示的に書くのが対策。

⑤ スタックポリシー — 更新事故を防ぐJSONの安全柵

スタックポリシー更新操作の許可/拒否を定めるJSON
ポリシーを1つ設定した瞬間に反転
EffectAllow / Deny
ActionUpdate:Modify / Replace / Delete / *
Principal「*」のみサポート・必須
ResourceLogicalResourceId/論理ID
ConditionResourceTypeで型を絞る
設定前: 全許可全更新アクションが通る
設定後: 全保護明示Allowのない更新はすべて拒否
  • Action 4種: Update:Modify=無停止/一部停止・物理ID維持 / Update:Replace=作り直しで物理IDが変わりうる / Update:Delete=削除 / Update:*=全更新操作
  • 「When you create a stack, all update actions are allowed on all resources.」
  • 「After you set a stack policy, all of the resources in the stack are protected by default. To allow updates on specific resources, you specify an explicit Allow statement」
  • 「The Principal element is required, but supports only the wild card (*)」
  • Condition は ResourceType を StringEquals / StringLike で指定(ワイルドカードを使うときは StringLike 必須)。

スタックポリシーはEffect/Action/Principal/Resource/Conditionの5要素からなるJSON。設定した瞬間に全リソースがデフォルト保護へ反転し、明示的なAllowがなければどんな更新も通らない。

⑥ Denyが常に勝つ — IAMと同じ競合解決、ただし更新中だけ

Allow Update:*Resource: * — 全体は更新OK
Deny Update:ReplaceResource: LogicalResourceId/ProductionDatabase
Denyが常にAllowに勝つ
Update:ModifyAllowに該当 → 通る(無停止変更)
Update:ReplaceAllowとDenyの両方に該当
置換だけ拒否置換=データ喪失を構造的に防ぐ
働くのはスタック更新の間だけ。コンソール直接操作は止められない(それは④のドリフトの世界)
  • 「a Deny statement always overrides an Allow statement. To ensure that a resource is protected, use a Deny statement」
  • 「A stack policy applies only during stack updates. It doesn't provide access controls like an ... (IAM) policy. Use a stack policy only as a fail-safe mechanism ... To control access to AWS resources or actions, use IAM.」
  • 本番DBを消したくなければIAMで権限を絞るのが本筋。スタックポリシーはその手前に置く「うっかり更新」へのフェイルセーフ。

AllowとDenyが重なればDenyが常に勝つ——認証暗号編のIAM評価と同じ競合解決規則が、適用範囲「更新中だけ」という違いを伴って再登場。本番DBのUpdate:Replaceだけを拒否すれば、置換によるデータ喪失を構造的に防げる。

⑦ 一時的上書きと、消せないポリシー

恒久ポリシー本番DBをDeny
書き換え不要・そのまま
更新が1回だけ通る
一時的上書きポリシー対象リソースへのAllowを含めて渡す
ポリシーそのものをやめたいときは
恒久ポリシーは元のまま上書きは今回の更新にのみ適用・自動で元に戻る
削除は不可「柵を撤去する」操作は存在しない
全許可へ書き換えAllow / Update:* / Principal:* / Resource:*
  • 「create a temporary policy that overrides the stack policy ... The override policy doesn't permanently change the stack policy.」
  • 「CloudFormation applies the override policy only during this update.」
  • 「You can't delete a stack policy. To remove all protection from all resources, you modify the policy to explicitly allow all actions on all resources.」
  • CLI: 恒久設定は set-stack-policy、更新1回だけの上書きは update-stack の --stack-policy-during-update-body / -url。

保護されたリソースを更新したいときは、その1回だけ有効な上書きポリシーを渡す——恒久設定は変わらない。そしてスタックポリシーは削除できず、保護を外すには全許可ポリシーへ書き換えるしかない。

公式ドキュメントで詳しく ↗