aws-inventory-manager 0.17.12__py3-none-any.whl

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.
Files changed (152) hide show
  1. aws_inventory_manager-0.17.12.dist-info/LICENSE +21 -0
  2. aws_inventory_manager-0.17.12.dist-info/METADATA +1292 -0
  3. aws_inventory_manager-0.17.12.dist-info/RECORD +152 -0
  4. aws_inventory_manager-0.17.12.dist-info/WHEEL +5 -0
  5. aws_inventory_manager-0.17.12.dist-info/entry_points.txt +2 -0
  6. aws_inventory_manager-0.17.12.dist-info/top_level.txt +1 -0
  7. src/__init__.py +3 -0
  8. src/aws/__init__.py +11 -0
  9. src/aws/client.py +128 -0
  10. src/aws/credentials.py +191 -0
  11. src/aws/rate_limiter.py +177 -0
  12. src/cli/__init__.py +12 -0
  13. src/cli/config.py +130 -0
  14. src/cli/main.py +4046 -0
  15. src/cloudtrail/__init__.py +5 -0
  16. src/cloudtrail/query.py +642 -0
  17. src/config_service/__init__.py +21 -0
  18. src/config_service/collector.py +346 -0
  19. src/config_service/detector.py +256 -0
  20. src/config_service/resource_type_mapping.py +328 -0
  21. src/cost/__init__.py +5 -0
  22. src/cost/analyzer.py +226 -0
  23. src/cost/explorer.py +209 -0
  24. src/cost/reporter.py +237 -0
  25. src/delta/__init__.py +5 -0
  26. src/delta/calculator.py +206 -0
  27. src/delta/differ.py +185 -0
  28. src/delta/formatters.py +272 -0
  29. src/delta/models.py +154 -0
  30. src/delta/reporter.py +234 -0
  31. src/matching/__init__.py +6 -0
  32. src/matching/config.py +52 -0
  33. src/matching/normalizer.py +450 -0
  34. src/matching/prompts.py +33 -0
  35. src/models/__init__.py +21 -0
  36. src/models/config_diff.py +135 -0
  37. src/models/cost_report.py +87 -0
  38. src/models/deletion_operation.py +104 -0
  39. src/models/deletion_record.py +97 -0
  40. src/models/delta_report.py +122 -0
  41. src/models/efs_resource.py +80 -0
  42. src/models/elasticache_resource.py +90 -0
  43. src/models/group.py +318 -0
  44. src/models/inventory.py +133 -0
  45. src/models/protection_rule.py +123 -0
  46. src/models/report.py +288 -0
  47. src/models/resource.py +111 -0
  48. src/models/security_finding.py +102 -0
  49. src/models/snapshot.py +122 -0
  50. src/restore/__init__.py +20 -0
  51. src/restore/audit.py +175 -0
  52. src/restore/cleaner.py +461 -0
  53. src/restore/config.py +209 -0
  54. src/restore/deleter.py +976 -0
  55. src/restore/dependency.py +254 -0
  56. src/restore/safety.py +115 -0
  57. src/security/__init__.py +0 -0
  58. src/security/checks/__init__.py +0 -0
  59. src/security/checks/base.py +56 -0
  60. src/security/checks/ec2_checks.py +88 -0
  61. src/security/checks/elasticache_checks.py +149 -0
  62. src/security/checks/iam_checks.py +102 -0
  63. src/security/checks/rds_checks.py +140 -0
  64. src/security/checks/s3_checks.py +95 -0
  65. src/security/checks/secrets_checks.py +96 -0
  66. src/security/checks/sg_checks.py +142 -0
  67. src/security/cis_mapper.py +97 -0
  68. src/security/models.py +53 -0
  69. src/security/reporter.py +174 -0
  70. src/security/scanner.py +87 -0
  71. src/snapshot/__init__.py +6 -0
  72. src/snapshot/capturer.py +453 -0
  73. src/snapshot/filter.py +259 -0
  74. src/snapshot/inventory_storage.py +236 -0
  75. src/snapshot/report_formatter.py +250 -0
  76. src/snapshot/reporter.py +189 -0
  77. src/snapshot/resource_collectors/__init__.py +5 -0
  78. src/snapshot/resource_collectors/apigateway.py +140 -0
  79. src/snapshot/resource_collectors/backup.py +136 -0
  80. src/snapshot/resource_collectors/base.py +81 -0
  81. src/snapshot/resource_collectors/cloudformation.py +55 -0
  82. src/snapshot/resource_collectors/cloudwatch.py +109 -0
  83. src/snapshot/resource_collectors/codebuild.py +69 -0
  84. src/snapshot/resource_collectors/codepipeline.py +82 -0
  85. src/snapshot/resource_collectors/dynamodb.py +65 -0
  86. src/snapshot/resource_collectors/ec2.py +240 -0
  87. src/snapshot/resource_collectors/ecs.py +215 -0
  88. src/snapshot/resource_collectors/efs_collector.py +102 -0
  89. src/snapshot/resource_collectors/eks.py +200 -0
  90. src/snapshot/resource_collectors/elasticache_collector.py +79 -0
  91. src/snapshot/resource_collectors/elb.py +126 -0
  92. src/snapshot/resource_collectors/eventbridge.py +156 -0
  93. src/snapshot/resource_collectors/glue.py +199 -0
  94. src/snapshot/resource_collectors/iam.py +188 -0
  95. src/snapshot/resource_collectors/kms.py +111 -0
  96. src/snapshot/resource_collectors/lambda_func.py +139 -0
  97. src/snapshot/resource_collectors/rds.py +109 -0
  98. src/snapshot/resource_collectors/route53.py +86 -0
  99. src/snapshot/resource_collectors/s3.py +105 -0
  100. src/snapshot/resource_collectors/secretsmanager.py +70 -0
  101. src/snapshot/resource_collectors/sns.py +68 -0
  102. src/snapshot/resource_collectors/sqs.py +82 -0
  103. src/snapshot/resource_collectors/ssm.py +160 -0
  104. src/snapshot/resource_collectors/stepfunctions.py +74 -0
  105. src/snapshot/resource_collectors/vpcendpoints.py +79 -0
  106. src/snapshot/resource_collectors/waf.py +159 -0
  107. src/snapshot/storage.py +351 -0
  108. src/storage/__init__.py +21 -0
  109. src/storage/audit_store.py +419 -0
  110. src/storage/database.py +294 -0
  111. src/storage/group_store.py +763 -0
  112. src/storage/inventory_store.py +320 -0
  113. src/storage/resource_store.py +416 -0
  114. src/storage/schema.py +339 -0
  115. src/storage/snapshot_store.py +363 -0
  116. src/utils/__init__.py +12 -0
  117. src/utils/export.py +305 -0
  118. src/utils/hash.py +60 -0
  119. src/utils/logging.py +63 -0
  120. src/utils/pagination.py +41 -0
  121. src/utils/paths.py +51 -0
  122. src/utils/progress.py +41 -0
  123. src/utils/unsupported_resources.py +306 -0
  124. src/web/__init__.py +5 -0
  125. src/web/app.py +97 -0
  126. src/web/dependencies.py +69 -0
  127. src/web/routes/__init__.py +1 -0
  128. src/web/routes/api/__init__.py +18 -0
  129. src/web/routes/api/charts.py +156 -0
  130. src/web/routes/api/cleanup.py +186 -0
  131. src/web/routes/api/filters.py +253 -0
  132. src/web/routes/api/groups.py +305 -0
  133. src/web/routes/api/inventories.py +80 -0
  134. src/web/routes/api/queries.py +202 -0
  135. src/web/routes/api/resources.py +393 -0
  136. src/web/routes/api/snapshots.py +314 -0
  137. src/web/routes/api/views.py +260 -0
  138. src/web/routes/pages.py +198 -0
  139. src/web/services/__init__.py +1 -0
  140. src/web/templates/base.html +955 -0
  141. src/web/templates/components/navbar.html +31 -0
  142. src/web/templates/components/sidebar.html +104 -0
  143. src/web/templates/pages/audit_logs.html +86 -0
  144. src/web/templates/pages/cleanup.html +279 -0
  145. src/web/templates/pages/dashboard.html +227 -0
  146. src/web/templates/pages/diff.html +175 -0
  147. src/web/templates/pages/error.html +30 -0
  148. src/web/templates/pages/groups.html +721 -0
  149. src/web/templates/pages/queries.html +246 -0
  150. src/web/templates/pages/resources.html +2429 -0
  151. src/web/templates/pages/snapshot_detail.html +271 -0
  152. src/web/templates/pages/snapshots.html +429 -0
@@ -0,0 +1,1292 @@
1
+ Metadata-Version: 2.2
2
+ Name: aws-inventory-manager
3
+ Version: 0.17.12
4
+ Summary: AWS Resource Inventory Management & Delta Tracking CLI tool
5
+ Author-email: Troy Larson <troy@calvinware.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/troylar/aws-inventory-manager
8
+ Project-URL: Documentation, https://github.com/troylar/aws-inventory-manager#readme
9
+ Project-URL: Repository, https://github.com/troylar/aws-inventory-manager
10
+ Project-URL: Issues, https://github.com/troylar/aws-inventory-manager/issues
11
+ Keywords: aws,cloud,infrastructure,snapshot,audit,cost-tracking,inventory
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: boto3>=1.28.0
28
+ Requires-Dist: typer>=0.9.0
29
+ Requires-Dist: rich>=13.0.0
30
+ Requires-Dist: pyyaml>=6.0
31
+ Requires-Dist: python-dateutil>=2.8.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
35
+ Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
36
+ Requires-Dist: black>=23.0.0; extra == "dev"
37
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
38
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
39
+ Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
40
+ Requires-Dist: invoke>=2.0.0; extra == "dev"
41
+ Provides-Extra: web
42
+ Requires-Dist: fastapi>=0.109.0; extra == "web"
43
+ Requires-Dist: uvicorn[standard]>=0.27.0; extra == "web"
44
+ Requires-Dist: jinja2>=3.1.0; extra == "web"
45
+ Requires-Dist: python-multipart>=0.0.6; extra == "web"
46
+
47
+ <div align="center">
48
+
49
+ # AWS Inventory Manager
50
+
51
+ ### *Snapshot, Track, Secure, and Clean Up Your AWS Environment*
52
+
53
+ [![CI](https://github.com/troylar/aws-inventory-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/troylar/aws-inventory-manager/actions/workflows/ci.yml)
54
+ [![Coverage](https://codecov.io/gh/troylar/aws-inventory-manager/branch/main/graph/badge.svg)](https://codecov.io/gh/troylar/aws-inventory-manager)
55
+ [![PyPI version](https://img.shields.io/pypi/v/aws-inventory-manager.svg)](https://pypi.org/project/aws-inventory-manager/)
56
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
57
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
58
+
59
+ **Inventory Snapshots** • **Configuration Drift** • **Security Scanning** • **Cost Analysis** • **Resource Cleanup**
60
+
61
+ [Quick Start](#quick-start) • [Features](#features) • [AWS Config](#aws-config-integration) • [Documentation](#documentation)
62
+
63
+ </div>
64
+
65
+ ---
66
+
67
+ ## What It Does
68
+
69
+ AWS Inventory Manager captures a **point-in-time inventory** of your AWS resources, then helps you track changes, find security issues, and clean up unwanted resources.
70
+
71
+ > **Note:** "Snapshot" in this tool means an *inventory snapshot* (a catalog of what exists), not an AWS EBS or RDS snapshot. No AWS snapshots are created.
72
+
73
+ ```bash
74
+ # Capture your current resource inventory
75
+ awsinv snapshot create my-baseline --regions us-east-1,us-west-2
76
+
77
+ # Track what changed since the baseline
78
+ awsinv delta --snapshot my-baseline --show-diff
79
+
80
+ # Find security issues
81
+ awsinv security scan --severity HIGH
82
+
83
+ # Remove resources created after the baseline
84
+ awsinv cleanup preview my-baseline # See what would be deleted
85
+ awsinv cleanup execute my-baseline --confirm # Execute cleanup
86
+ ```
87
+
88
+ ### Why You Need This
89
+
90
+ | Problem | Solution |
91
+ |---------|----------|
92
+ | "What changed in our account?" | Field-level configuration drift detection |
93
+ | "Are we following security best practices?" | Automated CIS Benchmark scanning |
94
+ | "Someone spun up a bunch of test resources" | Delete everything created after a baseline snapshot |
95
+ | "How much is each team spending?" | Per-inventory cost tracking with tag filtering |
96
+ | "I need to clean up a sandbox account" | Purge all resources except those with specific tags |
97
+
98
+ ---
99
+
100
+ ## Key Concepts
101
+
102
+ Before diving in, here's the terminology:
103
+
104
+ | Term | Meaning |
105
+ |------|---------|
106
+ | **Snapshot** | A point-in-time inventory of your AWS resources (stored in local SQLite database). Not an EBS/RDS snapshot. |
107
+ | **Inventory** | A named collection of snapshots. Use inventories to organize snapshots by environment, team, or purpose. |
108
+ | **Cleanup** | Delete resources that were created *after* a snapshot, returning to that baseline state. |
109
+ | **Purge** | Delete all resources *except* those matching protection rules (no snapshot comparison needed). |
110
+ | **Query** | Search and analyze resources across snapshots using SQL or built-in filters. |
111
+
112
+ ---
113
+
114
+ ## Features
115
+
116
+ <table>
117
+ <tr>
118
+ <td width="33%" valign="top">
119
+
120
+ ### Inventory Snapshots
121
+ - 27 AWS services, 80+ resource types
122
+ - Multi-region collection
123
+ - Tag-based filtering
124
+ - Export to JSON/CSV
125
+ - SQLite storage with SQL queries
126
+
127
+ </td>
128
+ <td width="33%" valign="top">
129
+
130
+ ### Change Tracking
131
+ - Field-level drift detection
132
+ - Before/after comparison
133
+ - Configuration + security changes
134
+ - Color-coded terminal output
135
+ - JSON export for CI/CD
136
+
137
+ </td>
138
+ <td width="33%" valign="top">
139
+
140
+ ### Security Scanning
141
+ - 12+ CIS-aligned checks
142
+ - CRITICAL/HIGH/MEDIUM/LOW severity
143
+ - Public S3 buckets, open ports
144
+ - IAM credential age
145
+ - Remediation guidance
146
+
147
+ </td>
148
+ </tr>
149
+ <tr>
150
+ <td width="33%" valign="top">
151
+
152
+ ### Cost Analysis
153
+ - Per-inventory cost tracking
154
+ - Date range filtering
155
+ - Service-level breakdown
156
+ - Tag-based attribution
157
+ - AWS Cost Explorer integration
158
+
159
+ </td>
160
+ <td width="33%" valign="top">
161
+
162
+ ### Resource Cleanup
163
+ - **Cleanup**: Return to a snapshot baseline
164
+ - **Purge**: Delete all except protected
165
+ - Preview mode (dry-run)
166
+ - Dependency-aware deletion
167
+ - 43 deletable resource types*
168
+
169
+ <sub>*Deletion requires service-specific logic; collection supports 80+ types, deletion supports 43.</sub>
170
+
171
+ </td>
172
+ <td width="33%" valign="top">
173
+
174
+ ### AWS Config Integration
175
+ - Automatic detection
176
+ - Up to 5x faster collection
177
+ - Hybrid fallback to direct API
178
+ - Per-resource source tracking
179
+ - Multi-account via Aggregators
180
+
181
+ </td>
182
+ </tr>
183
+ <tr>
184
+ <td width="33%" valign="top">
185
+
186
+ ### Query & Analysis
187
+ - Raw SQL queries on resources
188
+ - Search by type, region, tags
189
+ - Tag coverage analysis
190
+ - Cross-snapshot history
191
+ - Export to JSON/CSV
192
+
193
+ </td>
194
+ <td width="33%" valign="top">
195
+
196
+ ### Resource Provenance
197
+ - CloudTrail creator tracking
198
+ - `--track-creators` flag
199
+ - Enrich existing snapshots
200
+ - Web UI creator columns
201
+ - Identity type detection
202
+
203
+ </td>
204
+ <td width="33%" valign="top">
205
+ </td>
206
+ </tr>
207
+ </table>
208
+
209
+ ---
210
+
211
+ ## Prerequisites
212
+
213
+ Before installing, ensure you have:
214
+
215
+ - **Python 3.8+** (3.8, 3.9, 3.10, 3.11, 3.12, or 3.13)
216
+ - **AWS CLI configured** with credentials (`aws configure` or environment variables)
217
+ - **Sufficient IAM permissions** (see [IAM Permissions](#iam-permissions) below)
218
+
219
+ To verify your setup:
220
+ ```bash
221
+ python3 --version # Should be 3.8+ (use 'python' on some systems)
222
+ aws sts get-caller-identity # Should return your account info
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Quick Start
228
+
229
+ ### Installation
230
+
231
+ ```bash
232
+ pip install aws-inventory-manager
233
+ ```
234
+
235
+ Or with pipx for isolated installation:
236
+ ```bash
237
+ pipx install aws-inventory-manager
238
+ ```
239
+
240
+ ### Your First Snapshot
241
+
242
+ ```bash
243
+ # 1. Capture current state (takes 30-60 seconds depending on resource count)
244
+ awsinv snapshot create my-baseline --regions us-east-1
245
+
246
+ # 2. View what was captured
247
+ awsinv snapshot report
248
+
249
+ # Output:
250
+ # ┌─────────────────────────────────────────┐
251
+ # │ Snapshot: my-baseline │
252
+ # │ Resources: 127 │
253
+ # │ Regions: us-east-1 │
254
+ # ├─────────────────────────────────────────┤
255
+ # │ EC2 Instances: 12 │
256
+ # │ S3 Buckets: 8 │
257
+ # │ Lambda Functions: 23 │
258
+ # │ IAM Roles: 45 │
259
+ # │ ... │
260
+ # └─────────────────────────────────────────┘
261
+ ```
262
+
263
+ ### Common Workflows
264
+
265
+ ```bash
266
+ # Track changes since baseline
267
+ awsinv delta --snapshot my-baseline --show-diff
268
+
269
+ # Find security issues
270
+ awsinv security scan
271
+
272
+ # Clean up resources created after baseline
273
+ awsinv cleanup preview my-baseline # Always preview first!
274
+ awsinv cleanup execute my-baseline --confirm
275
+
276
+ # Clean up a sandbox (keep only tagged resources)
277
+ awsinv cleanup purge --protect-tag "keep=true" --preview
278
+ awsinv cleanup purge --protect-tag "keep=true" --confirm
279
+ ```
280
+
281
+ ---
282
+ ## Environment Variables
283
+
284
+ You can configure most CLI options via environment variables, which is useful for CI/CD pipelines or setting personal defaults.
285
+
286
+ | Variable | Description | Equivalent Flag |
287
+ |----------|-------------|-----------------|
288
+ | `AWSINV_SNAPSHOT_ID` | Default snapshot name for queries | `--snapshot` |
289
+ | `AWSINV_INVENTORY_ID` | Default inventory name | `--inventory` |
290
+ | `AWSINV_REGION` | Comma-separated regions (e.g., `us-east-1,us-west-2`) | `--regions` |
291
+ | `AWSINV_PROFILE` | AWS CLI profile to use | `--profile` |
292
+ | `AWSINV_STORAGE_PATH` | Custom path for SQLite DB and logs | `--storage-path` |
293
+
294
+ Example:
295
+ ```bash
296
+ export AWSINV_INVENTORY_ID="prod-baseline"
297
+ export AWSINV_REGION="us-east-1"
298
+
299
+ # These commands will now use the exported values automatically
300
+ awsinv snapshot create daily-snap
301
+ awsinv delta --snapshot previous-snap
302
+ ```
303
+
304
+ ---
305
+
306
+ ## AWS Config Integration
307
+
308
+ When [AWS Config](https://aws.amazon.com/config/) is enabled, the tool automatically uses it for faster resource collection.
309
+
310
+ ### Why Use AWS Config?
311
+
312
+ | Method | 500 Resources | 2000 Resources |
313
+ |--------|---------------|----------------|
314
+ | Direct API calls | ~45 seconds | ~3 minutes |
315
+ | AWS Config | ~8 seconds | ~20 seconds |
316
+
317
+ AWS Config maintains an indexed inventory of your resources. Instead of calling 27 different AWS service APIs, we query Config's pre-built index.
318
+
319
+ ### How It Works
320
+
321
+ ```
322
+ For each region:
323
+ 1. Check if AWS Config is enabled and recording
324
+ 2. For each resource type:
325
+ ├─ Config supports it? → Query Config API (fast)
326
+ └─ Config doesn't support it? → Call service API directly (Route53, WAF, etc.)
327
+ 3. Merge results into unified snapshot
328
+ ```
329
+
330
+ **No configuration required.** The tool detects Config availability automatically and falls back gracefully.
331
+
332
+ ### Usage
333
+
334
+ ```bash
335
+ # Default behavior: Use Config when available (recommended)
336
+ awsinv snapshot create my-snapshot --regions us-east-1
337
+
338
+ # Force direct API only (skip Config, useful for debugging)
339
+ awsinv snapshot create my-snapshot --regions us-east-1 --no-config
340
+
341
+ # Multi-account via Config Aggregator
342
+ awsinv snapshot create org-snapshot --config-aggregator my-org-aggregator
343
+ ```
344
+
345
+ ### Source Tracking
346
+
347
+ Each resource records how it was collected:
348
+
349
+ ```yaml
350
+ resources:
351
+ - arn: "arn:aws:s3:::my-bucket"
352
+ type: "AWS::S3::Bucket"
353
+ name: "my-bucket"
354
+ source: "config" # Collected via AWS Config
355
+
356
+ - arn: "arn:aws:route53:::hostedzone/Z123"
357
+ type: "AWS::Route53::HostedZone"
358
+ name: "example.com"
359
+ source: "direct_api" # Config doesn't support Route53
360
+ ```
361
+
362
+ ### Requirements
363
+
364
+ To benefit from Config integration:
365
+
366
+ 1. **AWS Config enabled** in target region(s)
367
+ 2. **Configuration Recorder** actively recording
368
+ 3. **Resource types being recorded** (either "all supported types" or specific types)
369
+
370
+ If these aren't met, the tool falls back to direct API calls automatically.
371
+
372
+ ---
373
+
374
+ ## Data Storage
375
+
376
+ ### Where Snapshots Are Stored
377
+
378
+ By default, all data is stored locally in a SQLite database:
379
+
380
+ ```
381
+ ~/.snapshots/
382
+ ├── inventory.db # SQLite database (snapshots, resources, tags)
383
+ └── audit-logs/
384
+ └── cleanup/ # Cleanup operation audit logs
385
+ └── 2026-01-15_cleanup.yaml
386
+ ```
387
+
388
+ The SQLite database provides:
389
+ - **Fast queries**: Search across all snapshots with SQL
390
+ - **Tag analysis**: Normalized tags table for efficient filtering
391
+ - **Cross-snapshot history**: Track resources across multiple snapshots
392
+
393
+ ### Changing Storage Location
394
+
395
+ ```bash
396
+ # Via environment variable
397
+ export AWS_INVENTORY_STORAGE_PATH=/path/to/storage
398
+ awsinv snapshot create my-snapshot
399
+
400
+ # Via CLI flag
401
+ awsinv snapshot create my-snapshot --storage-path /path/to/storage
402
+ ```
403
+
404
+ ### Team Sharing
405
+
406
+ The SQLite database is a single portable file. To share across a team:
407
+
408
+ - Store `inventory.db` in a shared filesystem
409
+ - Sync via S3 or other cloud storage
410
+ - Use separate databases per environment/team
411
+
412
+ ### Database Schema & Power User Queries
413
+
414
+ For advanced usage, including the full SQLite schema and complex analytical SQL queries, please see [DATABASE.md](DATABASE.md).
415
+
416
+ ---
417
+
418
+ ## Multi-Account Support
419
+
420
+ ### Option 1: AWS Config Aggregator (Recommended)
421
+
422
+ If you have a [Config Aggregator](https://docs.aws.amazon.com/config/latest/developerguide/aggregate-data.html) set up (common with AWS Organizations):
423
+
424
+ ```bash
425
+ # Query all accounts via the aggregator
426
+ awsinv snapshot create org-wide --config-aggregator my-aggregator
427
+ ```
428
+
429
+ **Prerequisites:**
430
+ - Config Aggregator already configured in your management account
431
+ - See [Setting Up an Aggregator Using the Console](https://docs.aws.amazon.com/config/latest/developerguide/setup-aggregator-console.html)
432
+ - Appropriate IAM permissions to query the aggregator (see [IAM Permissions](#iam-permissions))
433
+
434
+ ### Option 2: Profile Switching
435
+
436
+ ```bash
437
+ # Snapshot each account separately
438
+ awsinv snapshot create account-dev --profile dev-account
439
+ awsinv snapshot create account-prod --profile prod-account
440
+ ```
441
+
442
+ ### Option 3: Cross-Account Roles
443
+
444
+ Configure your AWS CLI with cross-account role assumption, then use profiles as above.
445
+
446
+ ---
447
+
448
+ ## IAM Permissions
449
+
450
+ The tool requires different permissions depending on which features you use. Combine the policies below based on which features you need, or attach them as separate managed policies.
451
+
452
+ > **Tip:** Start with just "Snapshot Collection" permissions. Add others only when needed.
453
+
454
+ ### Snapshot Collection (Read-Only)
455
+
456
+ For basic snapshot collection, you need read access to the services you want to inventory. The easiest approach is to use the `ReadOnlyAccess` AWS managed policy, but here's a minimal custom policy:
457
+
458
+ ```json
459
+ {
460
+ "Version": "2012-10-17",
461
+ "Statement": [
462
+ {
463
+ "Sid": "SnapshotCollection",
464
+ "Effect": "Allow",
465
+ "Action": [
466
+ "ec2:Describe*",
467
+ "s3:GetBucket*",
468
+ "s3:ListAllMyBuckets",
469
+ "s3:ListBucket",
470
+ "lambda:List*",
471
+ "lambda:GetFunction*",
472
+ "iam:List*",
473
+ "iam:Get*",
474
+ "rds:Describe*",
475
+ "dynamodb:Describe*",
476
+ "dynamodb:List*",
477
+ "ecs:Describe*",
478
+ "ecs:List*",
479
+ "eks:Describe*",
480
+ "eks:List*",
481
+ "sns:List*",
482
+ "sns:GetTopicAttributes",
483
+ "sqs:List*",
484
+ "sqs:GetQueueAttributes",
485
+ "cloudwatch:Describe*",
486
+ "cloudwatch:List*",
487
+ "elasticloadbalancing:Describe*",
488
+ "route53:List*",
489
+ "route53:Get*",
490
+ "secretsmanager:List*",
491
+ "secretsmanager:DescribeSecret",
492
+ "kms:List*",
493
+ "kms:Describe*",
494
+ "apigateway:GET",
495
+ "events:List*",
496
+ "events:Describe*",
497
+ "states:List*",
498
+ "states:Describe*",
499
+ "codepipeline:List*",
500
+ "codepipeline:Get*",
501
+ "codebuild:List*",
502
+ "codebuild:BatchGet*",
503
+ "cloudformation:Describe*",
504
+ "cloudformation:List*",
505
+ "elasticache:Describe*",
506
+ "ssm:DescribeParameters",
507
+ "ssm:GetParameter*",
508
+ "backup:List*",
509
+ "backup:Describe*",
510
+ "efs:Describe*",
511
+ "wafv2:List*",
512
+ "wafv2:Get*"
513
+ ],
514
+ "Resource": "*"
515
+ }
516
+ ]
517
+ }
518
+ ```
519
+
520
+ ### AWS Config Integration (Optional)
521
+
522
+ If you want to use AWS Config for faster collection:
523
+
524
+ ```json
525
+ {
526
+ "Version": "2012-10-17",
527
+ "Statement": [
528
+ {
529
+ "Sid": "ConfigRead",
530
+ "Effect": "Allow",
531
+ "Action": [
532
+ "config:DescribeConfigurationRecorders",
533
+ "config:DescribeConfigurationRecorderStatus",
534
+ "config:GetDiscoveredResourceCounts",
535
+ "config:ListDiscoveredResources",
536
+ "config:BatchGetResourceConfig"
537
+ ],
538
+ "Resource": "*"
539
+ }
540
+ ]
541
+ }
542
+ ```
543
+
544
+ For Config Aggregators (multi-account):
545
+
546
+ ```json
547
+ {
548
+ "Version": "2012-10-17",
549
+ "Statement": [
550
+ {
551
+ "Sid": "ConfigAggregator",
552
+ "Effect": "Allow",
553
+ "Action": [
554
+ "config:DescribeConfigurationAggregators",
555
+ "config:SelectAggregateResourceConfig"
556
+ ],
557
+ "Resource": "*"
558
+ }
559
+ ]
560
+ }
561
+ ```
562
+
563
+ ### CloudTrail (Creator Tracking)
564
+
565
+ For the `--track-creators` flag and `enrich-creators` command:
566
+
567
+ ```json
568
+ {
569
+ "Version": "2012-10-17",
570
+ "Statement": [
571
+ {
572
+ "Sid": "CloudTrailLookup",
573
+ "Effect": "Allow",
574
+ "Action": [
575
+ "cloudtrail:LookupEvents"
576
+ ],
577
+ "Resource": "*"
578
+ }
579
+ ]
580
+ }
581
+ ```
582
+
583
+ ### Cost Analysis
584
+
585
+ For the `awsinv cost` command:
586
+
587
+ ```json
588
+ {
589
+ "Version": "2012-10-17",
590
+ "Statement": [
591
+ {
592
+ "Sid": "CostExplorer",
593
+ "Effect": "Allow",
594
+ "Action": [
595
+ "ce:GetCostAndUsage",
596
+ "ce:GetCostForecast"
597
+ ],
598
+ "Resource": "*"
599
+ }
600
+ ]
601
+ }
602
+ ```
603
+
604
+ ### Resource Cleanup
605
+
606
+ ⚠️ **Warning:** These permissions allow resource deletion. Use with extreme caution.
607
+
608
+ ```json
609
+ {
610
+ "Version": "2012-10-17",
611
+ "Statement": [
612
+ {
613
+ "Sid": "ResourceCleanup",
614
+ "Effect": "Allow",
615
+ "Action": [
616
+ "ec2:TerminateInstances",
617
+ "ec2:DeleteVolume",
618
+ "ec2:DeleteVpc",
619
+ "ec2:DeleteSubnet",
620
+ "ec2:DeleteSecurityGroup",
621
+ "ec2:DeleteInternetGateway",
622
+ "ec2:DeleteNatGateway",
623
+ "ec2:DeleteRouteTable",
624
+ "ec2:DeleteVpcEndpoints",
625
+ "ec2:DetachInternetGateway",
626
+ "ec2:DisassociateRouteTable",
627
+ "ec2:ReleaseAddress",
628
+ "ec2:DeleteKeyPair",
629
+ "s3:DeleteBucket",
630
+ "s3:DeleteObject",
631
+ "s3:DeleteObjectVersion",
632
+ "lambda:DeleteFunction",
633
+ "iam:DeleteRole",
634
+ "iam:DeleteRolePolicy",
635
+ "iam:DetachRolePolicy",
636
+ "iam:DeleteUser",
637
+ "iam:DeleteUserPolicy",
638
+ "iam:DetachUserPolicy",
639
+ "iam:DeleteAccessKey",
640
+ "iam:DeleteLoginProfile",
641
+ "iam:DeactivateMFADevice",
642
+ "iam:DeletePolicy",
643
+ "rds:DeleteDBInstance",
644
+ "rds:DeleteDBCluster",
645
+ "dynamodb:DeleteTable",
646
+ "ecs:DeleteCluster",
647
+ "ecs:DeleteService",
648
+ "ecs:DeregisterTaskDefinition",
649
+ "eks:DeleteCluster",
650
+ "sns:DeleteTopic",
651
+ "sqs:DeleteQueue",
652
+ "cloudwatch:DeleteAlarms",
653
+ "elasticloadbalancing:DeleteLoadBalancer",
654
+ "elasticloadbalancing:DeleteTargetGroup",
655
+ "route53:DeleteHostedZone",
656
+ "route53:ChangeResourceRecordSets",
657
+ "secretsmanager:DeleteSecret",
658
+ "kms:ScheduleKeyDeletion",
659
+ "apigateway:DELETE",
660
+ "events:DeleteRule",
661
+ "events:RemoveTargets",
662
+ "states:DeleteStateMachine",
663
+ "codepipeline:DeletePipeline",
664
+ "codebuild:DeleteProject",
665
+ "cloudformation:DeleteStack",
666
+ "elasticache:DeleteCacheCluster",
667
+ "ssm:DeleteParameter",
668
+ "backup:DeleteBackupPlan",
669
+ "backup:DeleteBackupVault",
670
+ "backup:DeleteRecoveryPoint",
671
+ "efs:DeleteFileSystem",
672
+ "efs:DeleteMountTarget",
673
+ "wafv2:DeleteWebACL",
674
+ "wafv2:DeleteRuleGroup",
675
+ "wafv2:DisassociateWebACL"
676
+ ],
677
+ "Resource": "*"
678
+ }
679
+ ]
680
+ }
681
+ ```
682
+
683
+ **Recommendation:** For production accounts, use separate IAM roles for read-only operations (snapshots) and cleanup operations. Never give cleanup permissions to everyday users.
684
+
685
+ ---
686
+
687
+ ## Documentation
688
+
689
+ ### Resource Provenance (Creator Tracking)
690
+
691
+ Track who created each resource in your AWS account using CloudTrail:
692
+
693
+ ```bash
694
+ # Track creators during snapshot creation
695
+ awsinv snapshot create my-snapshot --regions us-east-1 --track-creators
696
+
697
+ # Enrich an existing snapshot with creator information
698
+ awsinv snapshot enrich-creators my-snapshot --days-back 90
699
+ ```
700
+
701
+ This adds three tags to each resource:
702
+ - `_created_by`: The IAM role/user ARN that created the resource
703
+ - `_created_by_type`: The identity type (AssumedRole, IAMUser, Root, AWSService)
704
+ - `_created_at`: When the resource was created (from CloudTrail)
705
+
706
+ **Use Cases:**
707
+ - Identify resources created by automation vs. manual creation
708
+ - Track resources created by specific CI/CD pipelines
709
+ - Find resources created by former team members
710
+ - Audit resource creation by identity type
711
+
712
+ **Web UI Support:**
713
+ The Resource Explorer includes three creator columns (enable via column selector):
714
+ - "Created By" - Shows the creator ARN (truncated for readability)
715
+ - "Creator Type" - Color-coded badge (AssumedRole=blue, IAMUser=green, Root=red, AWSService=orange)
716
+ - "Creation Time" - When the resource was created
717
+
718
+ > **Note:** CloudTrail has a 90-day lookup window. Resources created more than 90 days ago won't have creator information. The `--days-back` option lets you customize the lookup period (default: 90).
719
+
720
+ ---
721
+
722
+ ### Resource Cleanup
723
+
724
+ The `cleanup` command has two modes:
725
+
726
+ **Execute Mode** - Delete resources created *after* a baseline snapshot:
727
+ ```bash
728
+ # Preview what would be deleted
729
+ awsinv cleanup preview my-baseline
730
+
731
+ # Execute (requires confirmation)
732
+ awsinv cleanup execute my-baseline --confirm
733
+ ```
734
+
735
+ **Purge Mode** - Delete *all* resources except those matching protection rules:
736
+ ```bash
737
+ # Preview what would be deleted (everything except keep=true tagged resources)
738
+ awsinv cleanup purge --protect-tag "keep=true" --preview
739
+
740
+ # Execute
741
+ awsinv cleanup purge --protect-tag "keep=true" --confirm
742
+ ```
743
+
744
+ > **Note:** `cleanup execute` compares to a snapshot and deletes newer resources. `cleanup purge` ignores snapshots and deletes everything except protected resources.
745
+
746
+ ### Protection Rules
747
+
748
+ Prevent accidental deletion of important resources:
749
+
750
+ ```bash
751
+ # Protect by tag (OR logic - any match protects)
752
+ awsinv cleanup preview my-snapshot --protect-tag "env=prod" --protect-tag "keep=true"
753
+
754
+ # Filter to specific resource type (only delete this type)
755
+ awsinv cleanup preview my-snapshot --type AWS::EC2::Instance
756
+
757
+ # Use a config file for complex rules
758
+ awsinv cleanup preview my-snapshot --config .awsinv-cleanup.yaml
759
+ ```
760
+
761
+ Example `.awsinv-cleanup.yaml`:
762
+ ```yaml
763
+ # Protection Rules Configuration
764
+ # Resources matching ANY rule are protected from deletion
765
+
766
+ protection:
767
+ # Tag-based protection (OR logic - any matching tag protects)
768
+ tags:
769
+ - key: env
770
+ value: prod # Protect production resources
771
+ - key: keep
772
+ value: "true" # Protect explicitly marked resources
773
+ - key: Owner
774
+ value: "*" # Protect anything with an Owner tag (any value)
775
+
776
+ # Type-based protection
777
+ types:
778
+ - AWS::IAM::Role # Never delete IAM roles
779
+ - AWS::IAM::User # Never delete IAM users
780
+ - AWS::S3::Bucket # Never delete S3 buckets
781
+
782
+ # Age-based protection
783
+ age_days_minimum: 7 # Keep resources older than 7 days
784
+ ```
785
+
786
+ **Config file schema:**
787
+ | Field | Type | Description |
788
+ |-------|------|-------------|
789
+ | `protection.tags[]` | Array | Tag key/value pairs. `value: "*"` matches any value. |
790
+ | `protection.types[]` | Array | Full resource type names (e.g., `AWS::EC2::Instance`) |
791
+ | `protection.age_days_minimum` | Integer | Protect resources older than N days |
792
+
793
+ ### Safety Features
794
+
795
+ - **Preview mode**: Always see what would happen before execution
796
+ - **Confirmation required**: `--confirm` flag mandatory for destructive operations
797
+ - **Dependency ordering**: Deletes in correct order (instances before VPCs, etc.)
798
+ - **Audit logging**: Every deletion logged to `~/.snapshots/audit-logs/`
799
+
800
+ ### Deletion Behavior Notes
801
+
802
+ Some resources have special deletion behavior:
803
+
804
+ | Resource | Behavior |
805
+ |----------|----------|
806
+ | **KMS Keys** | Scheduled for deletion (minimum 7-day wait, not immediate) |
807
+ | **S3 Buckets** | Automatically emptied before deletion (including versioned objects) |
808
+ | **IAM Roles** | Attached policies detached, instance profiles removed first |
809
+ | **Route53 Zones** | All records deleted except NS/SOA before zone deletion |
810
+
811
+ ---
812
+
813
+ ## Supported Resource Types
814
+
815
+ <details>
816
+ <summary><b>Full list of 80+ supported resource types</b></summary>
817
+
818
+ ### Compute
819
+ | Service | Resource Types |
820
+ |---------|---------------|
821
+ | EC2 | Instances, Volumes, VPCs, Subnets, Security Groups, ENIs, Internet Gateways, NAT Gateways, Route Tables, Key Pairs, Elastic IPs, VPC Endpoints |
822
+ | Lambda | Functions, Layers, Event Source Mappings |
823
+ | ECS | Clusters, Services, Task Definitions |
824
+ | EKS | Clusters, Node Groups, Fargate Profiles |
825
+
826
+ ### Storage
827
+ | Service | Resource Types |
828
+ |---------|---------------|
829
+ | S3 | Buckets (with policies, encryption, versioning config) |
830
+ | EBS | Volumes, Snapshots |
831
+ | EFS | File Systems, Mount Targets |
832
+
833
+ ### Database
834
+ | Service | Resource Types |
835
+ |---------|---------------|
836
+ | RDS | DB Instances, DB Clusters, DB Subnet Groups |
837
+ | DynamoDB | Tables |
838
+ | ElastiCache | Clusters, Replication Groups |
839
+
840
+ ### Networking
841
+ | Service | Resource Types |
842
+ |---------|---------------|
843
+ | ELB | Application Load Balancers, Network Load Balancers, Classic Load Balancers, Target Groups |
844
+ | Route53 | Hosted Zones, Record Sets |
845
+ | API Gateway | REST APIs, HTTP APIs, Stages |
846
+
847
+ ### Security & Identity
848
+ | Service | Resource Types |
849
+ |---------|---------------|
850
+ | IAM | Users, Roles, Groups, Policies, Instance Profiles |
851
+ | KMS | Keys, Aliases |
852
+ | Secrets Manager | Secrets |
853
+ | WAF | WebACLs, Rule Groups, IP Sets |
854
+
855
+ ### Management & Monitoring
856
+ | Service | Resource Types |
857
+ |---------|---------------|
858
+ | CloudWatch | Alarms, Log Groups, Dashboards |
859
+ | CloudFormation | Stacks |
860
+ | EventBridge | Rules, Event Buses |
861
+ | SSM | Parameters |
862
+
863
+ ### Developer Tools
864
+ | Service | Resource Types |
865
+ |---------|---------------|
866
+ | CodePipeline | Pipelines |
867
+ | CodeBuild | Projects |
868
+ | Step Functions | State Machines |
869
+
870
+ ### Messaging
871
+ | Service | Resource Types |
872
+ |---------|---------------|
873
+ | SNS | Topics, Subscriptions |
874
+ | SQS | Queues |
875
+
876
+ ### Backup
877
+ | Service | Resource Types |
878
+ |---------|---------------|
879
+ | AWS Backup | Backup Plans, Backup Vaults |
880
+
881
+ </details>
882
+
883
+ ---
884
+
885
+ ## Command Reference
886
+
887
+ ```bash
888
+ # ─────────────────────────────────────────────────────────────
889
+ # SNAPSHOTS
890
+ # ─────────────────────────────────────────────────────────────
891
+ awsinv snapshot create <name> --regions <region1,region2>
892
+ [--use-config/--no-config] # AWS Config usage (default: disabled)
893
+ [--config-aggregator <name>] # Config Aggregator for multi-account
894
+ [--resource-types <svc1,svc2>] # Filter services (e.g., ec2,s3,lambda)
895
+ [--include-tags <key=value>] # Only include tagged resources
896
+ [--inventory <name>] # Assign to inventory group
897
+ [--track-creators] # Tag resources with CloudTrail creator info
898
+ [--created-by-role <role>] # Only include resources created by role
899
+
900
+ awsinv snapshot list # List all snapshots
901
+ awsinv snapshot report # Summary of current/specified snapshot
902
+ [--snapshot <name>]
903
+ [--detailed] # Show all resources
904
+ [--export <file.json|csv>]
905
+
906
+ awsinv snapshot enrich-creators <name> # Add creator info to existing snapshot
907
+ [--days-back <days>] # CloudTrail lookup period (default: 90)
908
+
909
+ # ─────────────────────────────────────────────────────────────
910
+ # ANALYSIS
911
+ # ─────────────────────────────────────────────────────────────
912
+ awsinv delta # Changes since active snapshot
913
+ [--snapshot <name>] # Compare to specific snapshot
914
+ [--show-diff] # Show field-level changes
915
+
916
+ awsinv security scan # Run security checks
917
+ [--severity <CRITICAL|HIGH|MEDIUM|LOW>]
918
+ [--export <file.json>]
919
+
920
+ awsinv cost # Cost analysis
921
+ [--start-date YYYY-MM-DD]
922
+ [--end-date YYYY-MM-DD]
923
+ [--show-services]
924
+
925
+ # ─────────────────────────────────────────────────────────────
926
+ # RESOURCE CLEANUP
927
+ # ─────────────────────────────────────────────────────────────
928
+ # Cleanup: Delete resources created AFTER a snapshot
929
+ awsinv cleanup preview <snapshot> # Dry-run (safe)
930
+ awsinv cleanup execute <snapshot> --confirm
931
+
932
+ # Purge: Delete ALL resources EXCEPT protected ones
933
+ awsinv cleanup purge --protect-tag <key=value> --preview
934
+ awsinv cleanup purge --protect-tag <key=value> --confirm
935
+
936
+ # Common options for both:
937
+ [--type <AWS::Service::Type>] # Filter by resource type
938
+ [--region <region>] # Filter by region
939
+ [--protect-tag <key=value>] # Protect matching resources (repeatable)
940
+ [--config <path>] # Protection rules file
941
+ [-y, --yes] # Skip interactive prompts
942
+
943
+ # ─────────────────────────────────────────────────────────────
944
+ # QUERY & ANALYSIS
945
+ # ─────────────────────────────────────────────────────────────
946
+ awsinv query sql "<SQL>" # Run raw SQL query
947
+ [--format table|json|csv]
948
+
949
+ awsinv query resources # Search resources
950
+ [--type <AWS::Service::Type>] # Filter by type
951
+ [--region <region>] # Filter by region
952
+ [--tag <Key=Value>] # Filter by tag
953
+ [--snapshot <name>] # Limit to snapshot
954
+ [--limit <n>] # Max results
955
+
956
+ awsinv query history <arn> # Resource history across snapshots
957
+
958
+ awsinv query stats # Resource statistics
959
+ [--snapshot <name>] # Specific snapshot
960
+ [--group-by type|region|service] # Grouping
961
+
962
+ awsinv query diff <snap1> <snap2> # Compare two snapshots
963
+ [--type <AWS::Service::Type>]
964
+
965
+ # Example queries:
966
+ awsinv query sql "SELECT resource_type, COUNT(*) FROM resources GROUP BY resource_type"
967
+ awsinv query resources --type "AWS::S3::Bucket" --tag "Environment=prod"
968
+ awsinv query stats --group-by region
969
+
970
+ # ─────────────────────────────────────────────────────────────
971
+ # GLOBAL OPTIONS
972
+ # ─────────────────────────────────────────────────────────────
973
+ --profile <aws-profile> # AWS CLI profile to use
974
+ --storage-path <path> # Custom storage location
975
+ --help # Show help for any command
976
+ ```
977
+
978
+ ---
979
+
980
+ ## Use Cases
981
+
982
+ ### Development Environment Reset
983
+
984
+ > ⚠️ **Warning:** Only use this in dedicated development/sandbox accounts. Never run cleanup commands in production without extensive testing and protection rules.
985
+
986
+ ```bash
987
+ # Morning: Capture clean state
988
+ awsinv snapshot create morning-baseline --regions us-east-1
989
+
990
+ # Evening: Clean up everything created during the day
991
+ awsinv cleanup preview morning-baseline # Always preview first!
992
+ awsinv cleanup execute morning-baseline --confirm
993
+ ```
994
+
995
+ ### Sandbox Account Cleanup
996
+
997
+ > ⚠️ **Warning:** Purge mode deletes ALL resources except protected ones. Triple-check your protection rules before executing.
998
+
999
+ ```bash
1000
+ # Tag your permanent infrastructure with "baseline=true"
1001
+ # Then periodically purge everything else
1002
+
1003
+ awsinv cleanup purge --protect-tag "baseline=true" --preview
1004
+ # Review the preview output carefully!
1005
+ awsinv cleanup purge --protect-tag "baseline=true" --confirm
1006
+ ```
1007
+
1008
+ ### Pre/Post Deployment Comparison
1009
+ ```bash
1010
+ # Before deploy
1011
+ awsinv snapshot create pre-deploy-v2.3 --regions us-east-1,us-west-2
1012
+
1013
+ # Deploy your changes...
1014
+
1015
+ # After deploy - see exactly what changed
1016
+ awsinv delta --snapshot pre-deploy-v2.3 --show-diff
1017
+ ```
1018
+
1019
+ ### Security Audit
1020
+ ```bash
1021
+ # Weekly security scan
1022
+ awsinv snapshot create weekly-audit --regions us-east-1
1023
+ awsinv security scan --export security-report-$(date +%Y%m%d).json
1024
+ ```
1025
+
1026
+ ### Cost Attribution by Team
1027
+ ```bash
1028
+ # Snapshot resources per team
1029
+ awsinv snapshot create team-platform --include-tags "team=platform"
1030
+ awsinv snapshot create team-data --include-tags "team=data"
1031
+
1032
+ # Compare costs
1033
+ awsinv cost --snapshot team-platform
1034
+ awsinv cost --snapshot team-data
1035
+ ```
1036
+
1037
+ ---
1038
+
1039
+ ## Architecture
1040
+
1041
+ ```
1042
+ ┌──────────────────────────────────────────────────────────────┐
1043
+ │ AWS Inventory Manager │
1044
+ ├──────────────────────────────────────────────────────────────┤
1045
+ │ │
1046
+ │ CLI Commands │
1047
+ │ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────┐ ┌─────────┐ │
1048
+ │ │snapshot │ │ delta │ │ security │ │ cost │ │ cleanup │ │
1049
+ │ └────┬────┘ └────┬────┘ └────┬─────┘ └──┬───┘ └────┬────┘ │
1050
+ │ │ │ │ │ │ │
1051
+ ├───────┴───────────┴───────────┴──────────┴──────────┴────────┤
1052
+ │ │
1053
+ │ Collection Layer │
1054
+ │ ┌────────────────────────┐ ┌────────────────────────────┐ │
1055
+ │ │ AWS Config API │ │ Direct Service APIs │ │
1056
+ │ │ (auto-detected, fast) │ │ (fallback, 27 collectors) │ │
1057
+ │ └────────────────────────┘ └────────────────────────────┘ │
1058
+ │ │
1059
+ ├──────────────────────────────────────────────────────────────┤
1060
+ │ │
1061
+ │ Analysis Engines │
1062
+ │ • Configuration Differ (field-level change detection) │
1063
+ │ • Security Scanner (CIS Benchmark checks) │
1064
+ │ • Cost Analyzer (AWS Cost Explorer) │
1065
+ │ • Dependency Resolver (deletion ordering) │
1066
+ │ │
1067
+ ├──────────────────────────────────────────────────────────────┤
1068
+ │ │
1069
+ │ Storage: ~/.snapshots/ │
1070
+ │ • inventory.db (SQLite: snapshots, resources, tags) │
1071
+ │ • audit-logs/**/*.yaml (cleanup operation logs) │
1072
+ │ │
1073
+ └──────────────────────────────────────────────────────────────┘
1074
+ ```
1075
+
1076
+ ---
1077
+
1078
+ ## Development
1079
+
1080
+ ```bash
1081
+ # Clone and install
1082
+ git clone https://github.com/troylar/aws-inventory-manager.git
1083
+ cd aws-inventory-manager
1084
+ pip install -e ".[dev]"
1085
+
1086
+ # Run tests
1087
+ invoke test # All tests with coverage
1088
+ invoke test-unit # Unit tests only (faster)
1089
+
1090
+ # Code quality
1091
+ invoke quality # Lint + typecheck
1092
+ invoke quality --fix # Auto-fix issues
1093
+
1094
+ # Build
1095
+ invoke build # Build distributable package
1096
+ ```
1097
+
1098
+ **Test Coverage:** 1550+ tests, 79% overall coverage. Cleanup module: 98%+ coverage.
1099
+
1100
+ ---
1101
+
1102
+ ## Troubleshooting
1103
+
1104
+ ### Common Issues
1105
+
1106
+ #### "AccessDenied" or "UnauthorizedOperation" errors
1107
+
1108
+ **Problem:** The tool returns permission errors during snapshot collection.
1109
+
1110
+ **Solution:** Ensure your IAM user/role has the required permissions. See [IAM Permissions](#iam-permissions) for the minimum required policies.
1111
+
1112
+ ```bash
1113
+ # Verify your current identity
1114
+ aws sts get-caller-identity
1115
+
1116
+ # Test if you have basic access
1117
+ aws ec2 describe-instances --region us-east-1
1118
+ ```
1119
+
1120
+ #### Snapshot takes a long time
1121
+
1122
+ **Problem:** Creating a snapshot takes several minutes.
1123
+
1124
+ **Solutions:**
1125
+ 1. **Enable AWS Config** for faster collection (up to 5x faster). The tool detects it automatically.
1126
+ 2. **Limit regions:** Only scan regions you use with `--regions us-east-1,us-west-2`
1127
+ 3. **Limit resource types:** Filter to specific services with `--resource-types ec2,s3,lambda`
1128
+
1129
+ ```bash
1130
+ # Faster: Only scan what you need
1131
+ awsinv snapshot create quick-snap --regions us-east-1 --resource-types ec2,lambda
1132
+ ```
1133
+
1134
+ #### "No resources found" in snapshot
1135
+
1136
+ **Problem:** Snapshot completes but shows 0 resources.
1137
+
1138
+ **Possible causes:**
1139
+ 1. **Wrong region:** You may be scanning a region with no resources. Check with `aws ec2 describe-instances --region <region>`
1140
+ 2. **Tag filtering:** If you used `--include-tags`, ensure resources have those tags
1141
+ 3. **Permission issues:** Some describe APIs may silently return empty results instead of errors
1142
+
1143
+ #### Config Aggregator not working
1144
+
1145
+ **Problem:** `--config-aggregator` flag doesn't return cross-account resources.
1146
+
1147
+ **Solutions:**
1148
+ 1. Verify the aggregator exists: `aws configservice describe-configuration-aggregators`
1149
+ 2. Ensure you have `config:SelectAggregateResourceConfig` permission
1150
+ 3. Check that source accounts are properly linked in the aggregator
1151
+ 4. Run from the aggregator's account/region (typically management account)
1152
+
1153
+ #### Cleanup preview shows unexpected resources
1154
+
1155
+ **Problem:** The cleanup preview shows resources you didn't expect to be deleted.
1156
+
1157
+ **Explanation:** Cleanup deletes resources that exist now but didn't exist in the snapshot. This includes:
1158
+ - Resources created after the snapshot
1159
+ - Resources in regions not included in the original snapshot
1160
+ - AWS-managed resources that get auto-created
1161
+
1162
+ **Solutions:**
1163
+ 1. Use `--protect-tag` to protect resources by tag
1164
+ 2. Use `--type` to limit to specific resource types
1165
+ 3. Create a more comprehensive baseline snapshot
1166
+
1167
+ #### Rate limiting / API throttling
1168
+
1169
+ **Problem:** Errors like "Rate exceeded" or "Throttling" during snapshot.
1170
+
1171
+ **Explanation:** The tool includes built-in retry logic with exponential backoff for AWS API rate limits. Most throttling is handled automatically.
1172
+
1173
+ **If you still see issues:**
1174
+ 1. Use `--no-config` to skip Config detection (reduces API calls)
1175
+ 2. Limit regions with `--regions`
1176
+ 3. Limit resource types with `--resource-types`
1177
+ 4. For very large accounts, consider running during off-peak hours
1178
+
1179
+ #### Large accounts (50k+ resources)
1180
+
1181
+ **Problem:** Scanning accounts with tens of thousands of resources.
1182
+
1183
+ **Considerations:**
1184
+ - **Memory:** Snapshot data is held in memory during collection; very large accounts may need 2-4GB RAM
1185
+ - **Database size:** SQLite database grows with resources but handles large datasets efficiently
1186
+ - **Time:** Direct API collection may take 10-15 minutes; AWS Config reduces this significantly
1187
+ - **Recommendation:** Use AWS Config + limit to specific regions/types for large accounts
1188
+
1189
+ ### Frequently Asked Questions
1190
+
1191
+ #### Q: Does this create actual AWS snapshots (EBS, RDS)?
1192
+
1193
+ **No.** "Snapshot" in this tool means an *inventory snapshot* — a catalog of what resources exist. It does not create EBS snapshots, RDS snapshots, or any AWS resources. All data is stored locally in a SQLite database.
1194
+
1195
+ #### Q: Is my AWS data sent anywhere?
1196
+
1197
+ **No.** All data stays local. The tool only makes read API calls to AWS (and delete calls if you use cleanup). All data is stored in a SQLite database at `~/.snapshots/inventory.db` on your local machine.
1198
+
1199
+ #### Q: Can I use this with AWS Organizations?
1200
+
1201
+ **Yes.** Use one of these approaches:
1202
+ 1. **Config Aggregator:** Query all accounts from your management account with `--config-aggregator`
1203
+ 2. **Profile switching:** Create snapshots per account using `--profile`
1204
+ 3. **Cross-account roles:** Configure role assumption in AWS CLI profiles
1205
+
1206
+ #### Q: What happens if AWS Config is only partially enabled?
1207
+
1208
+ The tool handles partial Config coverage gracefully:
1209
+ - **Region has Config:** Uses Config for supported types, direct API for others
1210
+ - **Region lacks Config:** Falls back to direct API for all types
1211
+ - **Type not recorded:** Falls back to direct API for that specific type
1212
+
1213
+ You can see which method was used per resource via the `source` field in snapshots.
1214
+
1215
+ #### Q: How do I undo a cleanup operation?
1216
+
1217
+ **You can't.** Deleted resources are permanently deleted. Always:
1218
+ 1. Use `cleanup preview` first
1219
+ 2. Review the output carefully
1220
+ 3. Consider creating a fresh snapshot before cleanup
1221
+ 4. Use `--protect-tag` to safeguard important resources
1222
+
1223
+ #### Q: Can I schedule automatic snapshots?
1224
+
1225
+ The tool itself doesn't include scheduling, but you can easily add it:
1226
+
1227
+ ```bash
1228
+ # Cron example (daily at midnight)
1229
+ 0 0 * * * /usr/local/bin/awsinv snapshot create daily-$(date +\%Y\%m\%d) --regions us-east-1
1230
+
1231
+ # Or use AWS EventBridge + Lambda to trigger from within AWS
1232
+ ```
1233
+
1234
+ #### Q: Where should I run this tool?
1235
+
1236
+ The tool works anywhere with Python and AWS credentials:
1237
+
1238
+ | Environment | Pros | Cons |
1239
+ |-------------|------|------|
1240
+ | **Local laptop** | Easy setup, interactive preview | Credentials on laptop, network latency |
1241
+ | **EC2 with instance role** | No credential management, low latency | Snapshots stored on instance (back up!) |
1242
+ | **CI/CD pipeline** | Automated, auditable | Credential setup, snapshot storage strategy needed |
1243
+ | **CloudShell** | Zero setup, in-browser | Session timeouts, ephemeral storage |
1244
+
1245
+ For team use, consider storing snapshots in a shared location (see [Data Storage](#data-storage)).
1246
+
1247
+ #### Q: Why does cleanup delete my VPC?
1248
+
1249
+ When you run cleanup execute against a baseline, the tool deletes resources created after that baseline. If the VPC was created after your snapshot, it will be marked for deletion.
1250
+
1251
+ **Best practice:** Always include networking infrastructure in your baseline snapshot, or protect it with tags:
1252
+
1253
+ ```bash
1254
+ awsinv cleanup execute my-baseline --protect-tag "layer=network" --confirm
1255
+ ```
1256
+
1257
+ ---
1258
+
1259
+ ## Contributing
1260
+
1261
+ 1. Fork the repository
1262
+ 2. Create a feature branch (`git checkout -b feature/my-feature`)
1263
+ 3. Run tests: `invoke test`
1264
+ 4. Run quality checks: `invoke quality`
1265
+ 5. Submit a pull request
1266
+
1267
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
1268
+
1269
+ ---
1270
+
1271
+ ## License
1272
+
1273
+ MIT License - see [LICENSE](LICENSE)
1274
+
1275
+ ---
1276
+
1277
+ ## Support
1278
+
1279
+ - **Issues:** [GitHub Issues](https://github.com/troylar/aws-inventory-manager/issues)
1280
+ - **Discussions:** [GitHub Discussions](https://github.com/troylar/aws-inventory-manager/discussions)
1281
+
1282
+ ---
1283
+
1284
+ <div align="center">
1285
+
1286
+ **Built for AWS practitioners who need visibility and control**
1287
+
1288
+ [![Star on GitHub](https://img.shields.io/github/stars/troylar/aws-inventory-manager?style=social)](https://github.com/troylar/aws-inventory-manager)
1289
+
1290
+ Version 0.17.1 • Python 3.8 - 3.13
1291
+
1292
+ </div>