Drift Detection¶
Cloudrift detects configuration drift by comparing your Terraform plan JSON against the actual state of AWS resources. Unlike post-apply tools like driftctl, Cloudrift catches drift before terraform apply.
How It Works¶
graph LR
A["Terraform Plan<br/>(JSON)"] --> C["Cloudrift"]
B["Live AWS State<br/>(API calls)"] --> C
C --> D["Drift Report"] - Parse — Cloudrift reads
resource_changes[].change.afterfrom your Terraform plan JSON - Fetch — Queries AWS APIs for the current state of each resource
- Compare — Attribute-by-attribute comparison between planned and live state
- Report — Outputs differences with severity levels
Supported Services¶
S3 Buckets¶
| Attribute | Description |
|---|---|
| ACL | Bucket access control list (private, public-read, etc.) |
| Tags | Resource tags (key-value pairs) |
| Versioning | Whether versioning is enabled |
| Encryption | Server-side encryption algorithm (AES256, aws:kms) |
| Logging | Access logging configuration |
| Public Access Block | Block public ACLs, policies, and bucket access |
| Lifecycle Rules | Object lifecycle management rules |
S3 attributes are fetched in parallel using Go's errgroup — all 7 API calls per bucket run concurrently.
EC2 Instances¶
| Attribute | Description |
|---|---|
| Instance Type | Instance size (t3.micro, m5.large, etc.) |
| AMI | Amazon Machine Image ID |
| Subnet | VPC subnet placement |
| Security Groups | Attached security group IDs |
| Tags | Resource tags |
| EBS Optimization | Whether EBS-optimized storage is enabled |
| Monitoring | Detailed monitoring status |
EC2 instances are fetched with pagination to support large fleets.
IAM Resources¶
| Attribute | Description |
|---|---|
| Roles — Trust Policy | AssumeRolePolicyDocument (JSON-normalized comparison) |
| Roles — Max Session | Maximum session duration in seconds |
| Roles — Description | Role description text |
| Roles — Path | IAM path for the role |
| Roles — Attached Policies | Managed policy ARNs attached to the role |
| Users — Path | IAM path for the user |
| Users — Attached Policies | Managed policy ARNs attached to the user |
| Policies — Document | Policy document JSON (JSON-normalized comparison) |
| Policies — Description | Policy description text |
| Policies — Path | IAM path for the policy |
| Groups — Path | IAM path for the group |
| Groups — Attached Policies | Managed policy ARNs attached to the group |
| Groups — Members | Group membership (user names) |
| All — Tags | Resource tags (key-value pairs) |
IAM resources (roles, users, policies, groups) are fetched in parallel using errgroup. AWS service-linked roles and AWS-managed policies are excluded to focus on customer-managed resources. Policy documents and trust policies are compared using JSON normalization to avoid false positives from formatting differences.
Drift Types¶
Missing Resources¶
A resource exists in the Terraform plan but not in AWS. This is flagged as critical severity.
Attribute Differences¶
A resource exists in both plan and AWS but has different attribute values.
Extra Tags¶
Tags exist in AWS but are not defined in the Terraform plan.
Pre-Apply vs Post-Apply¶
| Aspect | Cloudrift (Pre-Apply) | driftctl (Post-Apply) |
|---|---|---|
| When | Before terraform apply | After terraform apply |
| Input | Terraform plan JSON | Terraform state file |
| Catches | Config someone changed manually | State file vs live |
| Use case | CI/CD gate, code review | Ongoing monitoring |
| Risk | None — read-only | None — read-only |
Complementary tools
Cloudrift and post-apply tools serve different purposes. Use Cloudrift in CI/CD to catch drift before deploying, and a post-apply tool for ongoing monitoring.