Desired State and Actual State
coreintermediateInfrastructure as code describes a desired state: what should exist and how it should be configured. The account holds the actual state: what does exist right now. Drift is the difference between them, and it appears the moment anyone changes a resource outside the tool that created it.
Think of it as
The template is a claim about reality, not a copy of it. Nothing keeps the two in step automatically — a template is only applied when someone runs it, and the account accepts changes from anyone with permission. Drift is therefore the default outcome, and detecting it is a deliberate activity.
What we're doing: Decide what to do about a drifted resource, rather than reflexively reverting it.
- 1
- A drift report is a question, not an instruction — the tool cannot know whether the change was right.
- 7
- CloudTrail turns an anonymous difference into an attributable decision with a time and a person.
- 13
- Reverting a load-bearing manual change is one of the more common self-inflicted incidents.
- 19
- Either resolution ends with the template matching reality; that is what makes the next drift report meaningful.
Why this works: Drift is information about how the system is really operated. Treating every difference as a violation to be reverted destroys that information and creates outages; treating none of them as violations lets the template quietly become fiction. The middle path — attribute, decide, then write the decision into the template — is what keeps drift detection useful over time.
Treating a passing drift check as proof the template is complete
Wrong
Better
What you see: A resource type that does not support drift detection, or a property never written in the template, changes without anyone learning about it — while the dashboard stays green.
Why: IN_SYNC is a statement about the comparison that was performed, not about the account. Resources that do not support drift detection are reported as NOT_CHECKED, unset properties are excluded by design, and nested stacks are not covered — so the green status is bounded in three directions at once.
- A diagram with two boxes side by side and a labelled gap between them.
- On the left, desired state: the template in version control, describing what should exist, reviewed and reproducible.
- On the right, actual state: the resources in the account, changed by deploys, by consoles, by scripts, and by services acting on your behalf.
- Between them a gap labelled drift, with the note that it appears whenever a change is made outside the tool.
- Below, four routes to closing the gap: update the template to match reality, redeploy the template over reality, import an unmanaged resource into the stack, or accept and record the difference as a documented exception.
Where drift comes from, and how visible it is
Together
Remember: The template is a claim; the account is the fact; drift is the gap, and it is the default outcome rather than an anomaly. Only explicitly set properties are compared, so set them even at their defaults, and resolve every drift by deciding which side was right and writing that decision back into the template.
See also: cloudformation drift detection · immutable over console changes · reproducible and reviewable infrastructure · configuration recorder items and history

