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 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
+ [![PyPI version](https://badge.fury.io/py/drifty.svg)](https://pypi.org/project/drifty/)
33
+ [![Python](https://img.shields.io/pypi/pyversions/drifty)](https://pypi.org/project/drifty/)
34
+ [![CI](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml/badge.svg)](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml)
35
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
+ [![PyPI version](https://badge.fury.io/py/drifty.svg)](https://pypi.org/project/drifty/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/drifty)](https://pypi.org/project/drifty/)
7
+ [![CI](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml/badge.svg)](https://github.com/satyajit-dey-17/drifty/actions/workflows/test.yml)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
@@ -0,0 +1,5 @@
1
+ """drifty — Terraform Drift Intelligence."""
2
+
3
+ __version__ = "0.1.0"
4
+ __author__ = "Satyajit Dey"
5
+ __email__ = "satyajit.dey@umbc.edu"