drifty 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- drifty-0.1.0/LICENSE +21 -0
- drifty-0.1.0/PKG-INFO +273 -0
- drifty-0.1.0/README.md +246 -0
- drifty-0.1.0/drifty/.DS_Store +0 -0
- drifty-0.1.0/drifty/__init__.py +5 -0
- drifty-0.1.0/drifty/cli.py +313 -0
- drifty-0.1.0/drifty/cloudtrail.py +308 -0
- drifty-0.1.0/drifty/config.py +269 -0
- drifty-0.1.0/drifty/reporter.py +349 -0
- drifty-0.1.0/drifty/scanner.py +330 -0
- drifty-0.1.0/drifty/scorer.py +216 -0
- drifty-0.1.0/pyproject.toml +67 -0
drifty-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Satyajit Dey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
drifty-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drifty
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Terraform drift intelligence: detect, attribute, score, and fix IaC drift
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: terraform,drift,devops,sre,infrastructure,iac
|
|
8
|
+
Author: Satyajit Dey
|
|
9
|
+
Author-email: satyajit.dey@umbc.edu
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Topic :: System :: Systems Administration
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Requires-Dist: boto3 (>=1.34,<2.0)
|
|
20
|
+
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
21
|
+
Requires-Dist: rich (>=13.0,<15.0)
|
|
22
|
+
Requires-Dist: typer[all] (>=0.12,<1.0)
|
|
23
|
+
Project-URL: Bug Tracker, https://github.com/satyajit-dey-17/drifty/issues
|
|
24
|
+
Project-URL: Homepage, https://github.com/satyajit-dey-17/drifty
|
|
25
|
+
Project-URL: Repository, https://github.com/satyajit-dey-17/drifty
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# 🔍 drifty
|
|
29
|
+
|
|
30
|
+
> Terraform drift intelligence — detect what changed, who changed it, how dangerous it is, and how to fix it.
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/drifty/)
|
|
33
|
+
[](https://pypi.org/project/drifty/)
|
|
34
|
+
[](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install drifty
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The Problem
|
|
44
|
+
|
|
45
|
+
`terraform plan` tells you **what** drifted. It doesn't tell you **who** changed it, **how dangerous** the change is, or **what to do** about it.
|
|
46
|
+
|
|
47
|
+
Manual changes in the AWS console during incidents, auto-scaling events, and ad-hoc CLI commands silently diverge your infrastructure from your Terraform state. By the time you notice, you don't know if it was a colleague, a runbook, or a security incident.
|
|
48
|
+
|
|
49
|
+
Enterprise platforms like Spacelift and HCP Terraform Cloud detect drift on a schedule — but they're full IaC platforms that are heavyweight, expensive, and still offer zero attribution or severity intelligence.
|
|
50
|
+
|
|
51
|
+
**drifty fills this exact gap.**
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Demo
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
$ drifty scan --workspace ./infra --attribute
|
|
59
|
+
|
|
60
|
+
🔍 drifty — Terraform Drift Intelligence
|
|
61
|
+
Scanning workspace: ./infra | 2026-06-05 14:00 UTC
|
|
62
|
+
|
|
63
|
+
╭─────────────────────────────────────────────────────────────╮
|
|
64
|
+
│ 3 drifts detected - 1 Critical - 1 High - 1 Low │
|
|
65
|
+
╰─────────────────────────────────────────────────────────────╯
|
|
66
|
+
|
|
67
|
+
🔴 CRITICAL aws_security_group.main (sg-0abc1234)
|
|
68
|
+
Changed: ingress.0.cidr_blocks → ["0.0.0.0/0"] (was: ["10.0.0.0/8"])
|
|
69
|
+
Who: arn:aws:iam::123456789:user/john.doe
|
|
70
|
+
When: 2026-06-03 14:22:11 UTC
|
|
71
|
+
Action: ModifySecurityGroupRules
|
|
72
|
+
Fix: terraform import aws_security_group.main sg-0abc1234
|
|
73
|
+
|
|
74
|
+
🟠 HIGH aws_instance.api_server (i-0def5678)
|
|
75
|
+
Changed: instance_type → t3.large (was: t3.medium)
|
|
76
|
+
Who: arn:aws:iam::123456789:role/ops-automation
|
|
77
|
+
When: 2026-06-02 09:15:44 UTC
|
|
78
|
+
Action: ModifyInstanceAttribute
|
|
79
|
+
Fix: terraform import aws_instance.api_server i-0def5678
|
|
80
|
+
|
|
81
|
+
🟢 LOW aws_s3_bucket.assets (assets-bucket-prod)
|
|
82
|
+
Changed: tags.LastModified → "2026-06-01" (was: "2026-05-15")
|
|
83
|
+
Who: attribution unavailable (event outside 90-day CloudTrail window)
|
|
84
|
+
Fix: Add tag to Terraform config or run terraform apply to reconcile
|
|
85
|
+
|
|
86
|
+
──────────────────────────────────────────────────────────────
|
|
87
|
+
Run `drifty report --format markdown` to export this as a report.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Install
|
|
93
|
+
|
|
94
|
+
**Requirements:** Python 3.10+, Terraform 1.1+, AWS credentials configured
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install drifty
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Quick Start
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 1. Initialize config in your Terraform workspace
|
|
106
|
+
cd ./infra
|
|
107
|
+
drifty init
|
|
108
|
+
|
|
109
|
+
# 2. Scan for drift
|
|
110
|
+
drifty scan
|
|
111
|
+
|
|
112
|
+
# 3. Scan with CloudTrail attribution (who caused each drift)
|
|
113
|
+
drifty scan --attribute
|
|
114
|
+
|
|
115
|
+
# 4. Filter to critical and high only
|
|
116
|
+
drifty scan --severity high
|
|
117
|
+
|
|
118
|
+
# 5. Output as JSON (for CI/CD piping)
|
|
119
|
+
drifty scan --output json | jq '.findings[] | select(.severity=="critical")'
|
|
120
|
+
|
|
121
|
+
# 6. Export a markdown report
|
|
122
|
+
drifty report --format markdown --out ./drift-report.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## How It Works
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
drifty scan
|
|
131
|
+
│
|
|
132
|
+
├─ 1. runs: terraform plan -refresh-only -json
|
|
133
|
+
│
|
|
134
|
+
├─ 2. parses JSON Lines output → extracts resource_drift entries
|
|
135
|
+
│
|
|
136
|
+
├─ 3. scores each finding (scorer.py)
|
|
137
|
+
│ critical → IAM, security groups, S3 policies
|
|
138
|
+
│ high → EC2 instances, RDS, load balancers
|
|
139
|
+
│ medium → Lambda, Auto Scaling, CloudWatch
|
|
140
|
+
│ low → tag-only changes
|
|
141
|
+
│
|
|
142
|
+
├─ 4. attributes each finding via CloudTrail (if --attribute)
|
|
143
|
+
│ boto3 → LookupEvents by resource ID
|
|
144
|
+
│ returns: IAM principal, timestamp, API action
|
|
145
|
+
│
|
|
146
|
+
└─ 5. renders output
|
|
147
|
+
terminal → Rich color-coded table
|
|
148
|
+
json → structured output for CI/CD
|
|
149
|
+
markdown → report for Confluence / Notion
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Commands
|
|
155
|
+
|
|
156
|
+
### `drifty scan`
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
Options:
|
|
160
|
+
--workspace PATH Terraform directory (default: current dir)
|
|
161
|
+
--profile TEXT AWS CLI profile (default: "default")
|
|
162
|
+
--attribute Enable CloudTrail attribution
|
|
163
|
+
--severity TEXT Minimum severity: critical | high | medium | low
|
|
164
|
+
--output TEXT Output format: terminal | json | markdown
|
|
165
|
+
--notify TEXT Send results to: slack
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `drifty init`
|
|
169
|
+
|
|
170
|
+
Initializes `.drifty/config.yaml` in the workspace with default settings.
|
|
171
|
+
|
|
172
|
+
### `drifty config set KEY=VALUE`
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
drifty config set default_severity=high
|
|
176
|
+
drifty config set default_profile=prod
|
|
177
|
+
drifty config set slack_webhook=https://hooks.slack.com/...
|
|
178
|
+
drifty config set cloudtrail_lookback_days=30
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### `drifty report`
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
drifty report --format markdown --out ./reports/drift-$(date +%F).md
|
|
185
|
+
drifty report --format json
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Severity Rules
|
|
191
|
+
|
|
192
|
+
| Resource Type | Severity |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `aws_iam_role_policy`, `aws_iam_policy` | 🔴 Critical |
|
|
195
|
+
| `aws_security_group`, `aws_security_group_rule` | 🔴 Critical |
|
|
196
|
+
| `aws_s3_bucket_policy`, `aws_s3_bucket_public_access_block` | 🔴 Critical |
|
|
197
|
+
| `aws_instance` (type/AMI change) | 🟠 High |
|
|
198
|
+
| `aws_rds_instance`, `aws_lb`, `aws_alb` | 🟠 High |
|
|
199
|
+
| `aws_lambda_function`, `aws_autoscaling_group` | 🟡 Medium |
|
|
200
|
+
| `aws_cloudwatch_metric_alarm` | 🟡 Medium |
|
|
201
|
+
| `aws_instance` (tag-only change) | 🟢 Low |
|
|
202
|
+
| `aws_s3_bucket` (tag-only change) | 🟢 Low |
|
|
203
|
+
|
|
204
|
+
Override any rule per-workspace:
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
# .drifty/config.yaml
|
|
208
|
+
severity_overrides:
|
|
209
|
+
aws_lambda_function: high
|
|
210
|
+
aws_cloudwatch_metric_alarm: low
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## drifty vs. the Alternatives
|
|
216
|
+
|
|
217
|
+
| Feature | `terraform plan` | Spacelift / HCP TF | **drifty** |
|
|
218
|
+
|---|---|---|---|
|
|
219
|
+
| Detects drift | ✅ | ✅ | ✅ |
|
|
220
|
+
| Who caused it | ❌ | ❌ | ✅ CloudTrail |
|
|
221
|
+
| Severity score | ❌ | ❌ | ✅ |
|
|
222
|
+
| Remediation hint | ❌ | ❌ | ✅ |
|
|
223
|
+
| JSON / Markdown output | ❌ | partial | ✅ |
|
|
224
|
+
| Works locally / in CI | ✅ | ❌ SaaS only | ✅ |
|
|
225
|
+
| Cost | free | $$$ | free |
|
|
226
|
+
| Install | N/A | platform setup | `pip install drifty` |
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Configuration Reference
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
# .drifty/config.yaml
|
|
234
|
+
default_profile: default # AWS CLI profile
|
|
235
|
+
default_severity: null # minimum severity filter (null = show all)
|
|
236
|
+
default_output: terminal # terminal | json | markdown
|
|
237
|
+
slack_webhook: null # Slack incoming webhook URL
|
|
238
|
+
cloudtrail_lookback_days: 90 # max 90 (CloudTrail API limit)
|
|
239
|
+
severity_overrides: {} # per-resource type overrides
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Roadmap
|
|
245
|
+
|
|
246
|
+
- [ ] `--notify slack` — post drift summary to Slack webhook
|
|
247
|
+
- [ ] `drifty watch` — continuous drift monitoring on a poll interval
|
|
248
|
+
- [ ] Azure and GCP provider support
|
|
249
|
+
- [ ] GitHub PR comment integration — post drift report as a PR comment
|
|
250
|
+
- [ ] Drift history — persist findings to `.drifty/history.json`
|
|
251
|
+
- [ ] `drifty ignore` — suppress known/accepted drift entries
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
git clone https://github.com/satyajit-dey-17/drifty.git
|
|
259
|
+
cd drifty
|
|
260
|
+
poetry install
|
|
261
|
+
poetry run pytest -v
|
|
262
|
+
poetry run ruff check drifty/
|
|
263
|
+
poetry run black drifty/
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Please open an issue before submitting a large PR.
|
|
267
|
+
See [`.github/ISSUE_TEMPLATE/`](.github/ISSUE_TEMPLATE/) for bug and feature templates.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT © [Satyajit Dey](https://github.com/satyajit-dey-17)
|
drifty-0.1.0/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# 🔍 drifty
|
|
2
|
+
|
|
3
|
+
> Terraform drift intelligence — detect what changed, who changed it, how dangerous it is, and how to fix it.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/drifty/)
|
|
6
|
+
[](https://pypi.org/project/drifty/)
|
|
7
|
+
[](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install drifty
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The Problem
|
|
17
|
+
|
|
18
|
+
`terraform plan` tells you **what** drifted. It doesn't tell you **who** changed it, **how dangerous** the change is, or **what to do** about it.
|
|
19
|
+
|
|
20
|
+
Manual changes in the AWS console during incidents, auto-scaling events, and ad-hoc CLI commands silently diverge your infrastructure from your Terraform state. By the time you notice, you don't know if it was a colleague, a runbook, or a security incident.
|
|
21
|
+
|
|
22
|
+
Enterprise platforms like Spacelift and HCP Terraform Cloud detect drift on a schedule — but they're full IaC platforms that are heavyweight, expensive, and still offer zero attribution or severity intelligence.
|
|
23
|
+
|
|
24
|
+
**drifty fills this exact gap.**
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Demo
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
$ drifty scan --workspace ./infra --attribute
|
|
32
|
+
|
|
33
|
+
🔍 drifty — Terraform Drift Intelligence
|
|
34
|
+
Scanning workspace: ./infra | 2026-06-05 14:00 UTC
|
|
35
|
+
|
|
36
|
+
╭─────────────────────────────────────────────────────────────╮
|
|
37
|
+
│ 3 drifts detected - 1 Critical - 1 High - 1 Low │
|
|
38
|
+
╰─────────────────────────────────────────────────────────────╯
|
|
39
|
+
|
|
40
|
+
🔴 CRITICAL aws_security_group.main (sg-0abc1234)
|
|
41
|
+
Changed: ingress.0.cidr_blocks → ["0.0.0.0/0"] (was: ["10.0.0.0/8"])
|
|
42
|
+
Who: arn:aws:iam::123456789:user/john.doe
|
|
43
|
+
When: 2026-06-03 14:22:11 UTC
|
|
44
|
+
Action: ModifySecurityGroupRules
|
|
45
|
+
Fix: terraform import aws_security_group.main sg-0abc1234
|
|
46
|
+
|
|
47
|
+
🟠 HIGH aws_instance.api_server (i-0def5678)
|
|
48
|
+
Changed: instance_type → t3.large (was: t3.medium)
|
|
49
|
+
Who: arn:aws:iam::123456789:role/ops-automation
|
|
50
|
+
When: 2026-06-02 09:15:44 UTC
|
|
51
|
+
Action: ModifyInstanceAttribute
|
|
52
|
+
Fix: terraform import aws_instance.api_server i-0def5678
|
|
53
|
+
|
|
54
|
+
🟢 LOW aws_s3_bucket.assets (assets-bucket-prod)
|
|
55
|
+
Changed: tags.LastModified → "2026-06-01" (was: "2026-05-15")
|
|
56
|
+
Who: attribution unavailable (event outside 90-day CloudTrail window)
|
|
57
|
+
Fix: Add tag to Terraform config or run terraform apply to reconcile
|
|
58
|
+
|
|
59
|
+
──────────────────────────────────────────────────────────────
|
|
60
|
+
Run `drifty report --format markdown` to export this as a report.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
**Requirements:** Python 3.10+, Terraform 1.1+, AWS credentials configured
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install drifty
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Quick Start
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 1. Initialize config in your Terraform workspace
|
|
79
|
+
cd ./infra
|
|
80
|
+
drifty init
|
|
81
|
+
|
|
82
|
+
# 2. Scan for drift
|
|
83
|
+
drifty scan
|
|
84
|
+
|
|
85
|
+
# 3. Scan with CloudTrail attribution (who caused each drift)
|
|
86
|
+
drifty scan --attribute
|
|
87
|
+
|
|
88
|
+
# 4. Filter to critical and high only
|
|
89
|
+
drifty scan --severity high
|
|
90
|
+
|
|
91
|
+
# 5. Output as JSON (for CI/CD piping)
|
|
92
|
+
drifty scan --output json | jq '.findings[] | select(.severity=="critical")'
|
|
93
|
+
|
|
94
|
+
# 6. Export a markdown report
|
|
95
|
+
drifty report --format markdown --out ./drift-report.md
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## How It Works
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
drifty scan
|
|
104
|
+
│
|
|
105
|
+
├─ 1. runs: terraform plan -refresh-only -json
|
|
106
|
+
│
|
|
107
|
+
├─ 2. parses JSON Lines output → extracts resource_drift entries
|
|
108
|
+
│
|
|
109
|
+
├─ 3. scores each finding (scorer.py)
|
|
110
|
+
│ critical → IAM, security groups, S3 policies
|
|
111
|
+
│ high → EC2 instances, RDS, load balancers
|
|
112
|
+
│ medium → Lambda, Auto Scaling, CloudWatch
|
|
113
|
+
│ low → tag-only changes
|
|
114
|
+
│
|
|
115
|
+
├─ 4. attributes each finding via CloudTrail (if --attribute)
|
|
116
|
+
│ boto3 → LookupEvents by resource ID
|
|
117
|
+
│ returns: IAM principal, timestamp, API action
|
|
118
|
+
│
|
|
119
|
+
└─ 5. renders output
|
|
120
|
+
terminal → Rich color-coded table
|
|
121
|
+
json → structured output for CI/CD
|
|
122
|
+
markdown → report for Confluence / Notion
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Commands
|
|
128
|
+
|
|
129
|
+
### `drifty scan`
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
Options:
|
|
133
|
+
--workspace PATH Terraform directory (default: current dir)
|
|
134
|
+
--profile TEXT AWS CLI profile (default: "default")
|
|
135
|
+
--attribute Enable CloudTrail attribution
|
|
136
|
+
--severity TEXT Minimum severity: critical | high | medium | low
|
|
137
|
+
--output TEXT Output format: terminal | json | markdown
|
|
138
|
+
--notify TEXT Send results to: slack
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### `drifty init`
|
|
142
|
+
|
|
143
|
+
Initializes `.drifty/config.yaml` in the workspace with default settings.
|
|
144
|
+
|
|
145
|
+
### `drifty config set KEY=VALUE`
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
drifty config set default_severity=high
|
|
149
|
+
drifty config set default_profile=prod
|
|
150
|
+
drifty config set slack_webhook=https://hooks.slack.com/...
|
|
151
|
+
drifty config set cloudtrail_lookback_days=30
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `drifty report`
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
drifty report --format markdown --out ./reports/drift-$(date +%F).md
|
|
158
|
+
drifty report --format json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Severity Rules
|
|
164
|
+
|
|
165
|
+
| Resource Type | Severity |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `aws_iam_role_policy`, `aws_iam_policy` | 🔴 Critical |
|
|
168
|
+
| `aws_security_group`, `aws_security_group_rule` | 🔴 Critical |
|
|
169
|
+
| `aws_s3_bucket_policy`, `aws_s3_bucket_public_access_block` | 🔴 Critical |
|
|
170
|
+
| `aws_instance` (type/AMI change) | 🟠 High |
|
|
171
|
+
| `aws_rds_instance`, `aws_lb`, `aws_alb` | 🟠 High |
|
|
172
|
+
| `aws_lambda_function`, `aws_autoscaling_group` | 🟡 Medium |
|
|
173
|
+
| `aws_cloudwatch_metric_alarm` | 🟡 Medium |
|
|
174
|
+
| `aws_instance` (tag-only change) | 🟢 Low |
|
|
175
|
+
| `aws_s3_bucket` (tag-only change) | 🟢 Low |
|
|
176
|
+
|
|
177
|
+
Override any rule per-workspace:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
# .drifty/config.yaml
|
|
181
|
+
severity_overrides:
|
|
182
|
+
aws_lambda_function: high
|
|
183
|
+
aws_cloudwatch_metric_alarm: low
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## drifty vs. the Alternatives
|
|
189
|
+
|
|
190
|
+
| Feature | `terraform plan` | Spacelift / HCP TF | **drifty** |
|
|
191
|
+
|---|---|---|---|
|
|
192
|
+
| Detects drift | ✅ | ✅ | ✅ |
|
|
193
|
+
| Who caused it | ❌ | ❌ | ✅ CloudTrail |
|
|
194
|
+
| Severity score | ❌ | ❌ | ✅ |
|
|
195
|
+
| Remediation hint | ❌ | ❌ | ✅ |
|
|
196
|
+
| JSON / Markdown output | ❌ | partial | ✅ |
|
|
197
|
+
| Works locally / in CI | ✅ | ❌ SaaS only | ✅ |
|
|
198
|
+
| Cost | free | $$$ | free |
|
|
199
|
+
| Install | N/A | platform setup | `pip install drifty` |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Configuration Reference
|
|
204
|
+
|
|
205
|
+
```yaml
|
|
206
|
+
# .drifty/config.yaml
|
|
207
|
+
default_profile: default # AWS CLI profile
|
|
208
|
+
default_severity: null # minimum severity filter (null = show all)
|
|
209
|
+
default_output: terminal # terminal | json | markdown
|
|
210
|
+
slack_webhook: null # Slack incoming webhook URL
|
|
211
|
+
cloudtrail_lookback_days: 90 # max 90 (CloudTrail API limit)
|
|
212
|
+
severity_overrides: {} # per-resource type overrides
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Roadmap
|
|
218
|
+
|
|
219
|
+
- [ ] `--notify slack` — post drift summary to Slack webhook
|
|
220
|
+
- [ ] `drifty watch` — continuous drift monitoring on a poll interval
|
|
221
|
+
- [ ] Azure and GCP provider support
|
|
222
|
+
- [ ] GitHub PR comment integration — post drift report as a PR comment
|
|
223
|
+
- [ ] Drift history — persist findings to `.drifty/history.json`
|
|
224
|
+
- [ ] `drifty ignore` — suppress known/accepted drift entries
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Contributing
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
git clone https://github.com/satyajit-dey-17/drifty.git
|
|
232
|
+
cd drifty
|
|
233
|
+
poetry install
|
|
234
|
+
poetry run pytest -v
|
|
235
|
+
poetry run ruff check drifty/
|
|
236
|
+
poetry run black drifty/
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Please open an issue before submitting a large PR.
|
|
240
|
+
See [`.github/ISSUE_TEMPLATE/`](.github/ISSUE_TEMPLATE/) for bug and feature templates.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## License
|
|
245
|
+
|
|
246
|
+
MIT © [Satyajit Dey](https://github.com/satyajit-dey-17)
|
|
Binary file
|