Independent of how you manage your infrastructure - manual, automated, declarative or imperative - there is always the chance, that the actual state of your infrastructure differs from the state you want it to be. This is called drift. We want to minimize, or if possible completely remove any drift, to have an infrastructure which matches our expectations. This has some security aspects when permissions are drifting away from expected permissions and allowing more than necessary and can also have a drastic impact on developer experience. If a developer knows the state of the infrastructure it is way easier to trace and fix bugs or even add new infrastructure. This does also make your infrastructure reproducible e.g. over different environments. If your dev environment drifts away from the declared infrastructure your tests are meaningless, because you cannot reproduce the same behavior on production.
I will not further focus on manual or imperative setups, because I would not consider them reproducible by itself.
Drift can be introduced very easily. Imagine a setup on AWS where a lambda function tries to connect to any other service but always result in a timeout. Your first guess is a missing rule in the security group. You just add the new rule via the console to try things quick, and now the lambda works seamless, but at what cost. You just introduced some drift into your infrastructure. The actual state (rules in the security group) defer from what your previously declared via OpenTofu or CDK. The drift definitely should be fixed. That is where drift detection comes into play. We need some automation to detect such drift align the declared state and the actual state again.
For drift detection you typically have at least two states describing an outcome, e.g. the state you declared your infrastructure and the actual state of your infrastructure. These two could drift away from each other. We would like to keep them in sync, so that changes to the declared infrastructure are reproducible and predictable. Remember the previous example, if another developer deploys this into another account, things won't work, because the security group is missing a rule, again. To fix this, one of two states has to be adjusted so that both of them match again. While there are different approaches in how different tools handle and work with drift, i will take a quick look on OpenTofu and the CDK, which uses CloudFormation under the hood, as they differ in some fundamental steps, mostly because of the CloudFormation layer.
OpenTofu keeps it state stored in a file (or any other remote state management solution) to keep track of all the resources and map the declared infrastructure to real resources. When a deployment takes place the real resources are compared to the desired state which is than be applied. With this approach your real infrastructure should always be in the same state as your declared infrastructure. It is up to the provider implementation, how to retrieve the actual state, set the desired state or when a resource has to completely recreated. When a provider does not implement setting a specific property, the property can not be managed through tofu at all.
The CDK handles things a little different. The CDK is another layer over CloudFormation, so there are nothing the CDK can do, which CloudFormation can not. CloudFormation uses a template to define resources and their state. When using the CDK the same template is generated e.g. from a TypeScript project, which will then be applied. When changing resources the CDK creates a CloudFormation ChangeSet which will then be applied to the initial template. CloudFormation, by default only compares the state in the template with the newly declared state. When someone modifies a resource by hand, this is not projected in the CloudFormation template, and this will not be corrected, when the ChangeSet is applied. There is the possibility to perform a drift check within the AWS console, which compares the state of actual resources, with the state in the template. When drift is detected, the user has to manually fix it, which is pretty annoying. That said, there is one more thing, the drift detection only compares selected attributes. If an attribute is not implemented as part of the drift detection but can be set through CloudFormation any manual change will never be detected. In May 2025 the CDK implemented the drift command to be able to detect drift through the cli. In November 2025 CloudFormation got drift aware ChangeSets. This is the first time, that AWS can do a 3-way-comparison. By a 3-way-comparison your actual infrastructure is compared to the declared state in the template and the new state in the ChangeSet. If you manually modified a resource and introducing drift to your template AWS does not modify the actual resource, but only the template, when a drift aware ChangeSet is applied which declares the actual state as the new state, as the resource already is in the state. To complete the circle we got the --revert-drift flag in March 2026 to be able to create drift aware ChangeSets through the CDK 🎉.
This is great, to reduce the amount of drift. As a last step AWS could implement CloudFormation/AWS API in a way that each Attribute which can be set through CloudFormation or the Console can also be retrieved through CloudFormation or the API as this would allow to detect all drift which could potentially be created. Which would be great and make the lives of some developers, including mine, easier. Depending on the tool drift management can be hard, but I don't have to and especially does not necessarily need manual interaction to track and fix.
You can now use --revert-drift within CDK modifications to reduce the drift between your actual infrastructure and your declared infrastructure, and you probably should use it.