argus-cloud-optimizer 0.2.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/.env.example +102 -0
- argus_cloud_optimizer-0.2.0/LICENSE +21 -0
- argus_cloud_optimizer-0.2.0/MANIFEST.in +6 -0
- argus_cloud_optimizer-0.2.0/PKG-INFO +433 -0
- argus_cloud_optimizer-0.2.0/README.md +372 -0
- argus_cloud_optimizer-0.2.0/accounts.yaml.example +25 -0
- argus_cloud_optimizer-0.2.0/adapters/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/adapter.py +85 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/auth.py +57 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/cloudtrail.py +83 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/cloudwatch.py +732 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/config.py +9 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/cost_explorer.py +116 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/resource_explorer.py +186 -0
- argus_cloud_optimizer-0.2.0/adapters/aws/retry.py +55 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/activity_log.py +159 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/adapter.py +117 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/cost_management.py +125 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/monitor.py +311 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/resource_graph.py +113 -0
- argus_cloud_optimizer-0.2.0/adapters/azure/retry.py +57 -0
- argus_cloud_optimizer-0.2.0/adapters/base.py +105 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/adapter.py +86 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/asset_inventory.py +116 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/billing.py +118 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/cloud_logging.py +93 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/cloud_monitoring.py +276 -0
- argus_cloud_optimizer-0.2.0/adapters/gcp/retry.py +46 -0
- argus_cloud_optimizer-0.2.0/ai/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/ai/anthropic.py +174 -0
- argus_cloud_optimizer-0.2.0/ai/azure_openai.py +241 -0
- argus_cloud_optimizer-0.2.0/ai/base.py +78 -0
- argus_cloud_optimizer-0.2.0/ai/bedrock.py +169 -0
- argus_cloud_optimizer-0.2.0/ai/vertexai.py +234 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/PKG-INFO +433 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/SOURCES.txt +99 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/dependency_links.txt +1 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/entry_points.txt +2 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/requires.txt +40 -0
- argus_cloud_optimizer-0.2.0/argus_cloud_optimizer.egg-info/top_level.txt +4 -0
- argus_cloud_optimizer-0.2.0/core/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/core/__version__.py +1 -0
- argus_cloud_optimizer-0.2.0/core/agent/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/core/agent/loop.py +390 -0
- argus_cloud_optimizer-0.2.0/core/agent/prompts.py +317 -0
- argus_cloud_optimizer-0.2.0/core/config.py +235 -0
- argus_cloud_optimizer-0.2.0/core/log.py +69 -0
- argus_cloud_optimizer-0.2.0/core/models/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/core/models/finding.py +76 -0
- argus_cloud_optimizer-0.2.0/core/py.typed +0 -0
- argus_cloud_optimizer-0.2.0/core/reports/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/core/reports/comparison.py +49 -0
- argus_cloud_optimizer-0.2.0/core/reports/delivery.py +323 -0
- argus_cloud_optimizer-0.2.0/core/reports/export.py +111 -0
- argus_cloud_optimizer-0.2.0/core/reports/generator.py +168 -0
- argus_cloud_optimizer-0.2.0/core/reports/html.py +286 -0
- argus_cloud_optimizer-0.2.0/core/reports/multi_cloud.py +162 -0
- argus_cloud_optimizer-0.2.0/core/secrets.py +145 -0
- argus_cloud_optimizer-0.2.0/core/token_tracker.py +97 -0
- argus_cloud_optimizer-0.2.0/core/validation.py +214 -0
- argus_cloud_optimizer-0.2.0/deploy/aws/multi-account/hub/template.yaml +216 -0
- argus_cloud_optimizer-0.2.0/deploy/aws/multi-account/spoke-role.yaml +111 -0
- argus_cloud_optimizer-0.2.0/deploy/aws/single-account/template.yaml +251 -0
- argus_cloud_optimizer-0.2.0/deploy/azure/function-app.bicep +281 -0
- argus_cloud_optimizer-0.2.0/deploy/gcp/deploy.sh +204 -0
- argus_cloud_optimizer-0.2.0/docs/concepts/adapters.md +96 -0
- argus_cloud_optimizer-0.2.0/docs/concepts/ai-providers.md +103 -0
- argus_cloud_optimizer-0.2.0/docs/concepts/ai-reasoning.md +132 -0
- argus_cloud_optimizer-0.2.0/docs/concepts/how-it-works.md +111 -0
- argus_cloud_optimizer-0.2.0/docs/concepts/index.md +8 -0
- argus_cloud_optimizer-0.2.0/docs/contributing/development.md +106 -0
- argus_cloud_optimizer-0.2.0/docs/contributing/index.md +23 -0
- argus_cloud_optimizer-0.2.0/docs/contributing/new-adapter.md +130 -0
- argus_cloud_optimizer-0.2.0/docs/contributing/new-ai-provider.md +192 -0
- argus_cloud_optimizer-0.2.0/docs/deployment/aws.md +132 -0
- argus_cloud_optimizer-0.2.0/docs/deployment/azure.md +114 -0
- argus_cloud_optimizer-0.2.0/docs/deployment/gcp.md +77 -0
- argus_cloud_optimizer-0.2.0/docs/deployment/index.md +17 -0
- argus_cloud_optimizer-0.2.0/docs/deployment/multi-account.md +98 -0
- argus_cloud_optimizer-0.2.0/docs/getting-started/configuration.md +113 -0
- argus_cloud_optimizer-0.2.0/docs/getting-started/first-scan.md +119 -0
- argus_cloud_optimizer-0.2.0/docs/getting-started/index.md +48 -0
- argus_cloud_optimizer-0.2.0/docs/getting-started/quickstart.md +138 -0
- argus_cloud_optimizer-0.2.0/docs/index.md +210 -0
- argus_cloud_optimizer-0.2.0/docs/reference/env-vars.md +109 -0
- argus_cloud_optimizer-0.2.0/docs/reference/iam-permissions.md +145 -0
- argus_cloud_optimizer-0.2.0/docs/reference/index.md +5 -0
- argus_cloud_optimizer-0.2.0/docs/reference/report-schema.md +62 -0
- argus_cloud_optimizer-0.2.0/docs/reference/resource-types.md +103 -0
- argus_cloud_optimizer-0.2.0/docs/reference/security.md +83 -0
- argus_cloud_optimizer-0.2.0/docs/reference/troubleshooting.md +133 -0
- argus_cloud_optimizer-0.2.0/entrypoints/__init__.py +0 -0
- argus_cloud_optimizer-0.2.0/entrypoints/aws_lambda.py +299 -0
- argus_cloud_optimizer-0.2.0/entrypoints/azure_function.py +257 -0
- argus_cloud_optimizer-0.2.0/entrypoints/cli.py +156 -0
- argus_cloud_optimizer-0.2.0/entrypoints/gcp_cloudrun.py +209 -0
- argus_cloud_optimizer-0.2.0/pyproject.toml +120 -0
- argus_cloud_optimizer-0.2.0/setup.cfg +4 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Argus — Environment Variable Reference
|
|
3
|
+
# Copy this file to .env and fill in your values.
|
|
4
|
+
# NEVER commit .env to git — it is already in .gitignore.
|
|
5
|
+
#
|
|
6
|
+
# Minimum required for a local AWS scan:
|
|
7
|
+
# ANTHROPIC_API_KEY (or configure Bedrock instead)
|
|
8
|
+
# SLACK_WEBHOOK_URL (or set DRY_RUN=true to skip posting)
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
# AI Provider
|
|
13
|
+
# For local dev, use the Anthropic direct API (no cloud setup needed).
|
|
14
|
+
# In production (Lambda), use Bedrock — no key required, uses the IAM role.
|
|
15
|
+
# -----------------------------------------------------------------------------
|
|
16
|
+
AI_PROVIDER=anthropic # anthropic | bedrock | vertexai | azure_openai
|
|
17
|
+
AI_TEMPERATURE=0.0 # 0.0 = deterministic, 1.0 = creative (default: 0.0)
|
|
18
|
+
AI_MODEL= # override model for any provider (optional)
|
|
19
|
+
ANTHROPIC_API_KEY=sk-ant-... # required when AI_PROVIDER=anthropic
|
|
20
|
+
# Secret manager: instead of a literal key, you can use a secret reference:
|
|
21
|
+
# AWS: arn:aws:secretsmanager:us-east-1:123456789012:secret:argus/api-key
|
|
22
|
+
# GCP: gcp-secret://my-project/anthropic-key
|
|
23
|
+
# Azure: akv://my-vault/anthropic-key
|
|
24
|
+
|
|
25
|
+
# Bedrock settings (only used when AI_PROVIDER=bedrock)
|
|
26
|
+
BEDROCK_MODEL_ID=anthropic.claude-sonnet-4-6
|
|
27
|
+
BEDROCK_REGION=us-east-1 # must have model access enabled in this region
|
|
28
|
+
|
|
29
|
+
# -----------------------------------------------------------------------------
|
|
30
|
+
# AWS
|
|
31
|
+
# For local dev: uses ~/.aws/credentials default profile automatically.
|
|
32
|
+
# Set AWS_PROFILE to use a named profile.
|
|
33
|
+
# In production (Lambda): leave blank — uses the execution role.
|
|
34
|
+
# -----------------------------------------------------------------------------
|
|
35
|
+
# AWS_PROFILE=my-profile # uncomment to use a named profile
|
|
36
|
+
PRIMARY_REGION=us-east-1 # region for boto3 session + Bedrock calls
|
|
37
|
+
RESOURCE_EXPLORER_REGION=us-east-1 # must match where your aggregator index lives
|
|
38
|
+
IGNORE_REGIONS= # comma-separated regions to skip (e.g. ap-east-1,me-south-1)
|
|
39
|
+
|
|
40
|
+
# Multi-account mode (leave blank for single-account)
|
|
41
|
+
ACCOUNTS_MODE=single # single | multi
|
|
42
|
+
# ACCOUNTS_CONFIG=[{"id":"111122223333","name":"dev","role_arn":"arn:aws:iam::111122223333:role/ArgusSpokeRole"}]
|
|
43
|
+
|
|
44
|
+
# -----------------------------------------------------------------------------
|
|
45
|
+
# GCP (Phase 6)
|
|
46
|
+
# Uses Application Default Credentials — run: gcloud auth application-default login
|
|
47
|
+
# -----------------------------------------------------------------------------
|
|
48
|
+
GCP_PROJECT_ID=your-gcp-project-id
|
|
49
|
+
BILLING_BQ_TABLE=your-project.billing_dataset.gcp_billing_export_v1
|
|
50
|
+
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json # only if not using ADC
|
|
51
|
+
|
|
52
|
+
# -----------------------------------------------------------------------------
|
|
53
|
+
# Azure (Phase 7)
|
|
54
|
+
# Uses DefaultAzureCredential — run: az login
|
|
55
|
+
# -----------------------------------------------------------------------------
|
|
56
|
+
AZURE_SUBSCRIPTION_IDS=sub-id-1,sub-id-2 # comma-separated subscription IDs
|
|
57
|
+
AZURE_LOG_ANALYTICS_WORKSPACE_ID= # optional — enables Activity Log queries via KQL
|
|
58
|
+
|
|
59
|
+
# -----------------------------------------------------------------------------
|
|
60
|
+
# Report Delivery
|
|
61
|
+
# -----------------------------------------------------------------------------
|
|
62
|
+
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../...
|
|
63
|
+
REPORT_S3_BUCKET= # optional — saves full JSON report to S3
|
|
64
|
+
LOCAL_REPORT_DIR=local_reports # local fallback when no cloud bucket is set
|
|
65
|
+
REPORT_FORMAT=json,html # comma-separated: json, html, pdf, pptx
|
|
66
|
+
|
|
67
|
+
# Set to "true" to log the Slack payload to stdout instead of posting it.
|
|
68
|
+
# Useful for local testing without a real webhook.
|
|
69
|
+
DRY_RUN=false
|
|
70
|
+
|
|
71
|
+
# -----------------------------------------------------------------------------
|
|
72
|
+
# Logging
|
|
73
|
+
# -----------------------------------------------------------------------------
|
|
74
|
+
LOG_LEVEL=INFO # DEBUG | INFO | WARNING | ERROR
|
|
75
|
+
|
|
76
|
+
# -----------------------------------------------------------------------------
|
|
77
|
+
# Scan limits
|
|
78
|
+
# Resources are pre-sorted by cost before reaching the AI.
|
|
79
|
+
# Only the top N (by monthly cost) are analyzed. Raise for very large accounts.
|
|
80
|
+
# -----------------------------------------------------------------------------
|
|
81
|
+
# -----------------------------------------------------------------------------
|
|
82
|
+
# Exclusion Filters
|
|
83
|
+
# Skip resources by tag or type so known false positives are never flagged.
|
|
84
|
+
# -----------------------------------------------------------------------------
|
|
85
|
+
# EXCLUDE_TAGS={"cost-optimization": "excluded"} # JSON dict — any matching tag excludes the resource
|
|
86
|
+
# EXCLUDE_RESOURCE_TYPES=AWS::Lambda::Function # comma-separated resource types to skip
|
|
87
|
+
|
|
88
|
+
MAX_RESOURCES_PER_SCAN=200 # default: 200 (covers >99% of real waste)
|
|
89
|
+
ADAPTER_CONCURRENCY=10 # max parallel metric/activity fetches (default: 10)
|
|
90
|
+
MAX_AGENT_ITERATIONS=50 # max ReAct loop iterations (default: 50)
|
|
91
|
+
|
|
92
|
+
# Hard budget for LLM cost per scan. The scan aborts gracefully if exceeded.
|
|
93
|
+
# Set to 0 to disable the budget check.
|
|
94
|
+
LLM_BUDGET_USD=2.00 # default: $2.00 per scan
|
|
95
|
+
|
|
96
|
+
# Metrics lookback window in days.
|
|
97
|
+
# 90 days is the default — covers quarterly usage patterns and aligns with the
|
|
98
|
+
# CloudTrail lookback horizon. CloudWatch retains daily-granularity data for
|
|
99
|
+
# 455 days so 90 days is well within retention limits.
|
|
100
|
+
# Set to 14 for faster/cheaper local dev runs (not recommended in production —
|
|
101
|
+
# short windows produce false positives by missing weekly/monthly patterns).
|
|
102
|
+
METRICS_LOOKBACK_DAYS=90
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vamshi Siddarth Gaddam
|
|
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.
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: argus-cloud-optimizer
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: AI-powered multi-cloud cost optimization agent
|
|
5
|
+
Author-email: Vamshi Siddarth Gaddam <vamshisiddarth02@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/vamshisiddarth/argus
|
|
8
|
+
Project-URL: Documentation, https://vamshisiddarth.github.io/argus/
|
|
9
|
+
Project-URL: Repository, https://github.com/vamshisiddarth/argus
|
|
10
|
+
Project-URL: Issues, https://github.com/vamshisiddarth/argus/issues
|
|
11
|
+
Keywords: cloud,cost-optimization,aws,gcp,azure,finops
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: System :: Systems Administration
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: anthropic>=0.40.0
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
24
|
+
Requires-Dist: PyYAML>=6.0.2
|
|
25
|
+
Requires-Dist: pydantic>=2.9.2
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.6.0
|
|
27
|
+
Requires-Dist: python-dateutil>=2.9.0
|
|
28
|
+
Requires-Dist: structlog>=24.4.0
|
|
29
|
+
Requires-Dist: boto3>=1.35.36
|
|
30
|
+
Requires-Dist: botocore>=1.35.36
|
|
31
|
+
Requires-Dist: google-cloud-asset>=3.26.0
|
|
32
|
+
Requires-Dist: google-cloud-monitoring>=2.23.0
|
|
33
|
+
Requires-Dist: google-cloud-billing>=1.14.0
|
|
34
|
+
Requires-Dist: google-cloud-logging>=3.11.3
|
|
35
|
+
Requires-Dist: google-cloud-secret-manager>=2.20.0
|
|
36
|
+
Requires-Dist: azure-identity>=1.19.0
|
|
37
|
+
Requires-Dist: azure-mgmt-resourcegraph>=8.0.0
|
|
38
|
+
Requires-Dist: azure-monitor-query<2.0.0,>=1.4.0
|
|
39
|
+
Requires-Dist: azure-mgmt-costmanagement>=4.0.0
|
|
40
|
+
Requires-Dist: azure-keyvault-secrets>=4.8.0
|
|
41
|
+
Requires-Dist: openai>=1.55.0
|
|
42
|
+
Provides-Extra: export
|
|
43
|
+
Requires-Dist: weasyprint>=62.0; extra == "export"
|
|
44
|
+
Requires-Dist: python-pptx>=1.0.0; extra == "export"
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: pytest>=8.3.3; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
|
|
49
|
+
Requires-Dist: pytest-timeout>=2.3.1; extra == "dev"
|
|
50
|
+
Requires-Dist: moto[s3,sts]>=5.0.16; extra == "dev"
|
|
51
|
+
Requires-Dist: freezegun>=1.5.1; extra == "dev"
|
|
52
|
+
Requires-Dist: black>=24.10.0; extra == "dev"
|
|
53
|
+
Requires-Dist: ruff>=0.7.1; extra == "dev"
|
|
54
|
+
Requires-Dist: mypy>=1.13.0; extra == "dev"
|
|
55
|
+
Requires-Dist: types-PyYAML>=6.0.12; extra == "dev"
|
|
56
|
+
Requires-Dist: types-python-dateutil>=2.9.0; extra == "dev"
|
|
57
|
+
Requires-Dist: boto3-stubs[bedrock-runtime,ce,cloudwatch,resourceexplorer2,s3,sts]>=1.35.36; extra == "dev"
|
|
58
|
+
Requires-Dist: mkdocs-material>=9.5.44; extra == "dev"
|
|
59
|
+
Requires-Dist: mkdocs-minify-plugin>=0.8.0; extra == "dev"
|
|
60
|
+
Dynamic: license-file
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="docs/assets/images/logo-full.svg" alt="Argus" height="72">
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<p align="center"><strong>AI-powered cloud cost optimization agent for AWS, GCP, and Azure.</strong></p>
|
|
67
|
+
|
|
68
|
+
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
|
+
|
|
70
|
+
[](https://github.com/vamshisiddarth/argus/actions/workflows/ci.yml)
|
|
71
|
+
[](https://www.python.org/downloads/)
|
|
72
|
+
[](https://pypi.org/project/argus-cloud-optimizer/)
|
|
73
|
+
[](LICENSE)
|
|
74
|
+
[](https://vamshisiddarth.github.io/argus/)
|
|
75
|
+
|
|
76
|
+
<p align="center">
|
|
77
|
+
<img src="docs/assets/images/slack-demo.png" alt="Argus Slack report" width="600">
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## What it does
|
|
83
|
+
|
|
84
|
+
Every week (or on demand), Argus:
|
|
85
|
+
|
|
86
|
+
1. **Discovers** every resource in your cloud account using AWS Resource Explorer / GCP Asset Inventory / Azure Resource Graph
|
|
87
|
+
2. **Analyzes** each candidate — CloudWatch/Cloud Monitoring/Azure Monitor metrics, Cost Explorer/BigQuery/Cost Management cost data, and CloudTrail/Audit Log/Activity Log last-activity timestamps
|
|
88
|
+
3. **Reasons** about idleness using Claude (via AWS Bedrock, Anthropic API, or Vertex AI) — no hardcoded thresholds
|
|
89
|
+
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
|
+
|
|
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
|
+
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
|
+
|
|
112
|
+
> **See a realistic example:** [`examples/sample-report-aws.json`](examples/sample-report-aws.json) — 5 findings from a real-looking AWS scan with AI-written reasoning, metrics, and cost data.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Architecture
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
┌─────────────────────────────────────────────────────────┐
|
|
120
|
+
│ Agent Loop (ReAct) │
|
|
121
|
+
│ Think → Call Tool → Observe → Think → Submit │
|
|
122
|
+
└────────────────────┬────────────────────────────────────┘
|
|
123
|
+
│
|
|
124
|
+
┌────────────┴────────────┐
|
|
125
|
+
▼ ▼
|
|
126
|
+
CloudAdapter AIProvider
|
|
127
|
+
(AWS / GCP / Azure) (Bedrock / Anthropic / Vertex)
|
|
128
|
+
│
|
|
129
|
+
┌────┴──────────────────┐
|
|
130
|
+
│ list_resources │ Resource Explorer / Asset Inventory / Resource Graph
|
|
131
|
+
│ get_metrics │ CloudWatch / Cloud Monitoring / Azure Monitor
|
|
132
|
+
│ get_cost │ Cost Explorer / BigQuery / Cost Management
|
|
133
|
+
│ get_last_activity │ CloudTrail / Audit Logs / Activity Log
|
|
134
|
+
└───────────────────────┘
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Design principle: Same brain. Different hands. Different home.**
|
|
138
|
+
- **Brain** = agent loop + AI reasoning (`core/`) — pure Python, zero cloud imports
|
|
139
|
+
- **Hands** = cloud adapters (`adapters/`) — swappable per cloud
|
|
140
|
+
- **Home** = entrypoints (`entrypoints/`) — Lambda / Cloud Run / Azure Function
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Quick start
|
|
145
|
+
|
|
146
|
+
### Option A — Docker (fastest)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
docker build --build-arg CLOUD=aws -t argus .
|
|
150
|
+
|
|
151
|
+
docker run --rm \
|
|
152
|
+
-e ANTHROPIC_API_KEY=sk-ant-... \
|
|
153
|
+
-e DRY_RUN=true \
|
|
154
|
+
-v ~/.aws:/root/.aws:ro \
|
|
155
|
+
argus --cloud aws --run-now --dry-run
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Option B — Install from PyPI
|
|
159
|
+
|
|
160
|
+
**Prerequisites**
|
|
161
|
+
- Python 3.11+
|
|
162
|
+
- Cloud credentials configured (see below)
|
|
163
|
+
- An Anthropic API key **or** cloud-native AI access (Bedrock / Vertex AI / Azure OpenAI)
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pip install argus-cloud-optimizer
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
One package — all three clouds included. No extras needed.
|
|
170
|
+
|
|
171
|
+
> **AWS-specific setup:** 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` to your aggregator region). Without this, Argus cannot discover resources.
|
|
172
|
+
|
|
173
|
+
Set minimum env vars:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
export AI_PROVIDER=anthropic
|
|
177
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
178
|
+
export DRY_RUN=true # remove to post to Slack
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
argus --cloud aws --run-now --dry-run
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Option C — Clone and develop
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
git clone https://github.com/vamshisiddarth/argus.git
|
|
189
|
+
cd argus
|
|
190
|
+
pip install -e ".[all,dev]"
|
|
191
|
+
cp .env.example .env # edit with your values
|
|
192
|
+
argus --cloud aws --run-now
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### CLI Options
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
argus --cloud aws|gcp|azure --run-now [options]
|
|
199
|
+
|
|
200
|
+
-V, --version Show version and exit
|
|
201
|
+
--dry-run Print notification payload instead of posting
|
|
202
|
+
--ignore-regions REGIONS Comma-separated regions to skip (e.g. ap-east-1,me-south-1)
|
|
203
|
+
--ai-provider PROVIDER anthropic | bedrock | vertexai | azure_openai (default: anthropic)
|
|
204
|
+
--accounts PATH Path to accounts.yaml for multi-account mode (AWS only)
|
|
205
|
+
--max-resources N Maximum resources to analyze per scan (default: 200)
|
|
206
|
+
--lookback-days DAYS Metrics lookback window in days (default: 90, use 14 for faster local dev)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Deploy to AWS Lambda
|
|
212
|
+
|
|
213
|
+
Uses [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) — handles packaging and upload automatically. No S3 bucket needed.
|
|
214
|
+
|
|
215
|
+
### Single account
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
make deploy-aws
|
|
219
|
+
# or manually:
|
|
220
|
+
cd deploy/aws/single-account
|
|
221
|
+
sam build && sam deploy --guided
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`sam deploy --guided` walks you through parameters (Slack webhook, region, AI provider) and saves them to `samconfig.toml` for future deploys. Subsequent deploys are just `sam deploy`.
|
|
225
|
+
|
|
226
|
+
The stack creates:
|
|
227
|
+
- Lambda function (runs weekly via EventBridge)
|
|
228
|
+
- IAM role with least-privilege read-only permissions
|
|
229
|
+
- S3 bucket for full JSON report storage (90-day retention)
|
|
230
|
+
|
|
231
|
+
### Multi-account
|
|
232
|
+
|
|
233
|
+
**Hub account** (runs Argus):
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
make deploy-aws-multi
|
|
237
|
+
# or manually:
|
|
238
|
+
cd deploy/aws/multi-account/hub
|
|
239
|
+
sam build && sam deploy --guided
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Each spoke account** (read-only IAM role only — no Lambda):
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
aws cloudformation deploy \
|
|
246
|
+
--template-file deploy/aws/multi-account/spoke-role.yaml \
|
|
247
|
+
--stack-name Argus-Spoke \
|
|
248
|
+
--capabilities CAPABILITY_IAM \
|
|
249
|
+
--parameter-overrides HubAccountId=<hub-account-id>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The hub stack output includes the `HubRoleArn` — use it as the `HubRoleArn` parameter for spoke deployments.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Deploy to GCP (Cloud Run)
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Authenticate
|
|
260
|
+
gcloud auth application-default login
|
|
261
|
+
|
|
262
|
+
# Set your project
|
|
263
|
+
gcloud config set project YOUR_PROJECT_ID
|
|
264
|
+
|
|
265
|
+
# Deploy
|
|
266
|
+
bash deploy/gcp/deploy.sh
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Requires: Cloud Run API, Cloud Scheduler API, BigQuery billing export enabled.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Deploy to Azure (Function App)
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Authenticate
|
|
277
|
+
az login
|
|
278
|
+
|
|
279
|
+
# Deploy
|
|
280
|
+
az deployment group create \
|
|
281
|
+
--resource-group Argus-RG \
|
|
282
|
+
--template-file deploy/azure/function-app.bicep \
|
|
283
|
+
--parameters subscriptionIds="sub-id-1,sub-id-2" \
|
|
284
|
+
slackWebhookUrl="https://hooks.slack.com/services/..."
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## AI providers
|
|
290
|
+
|
|
291
|
+
| Provider | Use case | Setup |
|
|
292
|
+
|----------|----------|-------|
|
|
293
|
+
| Anthropic API | Local dev, any cloud | Set `ANTHROPIC_API_KEY` |
|
|
294
|
+
| AWS Bedrock | AWS production | IAM role — no key needed |
|
|
295
|
+
| Vertex AI (Gemini) | GCP production | ADC — no key needed |
|
|
296
|
+
| Azure OpenAI (GPT-4o) | Azure production | Managed identity — no key needed |
|
|
297
|
+
|
|
298
|
+
Set `AI_PROVIDER=anthropic|bedrock|vertexai|azure_openai` in `.env` or the deployment environment. Use `AI_MODEL` to override the model for any provider, and `AI_TEMPERATURE` to control creativity (default: `0.0`).
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Multi-account setup
|
|
303
|
+
|
|
304
|
+
Create `accounts.yaml`:
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
mode: multi
|
|
308
|
+
|
|
309
|
+
accounts:
|
|
310
|
+
- id: "111122223333"
|
|
311
|
+
name: dev
|
|
312
|
+
role_arn: arn:aws:iam::111122223333:role/ArgusSpokeRole
|
|
313
|
+
- id: "444455556666"
|
|
314
|
+
name: prod
|
|
315
|
+
role_arn: arn:aws:iam::444455556666:role/ArgusSpokeRole
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Then run:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
argus --cloud aws --run-now --accounts accounts.yaml
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## IAM permissions (AWS)
|
|
327
|
+
|
|
328
|
+
Argus needs **read-only** access. The Lambda execution role requires:
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
resource-explorer-2:Search
|
|
332
|
+
resource-explorer-2:GetView
|
|
333
|
+
cloudwatch:GetMetricData
|
|
334
|
+
ce:GetCostAndUsage
|
|
335
|
+
ce:GetCostAndUsageWithResources
|
|
336
|
+
cloudtrail:LookupEvents
|
|
337
|
+
bedrock:InvokeModel # only if AI_PROVIDER=bedrock
|
|
338
|
+
sts:AssumeRole # only for multi-account mode
|
|
339
|
+
s3:PutObject # only if REPORT_S3_BUCKET is set
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
No write permissions are ever requested.
|
|
343
|
+
|
|
344
|
+
> **Cost Explorer note:** `GetCostAndUsageWithResources` requires resource-level cost allocation
|
|
345
|
+
> to be enabled in AWS Cost Management → Preferences → Resource-level data.
|
|
346
|
+
> If not enabled, Argus logs a warning and continues — cost fields will show $0.00.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Limitations & known issues
|
|
351
|
+
|
|
352
|
+
Before you invest time deploying Argus, know what it **can't** do yet:
|
|
353
|
+
|
|
354
|
+
| Area | Status | Details |
|
|
355
|
+
|------|--------|---------|
|
|
356
|
+
| **Resource discovery** | AWS: strong, GCP/Azure: adequate | AWS covers 43 resource types via Resource Explorer. GCP covers 22 asset types; Azure covers 25 via Resource Graph. Some niche resource types (e.g. AWS Glue, SageMaker endpoints) are not yet mapped. |
|
|
357
|
+
| **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
|
+
| **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
|
+
| **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`. |
|
|
360
|
+
| **AWS Resource Explorer setup** | Manual step | You must enable Resource Explorer with an **aggregator index** (typically in `us-east-1`). Without this, Argus cannot discover resources. This is a one-time setup but is easy to miss. |
|
|
361
|
+
| **Write actions** | None | Argus is read-only. It reports findings but never deletes, stops, or modifies resources. Remediation is manual. |
|
|
362
|
+
| **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
|
+
| **Notifications** | Slack + Teams + webhook | No email. Slack/Teams delivery requires a webhook URL. |
|
|
364
|
+
|
|
365
|
+
### Multi-cloud parity
|
|
366
|
+
|
|
367
|
+
| Capability | AWS | GCP | Azure |
|
|
368
|
+
|-----------|-----|-----|-------|
|
|
369
|
+
| Resource discovery | 43 types (Resource Explorer) | 22 types (Asset Inventory) | 25 types (Resource Graph) |
|
|
370
|
+
| Metrics | CloudWatch (43 types + fallback) | Cloud Monitoring (15 types + fallback) | Azure Monitor (25 types + fallback) |
|
|
371
|
+
| Cost data | Cost Explorer (batched) | BigQuery billing export | Cost Management API |
|
|
372
|
+
| Last activity | CloudTrail (90-day lookback) | Cloud Audit Logs | Activity Log / Log Analytics |
|
|
373
|
+
| Deployment | Lambda (SAM) | Cloud Run Job | Azure Function (Bicep) |
|
|
374
|
+
| Multi-account | Hub/spoke with STS | Single project only | Cross-subscription via Resource Graph |
|
|
375
|
+
| Secret management | Secrets Manager | Secret Manager | Key Vault |
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Running tests
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
make test # unit tests only (431 tests, no cloud creds needed)
|
|
383
|
+
make test-integration # integration tests (32 tests — adapter contracts, report schema)
|
|
384
|
+
make test-all # everything (463 tests)
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Tests use `unittest.mock` throughout — no real AWS/GCP/Azure calls are made.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Project structure
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
argus/
|
|
395
|
+
├── core/ # Pure Python — no cloud imports
|
|
396
|
+
│ ├── agent/loop.py # ReAct agent loop
|
|
397
|
+
│ ├── agent/prompts.py # System prompt + tool schemas
|
|
398
|
+
│ ├── models/finding.py # ResourceFinding dataclass
|
|
399
|
+
│ └── reports/ # Report generator, multi-cloud merge, export, notifications
|
|
400
|
+
├── adapters/
|
|
401
|
+
│ ├── base.py # CloudAdapter abstract class
|
|
402
|
+
│ ├── aws/ # AWS adapter (Resource Explorer, CloudWatch, Cost Explorer, CloudTrail)
|
|
403
|
+
│ ├── gcp/ # GCP adapter (Asset Inventory, Cloud Monitoring, BigQuery, Audit Logs)
|
|
404
|
+
│ └── azure/ # Azure adapter (Resource Graph, Monitor, Cost Management, Activity Log)
|
|
405
|
+
├── ai/
|
|
406
|
+
│ ├── base.py # AIProvider abstract class
|
|
407
|
+
│ ├── anthropic.py # Anthropic API (local dev / universal fallback)
|
|
408
|
+
│ ├── bedrock.py # AWS Bedrock (Converse API)
|
|
409
|
+
│ ├── vertexai.py # Vertex AI / Gemini (GCP)
|
|
410
|
+
│ └── azure_openai.py # Azure OpenAI / GPT-4o (Azure)
|
|
411
|
+
├── entrypoints/
|
|
412
|
+
│ ├── cli.py # argus --cloud aws --run-now
|
|
413
|
+
│ ├── aws_lambda.py # AWS Lambda handler
|
|
414
|
+
│ ├── gcp_cloudrun.py # GCP Cloud Run Job handler
|
|
415
|
+
│ └── azure_function.py # Azure Function timer trigger
|
|
416
|
+
├── deploy/
|
|
417
|
+
│ ├── aws/ # CloudFormation templates
|
|
418
|
+
│ ├── gcp/ # Cloud Run + Scheduler deploy script
|
|
419
|
+
│ └── azure/ # Bicep templates
|
|
420
|
+
└── tests/ # 463 tests, all pass offline
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Contributing
|
|
426
|
+
|
|
427
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
MIT
|