Claude
Skills
Sign in
Back

drift-detector

Included with Lifetime
$97 forever

Detect infrastructure drift between Terraform state and actual cloud resources. Identifies unmanaged resources, manual changes, and configuration drift. Use when: - User asks to check for infrastructure drift - User wants to find unmanaged cloud resources - User mentions "drift detection" or "Terraform drift" - User asks to compare cloud state to IaC - User wants to audit infrastructure changes

Cloud & DevOps

What this skill does


# Infrastructure Drift Detector

Detect, track, and resolve infrastructure drift between Terraform state and actual cloud resources to maintain Infrastructure as Code integrity.

**Core Principle**: Your cloud should match your code.

**Note**: This skill uses `snyk iac describe` CLI command (requires shell execution).

---

## Quick Start

```bash
# Basic drift scan against a local Terraform state file
snyk iac describe --from=tfstate://terraform.tfstate

# Output as JSON for further analysis
snyk iac describe --from=tfstate://terraform.tfstate --json > drift-report.json
```

---

## Prerequisites

- Terraform project with state file (local or remote)
- Cloud provider credentials configured
- `snyk` CLI installed
- Network access to cloud APIs

### Supported Cloud Providers

| Provider | Setup |
|----------|-------|
| **AWS** | AWS credentials (profile, env vars, or IAM role) |
| **Azure** | Azure CLI login or service principal |
| **GCP** | Application default credentials or service account |

For a full list of supported resource types per provider, see `SERVICES.md`.

---

## Phase 1: Setup

**Goal**: Configure drift detection environment.

### Step 1.1: Verify Terraform State

Check for Terraform state:

**Local state**:
```bash
ls terraform.tfstate
```

**Remote state** (S3 backend):
```hcl
terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "state/terraform.tfstate"
    region = "us-east-1"
  }
}
```

### Step 1.2: Verify Cloud Credentials

**AWS**:
```bash
aws sts get-caller-identity
```

**Azure**:
```bash
az account show
```

**GCP**:
```bash
gcloud auth application-default print-access-token
```

---

## Phase 2: Run Drift Detection

**Goal**: Identify differences between IaC and actual cloud state.

### Step 2.1: Basic Drift Scan

```bash
snyk iac describe --from=tfstate://terraform.tfstate
```

### Step 2.2: Remote State Scan

For S3 backend:
```bash
snyk iac describe --from=tfstate+s3://my-bucket/state.tfstate
```

For Terraform Cloud:
```bash
snyk iac describe \
  --from=tfstate+tfcloud://organization/workspace \
  --tfc-token=$TFC_TOKEN
```

### Step 2.3: Specific Service Scan

To focus on specific AWS services:
```bash
snyk iac describe \
  --from=tfstate://terraform.tfstate \
  --service=aws_s3,aws_ec2,aws_rds
```

### Step 2.4: JSON Output for Analysis

```bash
snyk iac describe \
  --from=tfstate://terraform.tfstate \
  --json > drift-report.json
```

---

## Phase 3: Analyze Results

**Goal**: Understand and categorize drift.

### Step 3.1: Drift Categories

| Category | Description | Risk Level |
|----------|-------------|------------|
| **Unmanaged** | Resources not in Terraform | High - shadow IT |
| **Changed** | Resources modified outside Terraform | Medium - config drift |
| **Missing** | Resources in state but deleted | Low - usually intentional |

### Step 3.2: Generate Report

```
## Infrastructure Drift Report

Scan Date: 2024-01-15
Terraform State: s3://my-bucket/prod.tfstate
Cloud Provider: AWS (us-east-1)

### Summary
- Unmanaged Resources: 12 (High)
- Changed Resources:    5  (Medium)
- Missing Resources:    2  (Low)
- Total Drift:         19

### Unmanaged Resources (Not in Terraform)
- aws_s3_bucket      | prod-logs-manual   | High     | Import or delete
- aws_security_group | sg-temp-access     | Critical | Review and remove

### Changed Resources (Modified Outside Terraform)
- aws_security_group.web | ingress: [443]   → ingress: [443, 22]  | High
- aws_rds_instance.main  | multi_az: true   → multi_az: false      | Critical
```

### Step 3.3: Risk Assessment

Prioritize **Critical** issues first (e.g. SSH opened to 0.0.0.0/0, production HA disabled), then **High** risk issues (e.g. unmanaged IAM users or security groups). Document the affected resource, the risk, and the intended remediation action for each finding.

---

## Phase 4: Remediation

**Goal**: Resolve drift and restore IaC integrity.

### Step 4.1: Import Unmanaged Resources

For resources that should be in Terraform:

```bash
# Generate import block
terraform import aws_s3_bucket.manual_bucket prod-logs-manual

# Or use import block (Terraform 1.5+)
```

```hcl
import {
  to = aws_s3_bucket.manual_bucket
  id = "prod-logs-manual"
}
```

### Step 4.2: Remove Unauthorized Resources

For resources that shouldn't exist:

```bash
# After verification, delete unmanaged resources
aws s3 rb s3://unauthorized-bucket --force
aws ec2 terminate-instances --instance-ids i-temp-server
```

### Step 4.3: Revert Changes

For resources modified outside Terraform:

```bash
# Re-apply Terraform to restore intended state
terraform apply
```

### Step 4.4: Update Terraform (Adopt Changes)

If the manual change should be kept:

```hcl
# Update Terraform to match new reality
resource "aws_security_group" "web" {
  # Add the new rule
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"]  # Restrict if keeping
  }
}
```

---

## Phase 5: Prevention

**Goal**: Prevent future drift.

### Step 5.1: Generate Exclude Policy

For expected drift (auto-scaling, etc.):

```bash
snyk iac update-exclude-policy \
  --exclude-unmanaged \
  --exclude-changed
```

This creates a `.snyk` policy file:

```yaml
exclude:
  iac-drift:
    - aws_autoscaling_group.*
    - aws_ecs_service.*:desiredCount
```

### Step 5.2: CI/CD Integration

Add drift detection to CI/CD:

```yaml
# GitHub Actions example
- name: Check for Infrastructure Drift
  run: |
    snyk iac describe \
      --from=tfstate+s3://my-bucket/prod.tfstate \
      --json > drift.json
    
    # Fail if unmanaged resources found
    if [ $(jq '.summary.total_unmanaged' drift.json) -gt 0 ]; then
      echo "Drift detected!"
      exit 1
    fi
```

### Step 5.3: Regular Audits

Schedule regular drift audits:

| Frequency | Scope | Purpose |
|-----------|-------|---------|
| Daily | Critical resources | Security monitoring |
| Weekly | All production | Configuration audit |
| Monthly | All environments | Comprehensive review |

---

## Common Scenarios

For detailed worked examples, see `EXAMPLES.md`. Brief references:

- **Post-Incident Audit**: Run drift detection with JSON output, filter for security-related resources, identify unauthorized changes, generate incident report, remediate and document.
- **Pre-Deployment Check**: Run drift detection, fail deployment if drift exists, resolve drift first, then proceed with deployment.
- **Shadow IT Discovery**: Run drift detection, filter to unmanaged resources, categorize by owner/purpose, import or remove as appropriate.

---

## Error Handling

### State Access Error

```
Error: Could not read Terraform state

Solutions:
1. Verify state file path
2. Check S3/backend permissions
3. Ensure terraform init has been run
```

### Cloud Credential Error

```
Error: Authentication failed

Solutions:
1. Verify cloud credentials
2. Check IAM permissions for describe/list
3. Ensure credentials not expired
```

### Service Not Supported

```
Warning: Service X not supported

Solutions:
1. Check supported services list
2. Use Terraform plan comparison instead
3. Report to Snyk for feature request
```

---

## Constraints

1. **Read-only**: This skill only detects drift, doesn't modify resources
2. **Credentials required**: Needs cloud provider access
3. **Service coverage**: Not all resource types supported
4. **State required**: Must have Terraform state to compare
5. **Network required**: Needs access to cloud APIs

Related in Cloud & DevOps