argus-cloud-optimizer 0.2.0__tar.gz → 0.4.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.
- {argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info → argus_cloud_optimizer-0.4.0}/PKG-INFO +220 -43
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/README.md +216 -41
- argus_cloud_optimizer-0.4.0/accounts.yaml.example +58 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/monitor.py +85 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/resource_graph.py +2 -2
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/retry.py +1 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/adapter.py +1 -2
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/asset_inventory.py +23 -10
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/cloud_monitoring.py +181 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/anthropic.py +1 -2
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0/argus_cloud_optimizer.egg-info}/PKG-INFO +220 -43
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/argus_cloud_optimizer.egg-info/SOURCES.txt +2 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/argus_cloud_optimizer.egg-info/requires.txt +4 -1
- argus_cloud_optimizer-0.4.0/core/__version__.py +1 -0
- argus_cloud_optimizer-0.4.0/core/agent/chat.py +532 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/agent/loop.py +1 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/agent/prompts.py +129 -59
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/config.py +13 -23
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/delivery.py +3 -7
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/export.py +1 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/generator.py +114 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/html.py +31 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/multi_cloud.py +1 -3
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/secrets.py +4 -6
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/token_tracker.py +2 -5
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/validation.py +19 -10
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/contributing/development.md +13 -8
- argus_cloud_optimizer-0.4.0/docs/deployment/azure.md +279 -0
- argus_cloud_optimizer-0.4.0/docs/deployment/gcp.md +259 -0
- argus_cloud_optimizer-0.4.0/docs/deployment/multi-account.md +407 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/getting-started/configuration.md +14 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/getting-started/index.md +4 -3
- argus_cloud_optimizer-0.4.0/docs/getting-started/quickstart.md +197 -0
- argus_cloud_optimizer-0.4.0/docs/index.md +278 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/env-vars.md +0 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/iam-permissions.md +1 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/index.md +2 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/security.md +1 -1
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/entrypoints/aws_lambda.py +34 -10
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/entrypoints/azure_function.py +39 -9
- argus_cloud_optimizer-0.4.0/entrypoints/cli.py +385 -0
- argus_cloud_optimizer-0.4.0/entrypoints/cli_chat.py +346 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/entrypoints/gcp_cloudrun.py +170 -25
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/pyproject.toml +6 -9
- argus_cloud_optimizer-0.2.0/accounts.yaml.example +0 -25
- argus_cloud_optimizer-0.2.0/core/__version__.py +0 -1
- argus_cloud_optimizer-0.2.0/docs/deployment/azure.md +0 -114
- argus_cloud_optimizer-0.2.0/docs/deployment/gcp.md +0 -77
- argus_cloud_optimizer-0.2.0/docs/deployment/multi-account.md +0 -98
- argus_cloud_optimizer-0.2.0/docs/getting-started/quickstart.md +0 -138
- argus_cloud_optimizer-0.2.0/docs/index.md +0 -210
- argus_cloud_optimizer-0.2.0/entrypoints/cli.py +0 -156
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/.env.example +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/LICENSE +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/MANIFEST.in +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/adapter.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/auth.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/cloudtrail.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/cloudwatch.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/config.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/cost_explorer.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/resource_explorer.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/aws/retry.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/activity_log.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/adapter.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/azure/cost_management.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/base.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/billing.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/cloud_logging.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/adapters/gcp/retry.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/azure_openai.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/base.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/bedrock.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/ai/vertexai.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/argus_cloud_optimizer.egg-info/dependency_links.txt +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/argus_cloud_optimizer.egg-info/entry_points.txt +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/argus_cloud_optimizer.egg-info/top_level.txt +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/agent/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/log.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/models/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/models/finding.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/py.typed +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/core/reports/comparison.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/deploy/aws/multi-account/hub/template.yaml +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/deploy/aws/multi-account/spoke-role.yaml +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/deploy/aws/single-account/template.yaml +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/deploy/azure/function-app.bicep +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/deploy/gcp/deploy.sh +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/concepts/adapters.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/concepts/ai-providers.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/concepts/ai-reasoning.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/concepts/how-it-works.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/concepts/index.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/contributing/index.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/contributing/new-adapter.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/contributing/new-ai-provider.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/deployment/aws.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/deployment/index.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/getting-started/first-scan.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/report-schema.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/resource-types.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/docs/reference/troubleshooting.md +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/entrypoints/__init__.py +0 -0
- {argus_cloud_optimizer-0.2.0 → argus_cloud_optimizer-0.4.0}/setup.cfg +0 -0
{argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info → argus_cloud_optimizer-0.4.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: argus-cloud-optimizer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: AI-powered multi-cloud cost optimization agent
|
|
5
5
|
Author-email: Vamshi Siddarth Gaddam <vamshisiddarth02@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -42,6 +42,8 @@ Requires-Dist: openai>=1.55.0
|
|
|
42
42
|
Provides-Extra: export
|
|
43
43
|
Requires-Dist: weasyprint>=62.0; extra == "export"
|
|
44
44
|
Requires-Dist: python-pptx>=1.0.0; extra == "export"
|
|
45
|
+
Provides-Extra: chat
|
|
46
|
+
Requires-Dist: rich>=13.0.0; extra == "chat"
|
|
45
47
|
Provides-Extra: dev
|
|
46
48
|
Requires-Dist: pytest>=8.3.3; extra == "dev"
|
|
47
49
|
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
@@ -50,7 +52,7 @@ Requires-Dist: pytest-timeout>=2.3.1; extra == "dev"
|
|
|
50
52
|
Requires-Dist: moto[s3,sts]>=5.0.16; extra == "dev"
|
|
51
53
|
Requires-Dist: freezegun>=1.5.1; extra == "dev"
|
|
52
54
|
Requires-Dist: black>=24.10.0; extra == "dev"
|
|
53
|
-
Requires-Dist: ruff
|
|
55
|
+
Requires-Dist: ruff<0.8.0,>=0.7.1; extra == "dev"
|
|
54
56
|
Requires-Dist: mypy>=1.13.0; extra == "dev"
|
|
55
57
|
Requires-Dist: types-PyYAML>=6.0.12; extra == "dev"
|
|
56
58
|
Requires-Dist: types-python-dateutil>=2.9.0; extra == "dev"
|
|
@@ -68,14 +70,33 @@ Dynamic: license-file
|
|
|
68
70
|
Argus finds idle and wasted cloud resources — stopped EC2 instances, unattached EBS volumes, orphaned Elastic IPs, underutilized RDS databases — and delivers a prioritized, AI-reasoned report to Slack every week.
|
|
69
71
|
|
|
70
72
|
[](https://github.com/vamshisiddarth/argus/actions/workflows/ci.yml)
|
|
71
|
-
[](https://github.com/vamshisiddarth/argus/actions/workflows/publish.yml)
|
|
72
74
|
[](https://pypi.org/project/argus-cloud-optimizer/)
|
|
75
|
+
[](https://pypi.org/project/argus-cloud-optimizer/)
|
|
76
|
+
[](https://www.python.org/downloads/)
|
|
73
77
|
[](LICENSE)
|
|
74
78
|
[](https://vamshisiddarth.github.io/argus/)
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
```text
|
|
81
|
+
Argus — AWS Waste Report (2026-06-24)
|
|
82
|
+
|
|
83
|
+
💸 $1,432.85/month estimated waste
|
|
84
|
+
📊 6 idle resources across 1 account
|
|
85
|
+
|
|
86
|
+
Six resources were identified as idle or over-provisioned. The RDS instance
|
|
87
|
+
accounts for 87% of waste and should be right-sized immediately.
|
|
88
|
+
|
|
89
|
+
─────────────────────────────────────
|
|
90
|
+
Top findings
|
|
91
|
+
🔴 db-analytics-01 · RDS · $1,240.00/mo
|
|
92
|
+
🔴 cache-prod-001 · ElastiCache · $142.00/mo
|
|
93
|
+
🔴 i-0abc123def · EC2 · $28.40/mo
|
|
94
|
+
🟡 nat-0def456 · NAT Gateway · $10.80/mo
|
|
95
|
+
🟡 vol-orphan · EBS · $8.00/mo
|
|
96
|
+
⚪ +1 more finding in the full report
|
|
97
|
+
|
|
98
|
+
[ 📄 Full report (HTML) ] [ vamshisiddarth/argus ]
|
|
99
|
+
```
|
|
79
100
|
|
|
80
101
|
---
|
|
81
102
|
|
|
@@ -88,28 +109,9 @@ Every week (or on demand), Argus:
|
|
|
88
109
|
3. **Reasons** about idleness using Claude (via AWS Bedrock, Anthropic API, or Vertex AI) — no hardcoded thresholds
|
|
89
110
|
4. **Reports** a compact digest (Slack, Microsoft Teams, or generic webhook) with top findings and a link to a full self-contained HTML report
|
|
90
111
|
|
|
91
|
-
Example Slack output:
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
Argus — AWS Waste Report (2026-06-17)
|
|
95
|
-
|
|
96
|
-
💸 $42.65/month estimated waste 📊 4 idle resources across 1 account
|
|
97
|
-
|
|
98
|
-
Two stopped EC2 instances and a forgotten NAT Gateway account for 72% of
|
|
99
|
-
total waste. One EBS volume has had no I/O in over 30 days.
|
|
100
|
-
|
|
101
|
-
Top findings
|
|
102
|
-
🔴 i-0abc123def · EC2 t3.large · $28.40/mo
|
|
103
|
-
🔴 nat-0def456 · NAT Gateway · $10.80/mo
|
|
104
|
-
🟡 vol-orphan · EBS gp3 100GiB · $8.00/mo
|
|
105
|
-
🟢 eipalloc-xyz · Elastic IP · $3.65/mo
|
|
106
|
-
|
|
107
|
-
[ 📄 Full report (HTML) ] [ vamshisiddarth/argus ]
|
|
108
|
-
```
|
|
109
|
-
|
|
110
112
|
The **Full report** button links to a self-contained HTML file (S3 / GCS / Azure Blob) with a filterable/sortable table and expandable AI reasoning per finding. Works offline, no login required.
|
|
111
113
|
|
|
112
|
-
> **See
|
|
114
|
+
> **See realistic examples:** [`sample-report-aws.json`](examples/sample-report-aws.json) · [`sample-report-gcp.json`](examples/sample-report-gcp.json) · [`sample-report-azure.json`](examples/sample-report-azure.json) — 5 findings each with AI-written reasoning, metrics, and cost data.
|
|
113
115
|
|
|
114
116
|
---
|
|
115
117
|
|
|
@@ -164,22 +166,48 @@ docker run --rm \
|
|
|
164
166
|
|
|
165
167
|
```bash
|
|
166
168
|
pip install argus-cloud-optimizer
|
|
169
|
+
argus --version # argus 0.3.0
|
|
170
|
+
argus --help
|
|
167
171
|
```
|
|
168
172
|
|
|
169
|
-
One package — all three clouds included. No extras needed.
|
|
173
|
+
One package — all three clouds included. No extras needed. `--cloud` auto-detects from your environment (GCP_PROJECT_ID / AZURE_SUBSCRIPTION_IDS / AWS credentials), or specify explicitly.
|
|
170
174
|
|
|
171
|
-
> **
|
|
175
|
+
> **Verified 2026-06-21:** `pip install argus-cloud-optimizer && argus --version` works on a clean Python 3.11/3.12/3.13 venv with no project files.
|
|
172
176
|
|
|
173
|
-
|
|
177
|
+
**AWS:**
|
|
174
178
|
|
|
175
179
|
```bash
|
|
176
180
|
export AI_PROVIDER=anthropic
|
|
177
181
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
178
|
-
export DRY_RUN=true
|
|
182
|
+
export DRY_RUN=true
|
|
183
|
+
argus scan --cloud aws --dry-run
|
|
184
|
+
# or just: argus scan (auto-detects from AWS_PROFILE / AWS_ACCESS_KEY_ID)
|
|
179
185
|
```
|
|
180
186
|
|
|
187
|
+
> Enable [Resource Explorer](https://docs.aws.amazon.com/resource-explorer/latest/userguide/) with an **aggregator index** in `us-east-1` (or set `RESOURCE_EXPLORER_REGION`).
|
|
188
|
+
|
|
189
|
+
**GCP:**
|
|
190
|
+
|
|
181
191
|
```bash
|
|
182
|
-
|
|
192
|
+
export GCP_PROJECT_ID=my-project-123
|
|
193
|
+
export AI_PROVIDER=anthropic
|
|
194
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
195
|
+
export DRY_RUN=true
|
|
196
|
+
argus scan --cloud gcp --dry-run
|
|
197
|
+
# or just: argus scan (auto-detects from GCP_PROJECT_ID)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
> Requires BigQuery billing export enabled for cost data.
|
|
201
|
+
|
|
202
|
+
**Azure:**
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
export AZURE_SUBSCRIPTION_IDS=sub-id-1,sub-id-2
|
|
206
|
+
export AI_PROVIDER=anthropic
|
|
207
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
208
|
+
export DRY_RUN=true
|
|
209
|
+
argus scan --cloud azure --dry-run
|
|
210
|
+
# or just: argus scan (auto-detects from AZURE_SUBSCRIPTION_IDS)
|
|
183
211
|
```
|
|
184
212
|
|
|
185
213
|
### Option C — Clone and develop
|
|
@@ -192,18 +220,80 @@ cp .env.example .env # edit with your values
|
|
|
192
220
|
argus --cloud aws --run-now
|
|
193
221
|
```
|
|
194
222
|
|
|
223
|
+
### Interactive Chat Mode
|
|
224
|
+
|
|
225
|
+
Ask questions about your cloud infrastructure in natural language:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
pip install argus-cloud-optimizer[chat] # optional: adds rich formatting
|
|
229
|
+
argus chat --cloud aws --ai-provider anthropic # explicit cloud
|
|
230
|
+
argus chat # auto-detects cloud
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
Argus v0.3.0 — Interactive Cloud Cost Assistant
|
|
235
|
+
Cloud: AWS | Accounts: prod (123456789012) | Budget: $1.00/session
|
|
236
|
+
Tip: end a line with \ to continue on the next line.
|
|
237
|
+
Type your question, or /help for commands.
|
|
238
|
+
|
|
239
|
+
argus> What's costing the most and not doing anything?
|
|
240
|
+
|
|
241
|
+
→ Scanning resources
|
|
242
|
+
→ Fetching cost data
|
|
243
|
+
|
|
244
|
+
Argus: Three idle resources account for $73.30/mo in waste:
|
|
245
|
+
• nat-0abc123 (NAT Gateway, us-east-1) — $32.50/mo — 847 bytes in 90 days, delete it
|
|
246
|
+
• db-prod-replica (RDS, us-west-2) — $28.80/mo — zero connections, read replica with no readers
|
|
247
|
+
• vol-0def456 (EBS, us-east-1) — $12.00/mo — unattached since 2026-03-15
|
|
248
|
+
|
|
249
|
+
[this turn: 2,847 in / 412 out, $0.0147 | session: 2,847 in / 412 out, $0.0147 / $1.00 budget]
|
|
250
|
+
|
|
251
|
+
argus> Is the RDS replica definitely safe to delete?
|
|
252
|
+
|
|
253
|
+
→ Fetching metrics: db-prod-replica
|
|
254
|
+
→ Checking last activity: db-prod-replica
|
|
255
|
+
|
|
256
|
+
Argus: Yes. db-prod-replica is confirmed idle — CPU avg 0.1%, DatabaseConnections avg 0,
|
|
257
|
+
last activity 2026-03-21 (93 days ago). The primary db-prod is fully active; this replica
|
|
258
|
+
has no readers. Safe to snapshot and delete. Saves $28.80/mo.
|
|
259
|
+
|
|
260
|
+
[this turn: 1,923 in / 187 out, $0.0089 | session: 4,770 in / 599 out, $0.0236 / $1.00 budget]
|
|
261
|
+
|
|
262
|
+
argus> What would our total monthly bill look like after cleaning all three up?
|
|
263
|
+
|
|
264
|
+
Argus: Current waste: $73.30/mo across the three resources. Deleting all three saves
|
|
265
|
+
$879.60/year. Your remaining infrastructure cost is unchanged — none of these have
|
|
266
|
+
active dependencies based on metrics and activity logs.
|
|
267
|
+
|
|
268
|
+
[this turn: 1,102 in / 98 out, $0.0047 | session: 5,872 in / 697 out, $0.0283 / $1.00 budget]
|
|
269
|
+
|
|
270
|
+
argus> /summary
|
|
271
|
+
Summarizing conversation...
|
|
272
|
+
Done — earlier turns condensed into context.
|
|
273
|
+
|
|
274
|
+
argus> Remind me which one had the highest monthly cost?
|
|
275
|
+
|
|
276
|
+
Argus: nat-0abc123 (NAT Gateway, us-east-1) at $32.50/mo — negligible traffic over 90 days.
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Available REPL commands: `/help`, `/scan`, `/cost`, `/clear`, `/summary`, `/quit`
|
|
280
|
+
|
|
195
281
|
### CLI Options
|
|
196
282
|
|
|
197
283
|
```
|
|
198
|
-
argus --cloud aws|gcp|azure
|
|
284
|
+
argus scan [--cloud aws|gcp|azure] [options] # full batch scan
|
|
285
|
+
argus chat [--cloud aws|gcp|azure] [options] # interactive Q&A
|
|
286
|
+
argus --run-now --cloud aws [options] # backward compat
|
|
199
287
|
|
|
288
|
+
--cloud CLOUD Cloud provider (auto-detected from env vars if omitted)
|
|
200
289
|
-V, --version Show version and exit
|
|
201
290
|
--dry-run Print notification payload instead of posting
|
|
202
291
|
--ignore-regions REGIONS Comma-separated regions to skip (e.g. ap-east-1,me-south-1)
|
|
203
292
|
--ai-provider PROVIDER anthropic | bedrock | vertexai | azure_openai (default: anthropic)
|
|
204
|
-
--accounts PATH Path to accounts.yaml for multi-account mode
|
|
293
|
+
--accounts PATH Path to accounts.yaml for multi-account/project/subscription mode
|
|
205
294
|
--max-resources N Maximum resources to analyze per scan (default: 200)
|
|
206
295
|
--lookback-days DAYS Metrics lookback window in days (default: 90, use 14 for faster local dev)
|
|
296
|
+
--llm-budget USD Cost budget per scan/session (default: $2.00 scan, $1.00 chat)
|
|
207
297
|
```
|
|
208
298
|
|
|
209
299
|
---
|
|
@@ -299,9 +389,11 @@ Set `AI_PROVIDER=anthropic|bedrock|vertexai|azure_openai` in `.env` or the deplo
|
|
|
299
389
|
|
|
300
390
|
---
|
|
301
391
|
|
|
302
|
-
## Multi-account setup
|
|
392
|
+
## Multi-account / multi-project setup
|
|
393
|
+
|
|
394
|
+
Create `accounts.yaml` with the key matching your cloud:
|
|
303
395
|
|
|
304
|
-
|
|
396
|
+
**AWS** (hub/spoke with STS AssumeRole):
|
|
305
397
|
|
|
306
398
|
```yaml
|
|
307
399
|
mode: multi
|
|
@@ -315,10 +407,40 @@ accounts:
|
|
|
315
407
|
role_arn: arn:aws:iam::444455556666:role/ArgusSpokeRole
|
|
316
408
|
```
|
|
317
409
|
|
|
410
|
+
**GCP** (one scan per project, ADC handles auth):
|
|
411
|
+
|
|
412
|
+
```yaml
|
|
413
|
+
mode: multi
|
|
414
|
+
|
|
415
|
+
projects:
|
|
416
|
+
- id: my-project-dev
|
|
417
|
+
name: dev
|
|
418
|
+
- id: my-project-prod
|
|
419
|
+
name: production
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Or set `GCP_PROJECT_IDS=my-project-dev,my-project-prod` instead.
|
|
423
|
+
|
|
424
|
+
**Azure** (cross-subscription via Resource Graph):
|
|
425
|
+
|
|
426
|
+
```yaml
|
|
427
|
+
mode: multi
|
|
428
|
+
|
|
429
|
+
subscriptions:
|
|
430
|
+
- id: "aaaabbbb-cccc-dddd-eeee-ffffffffffff"
|
|
431
|
+
name: dev
|
|
432
|
+
- id: "11112222-3333-4444-5555-666677778888"
|
|
433
|
+
name: production
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Or set `AZURE_SUBSCRIPTION_IDS=sub-1,sub-2` instead.
|
|
437
|
+
|
|
318
438
|
Then run:
|
|
319
439
|
|
|
320
440
|
```bash
|
|
321
|
-
argus --cloud aws --
|
|
441
|
+
argus scan --cloud aws --accounts accounts.yaml
|
|
442
|
+
argus scan --cloud gcp --accounts accounts.yaml
|
|
443
|
+
argus scan --cloud azure --accounts accounts.yaml
|
|
322
444
|
```
|
|
323
445
|
|
|
324
446
|
---
|
|
@@ -347,13 +469,64 @@ No write permissions are ever requested.
|
|
|
347
469
|
|
|
348
470
|
---
|
|
349
471
|
|
|
472
|
+
## IAM permissions (GCP)
|
|
473
|
+
|
|
474
|
+
Argus needs **read-only** access. The service account (`argus-sa@PROJECT.iam.gserviceaccount.com`) requires:
|
|
475
|
+
|
|
476
|
+
```
|
|
477
|
+
cloudasset.assets.listAssets # list all resources (Asset Inventory API)
|
|
478
|
+
monitoring.timeSeries.list # read CPU / memory / request metrics
|
|
479
|
+
monitoring.metricDescriptors.list # discover available metric types
|
|
480
|
+
logging.logEntries.list # read Cloud Audit Logs for last-activity timestamps
|
|
481
|
+
bigquery.jobs.create # only if BILLING_BQ_TABLE is set
|
|
482
|
+
bigquery.tables.getData # only if BILLING_BQ_TABLE is set
|
|
483
|
+
aiplatform.endpoints.predict # only if AI_PROVIDER=vertexai (default)
|
|
484
|
+
storage.objects.create # only if REPORT_GCS_BUCKET is set
|
|
485
|
+
storage.objects.get # only if REPORT_GCS_BUCKET is set
|
|
486
|
+
iam.serviceAccounts.signBlob # only if REPORT_GCS_BUCKET is set
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
No write permissions are ever requested.
|
|
490
|
+
|
|
491
|
+
The deploy script binds `roles/cloudasset.viewer`, `roles/monitoring.viewer`, and `roles/logging.viewer` automatically. For a tighter permission surface, create a custom role using only the exact permissions above — see [GCP deployment docs](docs/deployment/gcp.md#iam-permissions) for the one-command setup.
|
|
492
|
+
|
|
493
|
+
> **BigQuery note:** without `BILLING_BQ_TABLE`, cost fields show `$0.00` — resource
|
|
494
|
+
> discovery and idleness detection still work via metrics and audit logs.
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## IAM permissions (Azure)
|
|
499
|
+
|
|
500
|
+
Argus needs **read-only** access. The Managed Identity requires:
|
|
501
|
+
|
|
502
|
+
```
|
|
503
|
+
Microsoft.ResourceGraph/resources/action # list all resources (Resource Graph KQL)
|
|
504
|
+
Microsoft.Insights/metrics/read # read CPU / memory / request metrics
|
|
505
|
+
Microsoft.Insights/metricDefinitions/read # discover available metric types
|
|
506
|
+
Microsoft.Insights/eventtypes/management/values/read # Activity Log fallback for last-activity
|
|
507
|
+
Microsoft.CostManagement/query/action # run cost queries
|
|
508
|
+
Microsoft.CostManagement/*/read # read cost data
|
|
509
|
+
Microsoft.OperationalInsights/workspaces/query/read # only if logAnalyticsWorkspaceId is set
|
|
510
|
+
Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write # only if reportStorageAccount is set
|
|
511
|
+
Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read # only if reportStorageAccount is set
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
No write permissions are ever requested.
|
|
515
|
+
|
|
516
|
+
The built-in `Reader` + `Cost Management Reader` roles cover all required actions per subscription. For a tighter permission surface, create a custom role using only the exact actions above — see [Azure deployment docs](docs/deployment/azure.md#iam-permissions) for the one-command setup.
|
|
517
|
+
|
|
518
|
+
> **Cost Management note:** `Reader` covers `*/read` but cost queries use a `query/action`
|
|
519
|
+
> verb. `Cost Management Reader` must be added separately — without it, cost fields show `$0.00`.
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
350
523
|
## Limitations & known issues
|
|
351
524
|
|
|
352
525
|
Before you invest time deploying Argus, know what it **can't** do yet:
|
|
353
526
|
|
|
354
527
|
| Area | Status | Details |
|
|
355
528
|
|------|--------|---------|
|
|
356
|
-
| **Resource discovery** |
|
|
529
|
+
| **Resource discovery** | All three strong | AWS covers 43 resource types via Resource Explorer. GCP covers 31 asset types via Asset Inventory. Azure discovers all types via Resource Graph with 40 having curated metric mappings. All three fall back to dynamic metric auto-discovery for unmapped types. AWS has the deepest per-type metric coverage; GCP and Azure are catching up. |
|
|
357
530
|
| **Cost accuracy** | Best-effort | AWS Cost Explorer charges $0.01/API call — Argus batches aggressively (max 2 calls/scan). GCP requires BigQuery billing export enabled. Azure cost data depends on subscription-level access. Resource-level cost allocation must be enabled in AWS for per-resource costs; without it, costs show $0.00. |
|
|
358
531
|
| **AI non-determinism** | By design | The AI decides what's idle — different runs may produce slightly different findings or reasoning. Set `AI_TEMPERATURE=0.0` (default) for most consistent results. |
|
|
359
532
|
| **LLM cost** | Configurable | A full scan of ~200 resources costs ~$0.05–$0.50 in LLM API fees depending on provider. Use `--llm-budget` to set a hard cap (default: $2.00/scan). Large estates (1000+ resources) will hit the budget limit — increase it or use `--max-resources`. |
|
|
@@ -362,16 +535,20 @@ Before you invest time deploying Argus, know what it **can't** do yet:
|
|
|
362
535
|
| **Multi-cloud in one scan** | Not yet | Each `argus` invocation scans one cloud. Use the merge report feature (`core/reports/multi_cloud.py`) to combine results after separate runs. |
|
|
363
536
|
| **Notifications** | Slack + Teams + webhook | No email. Slack/Teams delivery requires a webhook URL. |
|
|
364
537
|
|
|
538
|
+
### Multi-cloud maturity
|
|
539
|
+
|
|
540
|
+
AWS has the richest experience — it was developed first, has the most resource types with curated metric mappings, and has a mature multi-account hub/spoke deployment model. GCP and Azure are fully functional but the AWS adapter has been battle-tested more extensively. Cost data depth also varies: AWS Cost Explorer with resource-level allocation is the most reliable, GCP requires BigQuery billing export to be configured, and Azure Cost Management depends on subscription-level access. All three clouds have dynamic metric fallback for unmapped resource types, so even uncurated types get some signal.
|
|
541
|
+
|
|
365
542
|
### Multi-cloud parity
|
|
366
543
|
|
|
367
544
|
| Capability | AWS | GCP | Azure |
|
|
368
545
|
|-----------|-----|-----|-------|
|
|
369
|
-
| Resource discovery | 43 types (Resource Explorer) |
|
|
370
|
-
| Metrics | CloudWatch (43 types + fallback) | Cloud Monitoring (
|
|
546
|
+
| Resource discovery | 43 types (Resource Explorer) | 31 types (Asset Inventory) | All types (Resource Graph) |
|
|
547
|
+
| Metrics | CloudWatch (43 types + fallback) | Cloud Monitoring (31 types + fallback) | Azure Monitor (40 types + fallback) |
|
|
371
548
|
| Cost data | Cost Explorer (batched) | BigQuery billing export | Cost Management API |
|
|
372
549
|
| Last activity | CloudTrail (90-day lookback) | Cloud Audit Logs | Activity Log / Log Analytics |
|
|
373
550
|
| Deployment | Lambda (SAM) | Cloud Run Job | Azure Function (Bicep) |
|
|
374
|
-
| Multi-account | Hub/spoke with STS |
|
|
551
|
+
| Multi-account | Hub/spoke with STS | Multi-project (per-project scan) | Cross-subscription via Resource Graph |
|
|
375
552
|
| Secret management | Secrets Manager | Secret Manager | Key Vault |
|
|
376
553
|
|
|
377
554
|
---
|
|
@@ -379,9 +556,9 @@ Before you invest time deploying Argus, know what it **can't** do yet:
|
|
|
379
556
|
## Running tests
|
|
380
557
|
|
|
381
558
|
```bash
|
|
382
|
-
make test # unit tests only (
|
|
559
|
+
make test # unit tests only (528 tests, no cloud creds needed)
|
|
383
560
|
make test-integration # integration tests (32 tests — adapter contracts, report schema)
|
|
384
|
-
make test-all # everything (
|
|
561
|
+
make test-all # everything (560 tests)
|
|
385
562
|
```
|
|
386
563
|
|
|
387
564
|
Tests use `unittest.mock` throughout — no real AWS/GCP/Azure calls are made.
|
|
@@ -417,7 +594,7 @@ argus/
|
|
|
417
594
|
│ ├── aws/ # CloudFormation templates
|
|
418
595
|
│ ├── gcp/ # Cloud Run + Scheduler deploy script
|
|
419
596
|
│ └── azure/ # Bicep templates
|
|
420
|
-
└── tests/ #
|
|
597
|
+
└── tests/ # 560 tests, all pass offline
|
|
421
598
|
```
|
|
422
599
|
|
|
423
600
|
---
|