In March 2023, a mid-sized fintech's security team discovered that 14 of their 60 production S3 buckets had public-read access enabled — despite Terraform state files showing every bucket locked down with block_public_acls = true. Someone had used the AWS console to unblock access during an emergency data-sharing request eight months earlier, and no one ever reverted it. The Terraform plan showed "no changes." The actual environment told a different story. This gap between what your IaC declares and what's actually running in your cloud account is called drift, and it's one of the least monitored attack surfaces in modern infrastructure. Manual hotfixes, console tweaks during incidents, auto-scaling side effects, and third-party automation all silently rewrite infrastructure state without ever touching a .tf file. By the time drift is discovered — often during an audit or, worse, a breach investigation — it has usually existed for months.
What Is IaC Drift, and Why Does It Happen?
IaC drift is any divergence between the configuration declared in your Terraform, CloudFormation, or Pulumi code and the configuration actually deployed in your cloud provider. It happens for four recurring reasons: manual console changes made under time pressure (an on-call engineer opening a security group port at 2 a.m.), out-of-band automation (a Lambda auto-remediation script, a third-party SaaS integration, or a CSPM tool "fixing" something without updating source), provider-side defaults changing between API versions, and partial or failed apply runs that leave resources in an inconsistent state. A 2023 survey by Env0 found that 76% of platform teams had experienced drift-related incidents, yet only 38% had automated drift detection running continuously. The rest rely on periodic manual terraform plan checks — often monthly or less — leaving weeks of unmonitored exposure between runs.
How Common Is Configuration Drift in Production Cloud Environments?
Drift is the rule, not the exception, in any environment older than a single sprint. Internal telemetry from cloud security posture tools consistently shows that 20-30% of resources in a typical AWS or Azure account no longer match their last-known IaC definition within 90 days of initial deployment. Common drifted resources include IAM policies (permissions added for a one-off integration and never removed), security group rules (temporary access for debugging that becomes permanent), and storage bucket ACLs. A widely cited 2022 incident involved a healthcare SaaS provider whose RDS instance had drifted to publicly accessible mode after a database migration script ran outside the normal Terraform pipeline — the instance sat exposed for 11 days before a routine scan caught it, despite the Terraform module explicitly setting publicly_accessible = false.
What Are the Security Risks of Undetected Drift?
Undetected drift breaks the core assumption that your IaC repository is a reliable security control — meaning your policy-as-code checks, peer reviews, and compliance attestations are all validating a document that no longer describes reality. If your Open Policy Agent or Checkov rules scan the Terraform source and pass, but the live resource has drifted to a non-compliant state, you get a false sense of assurance precisely where you need the most confidence. This matters most for three resource classes: identity and access management (a drifted IAM role with an extra AdministratorAccess attachment), network boundaries (a security group opened to 0.0.0.0/0 during troubleshooting), and encryption settings (a KMS key rotation disabled or an EBS volume created unencrypted by a script that bypassed the module). Each of these is also a top-five finding category in cloud breach post-mortems, including the 2019 Capital One breach, where a misconfigured web application firewall role — modified after initial deployment — allowed a server-side request forgery to reach internal metadata services.
Can Terraform State Alone Detect Drift?
No — Terraform state tracks what Terraform last applied, not what currently exists in the cloud, so relying on terraform plan alone catches only drift that Terraform itself is aware of and configured to reconcile. Running terraform plan will surface drift for resources fully managed in state, but it misses resources created outside Terraform entirely (a security group added by a different tool or team), attributes intentionally excluded via ignore_changes lifecycle blocks (a common pattern for autoscaling group desired counts that silently masks other drifted attributes on the same resource), and any changes made between scheduled plan runs. Terraform Cloud's own drift detection feature, generally available since 2022, only runs on a schedule you configure — commonly every 24 hours — which still leaves a window where a drifted, publicly exposed resource is invisible to your pipeline. Effective drift detection requires continuously comparing live cloud API state against declared configuration, independent of whether the drift originated inside or outside your IaC tooling.
How Do Real-World Breaches Trace Back to Drift?
Breaches trace back to drift when a temporary, manually-introduced change outlives the incident that justified it and is never re-audited against source. The 2021 breach of a well-known e-commerce platform's customer database began with a security group rule opened during a load-testing exercise to allow a testing vendor's IP range; the rule was never scoped back down, and eleven months later an unrelated credential-stuffing attack pivoted through that same open port to reach an internal database server. In each of these cases, the IaC repository — if anyone had checked it — still showed the "correct," locked-down configuration. The organization's own compliance evidence was technically accurate and practically wrong, which is exactly the failure mode that makes drift more dangerous than a straightforward misconfiguration: it defeats the audit trail meant to catch it.
How Safeguard Helps
Safeguard closes the gap between declared and actual cloud state by continuously reconciling live infrastructure against your IaC source of truth, not just re-running periodic plans. Safeguard ingests Terraform, CloudFormation, and Pulumi state alongside direct, read-only API polling of your AWS, Azure, and GCP accounts, then flags any resource attribute — IAM policy, security group rule, encryption setting, public access flag — that has diverged from source, including drift on resources created entirely outside your IaC pipeline. Findings are prioritized by exploitability and blast radius rather than raw count, so a drifted public S3 bucket holding customer data surfaces above a cosmetic tag mismatch. Each finding links directly to the responsible commit or console change where available, giving your team the "who and when" needed to close the loop instead of just the "what." For teams enforcing policy-as-code with OPA or Checkov, Safeguard extends that same policy set to live resources, so compliance checks that pass in CI can't be quietly invalidated by a change made after deployment. The result is an infrastructure security posture that reflects what's actually running in production, not just what the last commit said it should be.