cloud-cost-cli 0.3.0-beta.1 → 0.3.0
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.
package/README.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
A command-line tool that analyzes your AWS and Azure resources to identify cost-saving opportunities — idle resources, oversized instances, unattached volumes, and more.
|
|
9
9
|
|
|
10
|
+
**✨ NEW in v0.3.0:** AI-powered explanations and natural language queries!
|
|
11
|
+
|
|
10
12
|
---
|
|
11
13
|
|
|
12
14
|
## The Problem
|
|
@@ -34,6 +36,11 @@ Cloud bills are growing faster than revenue. Engineering teams overprovision, fo
|
|
|
34
36
|
- ✅ **Multi-cloud support** - AWS and Azure
|
|
35
37
|
- ✅ **AWS analyzers** - EC2, EBS, RDS, S3, ELB, Elastic IP
|
|
36
38
|
- ✅ **Azure analyzers** - VMs, Managed Disks, Storage, SQL, Public IPs
|
|
39
|
+
- ✅ **🤖 AI-powered explanations** - Get human-readable explanations for why resources are costing money
|
|
40
|
+
- ✅ **💬 Natural language queries** - Ask questions like "What's my biggest cost?" or "Show me idle VMs"
|
|
41
|
+
- ✅ **🔒 Privacy-first AI** - Use local Ollama or cloud OpenAI
|
|
42
|
+
- ✅ **💰 Cost tracking** - Track AI API costs (OpenAI only)
|
|
43
|
+
- ✅ **⚙️ Configuration file** - Save your preferences
|
|
37
44
|
- ✅ Connect via cloud credentials (read-only recommended)
|
|
38
45
|
- ✅ Analyze last 7-30 days of usage
|
|
39
46
|
- ✅ Output top savings opportunities with estimated monthly savings
|
|
@@ -44,7 +51,6 @@ Cloud bills are growing faster than revenue. Engineering teams overprovision, fo
|
|
|
44
51
|
**Potential future additions:**
|
|
45
52
|
- GCP support (Compute Engine, Cloud Storage, Cloud SQL)
|
|
46
53
|
- Real-time pricing API integration
|
|
47
|
-
- Configuration file support
|
|
48
54
|
- Additional AWS services (Lambda, DynamoDB, CloudFront, etc.)
|
|
49
55
|
- Additional Azure services (App Services, CosmosDB, etc.)
|
|
50
56
|
- Multi-region analysis
|
|
@@ -61,9 +67,17 @@ No commitment on timeline - contributions welcome!
|
|
|
61
67
|
|
|
62
68
|
**Requirements:**
|
|
63
69
|
- Node.js >= 18
|
|
64
|
-
- Cloud credentials:
|
|
65
|
-
- **AWS**:
|
|
66
|
-
|
|
70
|
+
- Cloud credentials (choose one per provider):
|
|
71
|
+
- **AWS**:
|
|
72
|
+
- [AWS CLI configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) OR
|
|
73
|
+
- Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`)
|
|
74
|
+
- **Azure**:
|
|
75
|
+
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) (`az login`) OR
|
|
76
|
+
- Service Principal (env vars: `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TENANT_ID`) OR
|
|
77
|
+
- Managed Identity (for Azure VMs)
|
|
78
|
+
- **Optional for AI features**:
|
|
79
|
+
- OpenAI API key OR
|
|
80
|
+
- [Ollama](https://ollama.ai) installed locally (free, private, runs on your machine)
|
|
67
81
|
|
|
68
82
|
**Install via npm:**
|
|
69
83
|
```bash
|
|
@@ -74,6 +88,8 @@ npm install -g cloud-cost-cli
|
|
|
74
88
|
|
|
75
89
|
## Usage
|
|
76
90
|
|
|
91
|
+
### Basic Scan
|
|
92
|
+
|
|
77
93
|
**AWS scan:**
|
|
78
94
|
```bash
|
|
79
95
|
cloud-cost-cli scan --provider aws --profile default --region us-east-1
|
|
@@ -81,12 +97,92 @@ cloud-cost-cli scan --provider aws --profile default --region us-east-1
|
|
|
81
97
|
|
|
82
98
|
**Azure scan:**
|
|
83
99
|
```bash
|
|
84
|
-
#
|
|
100
|
+
# Option 1: Azure CLI (easiest for local use)
|
|
101
|
+
az login
|
|
85
102
|
export AZURE_SUBSCRIPTION_ID="your-subscription-id"
|
|
103
|
+
cloud-cost-cli scan --provider azure --location eastus
|
|
86
104
|
|
|
105
|
+
# Option 2: Service Principal (recommended for CI/CD and automation)
|
|
106
|
+
export AZURE_CLIENT_ID="your-app-id"
|
|
107
|
+
export AZURE_CLIENT_SECRET="your-secret"
|
|
108
|
+
export AZURE_TENANT_ID="your-tenant-id"
|
|
109
|
+
export AZURE_SUBSCRIPTION_ID="your-subscription-id"
|
|
87
110
|
cloud-cost-cli scan --provider azure --location eastus
|
|
88
111
|
```
|
|
89
112
|
|
|
113
|
+
**How to create Azure Service Principal:**
|
|
114
|
+
```bash
|
|
115
|
+
# Create service principal with Reader role
|
|
116
|
+
az ad sp create-for-rbac --name "cloud-cost-cli" --role Reader --scopes /subscriptions/YOUR_SUBSCRIPTION_ID
|
|
117
|
+
|
|
118
|
+
# Output will show:
|
|
119
|
+
# {
|
|
120
|
+
# "appId": "xxx", # Use as AZURE_CLIENT_ID
|
|
121
|
+
# "password": "xxx", # Use as AZURE_CLIENT_SECRET
|
|
122
|
+
# "tenant": "xxx" # Use as AZURE_TENANT_ID
|
|
123
|
+
# }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 🤖 AI-Powered Features
|
|
127
|
+
|
|
128
|
+
**Get AI explanations for opportunities:**
|
|
129
|
+
```bash
|
|
130
|
+
# Using OpenAI (requires API key)
|
|
131
|
+
export OPENAI_API_KEY="sk-..."
|
|
132
|
+
cloud-cost-cli scan --provider aws --region us-east-1 --explain
|
|
133
|
+
|
|
134
|
+
# Using local Ollama (free, private, no API key needed)
|
|
135
|
+
cloud-cost-cli scan --provider aws --region us-east-1 --explain --ai-provider ollama
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Ask natural language questions:**
|
|
139
|
+
```bash
|
|
140
|
+
# First, run a scan to collect data
|
|
141
|
+
cloud-cost-cli scan --provider aws --region us-east-1
|
|
142
|
+
|
|
143
|
+
# Then ask questions about your costs
|
|
144
|
+
cloud-cost-cli ask "What's my biggest cost opportunity?"
|
|
145
|
+
cloud-cost-cli ask "Show me all idle EC2 instances"
|
|
146
|
+
cloud-cost-cli ask "How much can I save on storage?"
|
|
147
|
+
cloud-cost-cli ask "Which resources should I optimize first?"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Configure AI settings (saves preferences):**
|
|
151
|
+
```bash
|
|
152
|
+
# Initialize config file
|
|
153
|
+
cloud-cost-cli config init
|
|
154
|
+
|
|
155
|
+
# Set AI provider (openai or ollama)
|
|
156
|
+
cloud-cost-cli config set ai.provider ollama
|
|
157
|
+
|
|
158
|
+
# Set OpenAI API key (if using OpenAI)
|
|
159
|
+
cloud-cost-cli config set ai.apiKey "sk-..."
|
|
160
|
+
|
|
161
|
+
# Set AI model
|
|
162
|
+
cloud-cost-cli config set ai.model "llama3.1:8b" # For Ollama
|
|
163
|
+
cloud-cost-cli config set ai.model "gpt-4o-mini" # For OpenAI
|
|
164
|
+
|
|
165
|
+
# Set max explanations (how many to explain)
|
|
166
|
+
cloud-cost-cli config set ai.maxExplanations 5
|
|
167
|
+
|
|
168
|
+
# View your config
|
|
169
|
+
cloud-cost-cli config show
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Track AI costs (OpenAI only):**
|
|
173
|
+
```bash
|
|
174
|
+
# View AI API costs
|
|
175
|
+
cloud-cost-cli costs
|
|
176
|
+
|
|
177
|
+
# View last 7 days
|
|
178
|
+
cloud-cost-cli costs --days 7
|
|
179
|
+
|
|
180
|
+
# Clear cost tracking
|
|
181
|
+
cloud-cost-cli costs --clear
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Advanced Options
|
|
185
|
+
|
|
90
186
|
**Show more opportunities:**
|
|
91
187
|
```bash
|
|
92
188
|
cloud-cost-cli scan --provider aws --top 20 # Show top 20 instead of default 5
|
|
@@ -102,7 +198,7 @@ cloud-cost-cli scan --provider azure --min-savings 50 # Only show opportunities
|
|
|
102
198
|
cloud-cost-cli scan --provider aws --output json > report.json
|
|
103
199
|
```
|
|
104
200
|
|
|
105
|
-
**Example output:**
|
|
201
|
+
**Example output (with AI explanations):**
|
|
106
202
|
```
|
|
107
203
|
Cloud Cost Optimization Report
|
|
108
204
|
Provider: AWS | Region: us-east-1 | Account: N/A
|
|
@@ -118,18 +214,114 @@ Top 5 Savings Opportunities (est. $1,245/month):
|
|
|
118
214
|
│ 2 │ EBS │ vol-0xyz789abc │ Delete unattached volume (500 GB) │ $40.00 │
|
|
119
215
|
├───┼──────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────┼─────────────┤
|
|
120
216
|
│ 3 │ RDS │ mydb-production │ Downsize from db.r5.xlarge to db.t3.large (CPU: 15%) │ $180.00 │
|
|
121
|
-
├───┼──────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────┼─────────────┤
|
|
122
|
-
│ 4 │ ELB │ my-old-alb │ Delete unused load balancer │ $22.00 │
|
|
123
|
-
├───┼──────────┼────────────────────────────────────────┼──────────────────────────────────────────────────────────┼─────────────┤
|
|
124
|
-
│ 5 │ S3 │ logs-bucket-2023 │ Add lifecycle policy to transition to Glacier │ $938.00 │
|
|
125
217
|
└───┴──────────┴────────────────────────────────────────┴──────────────────────────────────────────────────────────┴─────────────┘
|
|
126
218
|
|
|
219
|
+
🤖 AI Explanations:
|
|
220
|
+
|
|
221
|
+
💡 Opportunity #1: Stop idle instance (CPU: 2%)
|
|
222
|
+
This EC2 instance is consuming only 2% CPU, indicating it's severely underutilized.
|
|
223
|
+
Consider stopping it during off-hours or right-sizing to a smaller instance type.
|
|
224
|
+
Quick win: Stop it immediately if it's a dev/test server not actively used.
|
|
225
|
+
Risk: Low - monitor for 24h first to confirm usage patterns.
|
|
226
|
+
|
|
227
|
+
💡 Opportunity #2: Delete unattached volume (500 GB)
|
|
228
|
+
This EBS volume isn't attached to any instance but you're still paying for storage.
|
|
229
|
+
Either delete it if data isn't needed, or create a snapshot first for backup.
|
|
230
|
+
Quick win: Take a snapshot ($0.05/GB/mo vs $0.08/GB/mo), then delete the volume.
|
|
231
|
+
Risk: Medium - verify no one needs this data before deleting.
|
|
232
|
+
|
|
233
|
+
💡 Opportunity #3: Downsize RDS instance
|
|
234
|
+
Your database is only using 15% CPU on a db.r5.xlarge. You're paying for 4 vCPUs
|
|
235
|
+
but only need 1-2. Downsize to db.t3.large (2 vCPUs) and save $180/month.
|
|
236
|
+
Quick win: Schedule a downsize during your next maintenance window.
|
|
237
|
+
Risk: Low-Medium - test query performance after resize.
|
|
238
|
+
|
|
127
239
|
Total potential savings: $1,245/month ($14,940/year)
|
|
128
240
|
|
|
129
|
-
|
|
241
|
+
ℹ AI explanations powered by OpenAI GPT-4o-mini (cost: $0.02)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## AI Features Setup
|
|
130
247
|
|
|
131
|
-
|
|
132
|
-
|
|
248
|
+
### Option 1: OpenAI (Cloud, Paid)
|
|
249
|
+
|
|
250
|
+
**Pros:** Fast, accurate, works anywhere
|
|
251
|
+
**Cons:** Costs ~$0.01-0.05 per scan, data sent to OpenAI
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Get API key from https://platform.openai.com/api-keys
|
|
255
|
+
export OPENAI_API_KEY="sk-..."
|
|
256
|
+
|
|
257
|
+
# Or save to config
|
|
258
|
+
cloud-cost-cli config set ai.apiKey "sk-..."
|
|
259
|
+
cloud-cost-cli config set ai.provider openai
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Option 2: Ollama (Local, Free)
|
|
263
|
+
|
|
264
|
+
**Pros:** Free, private (runs on your machine), no API costs
|
|
265
|
+
**Cons:** Requires ~4GB RAM, slower than OpenAI
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Install Ollama
|
|
269
|
+
curl -fsSL https://ollama.ai/install.sh | sh
|
|
270
|
+
|
|
271
|
+
# Pull a model (one-time, ~4GB download)
|
|
272
|
+
ollama pull llama3.1:8b
|
|
273
|
+
|
|
274
|
+
# Configure cloud-cost-cli
|
|
275
|
+
cloud-cost-cli config set ai.provider ollama
|
|
276
|
+
cloud-cost-cli config set ai.model "llama3.1:8b"
|
|
277
|
+
|
|
278
|
+
# Use it
|
|
279
|
+
cloud-cost-cli scan --provider aws --region us-east-1 --explain
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Recommended Ollama models:**
|
|
283
|
+
- `llama3.1:8b` - Best balance (4GB RAM, good quality)
|
|
284
|
+
- `llama3.2:3b` - Faster, less RAM (2GB, slightly lower quality)
|
|
285
|
+
- `mistral:7b` - Alternative, similar to llama3.1
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Configuration File
|
|
290
|
+
|
|
291
|
+
**Location:** `~/.cloud-cost-cli.json`
|
|
292
|
+
|
|
293
|
+
**Example config:**
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"ai": {
|
|
297
|
+
"provider": "ollama",
|
|
298
|
+
"model": "llama3.1:8b",
|
|
299
|
+
"maxExplanations": 5,
|
|
300
|
+
"cache": {
|
|
301
|
+
"enabled": true,
|
|
302
|
+
"ttlDays": 7
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
"scan": {
|
|
306
|
+
"defaultProvider": "aws",
|
|
307
|
+
"defaultRegion": "us-east-1",
|
|
308
|
+
"defaultTop": 5,
|
|
309
|
+
"minSavings": 10
|
|
310
|
+
},
|
|
311
|
+
"aws": {
|
|
312
|
+
"profile": "default",
|
|
313
|
+
"region": "us-east-1"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Manage config:**
|
|
319
|
+
```bash
|
|
320
|
+
cloud-cost-cli config init # Create config file
|
|
321
|
+
cloud-cost-cli config show # View current config
|
|
322
|
+
cloud-cost-cli config get ai.provider # Get specific value
|
|
323
|
+
cloud-cost-cli config set ai.provider ollama # Set value
|
|
324
|
+
cloud-cost-cli config path # Show config file location
|
|
133
325
|
```
|
|
134
326
|
|
|
135
327
|
---
|
|
@@ -208,6 +400,8 @@ MIT License - see [LICENSE](LICENSE)
|
|
|
208
400
|
- [Commander.js](https://github.com/tj/commander.js) - CLI framework
|
|
209
401
|
- [cli-table3](https://github.com/cli-table/cli-table3) - Terminal tables
|
|
210
402
|
- [Chalk](https://github.com/chalk/chalk) - Terminal styling
|
|
403
|
+
- [OpenAI API](https://platform.openai.com/) - AI explanations
|
|
404
|
+
- [Ollama](https://ollama.ai) - Local AI models
|
|
211
405
|
|
|
212
406
|
---
|
|
213
407
|
|
|
@@ -224,9 +418,20 @@ A: Read-only permissions for each cloud provider:
|
|
|
224
418
|
**Q: How accurate are the savings estimates?**
|
|
225
419
|
A: Estimates are based on current pricing and usage patterns. Actual savings may vary by region and your specific pricing agreements (Reserved Instances, Savings Plans, etc.).
|
|
226
420
|
|
|
421
|
+
**Q: Is my data sent to OpenAI?**
|
|
422
|
+
A: Only if you use OpenAI for AI features. When you use `--explain` without specifying `--ai-provider`, it defaults to OpenAI and requires an API key. Resource metadata and recommendations are sent to OpenAI's API to generate explanations. If you want complete privacy, use `--ai-provider ollama` (or set it in config) which runs 100% locally on your machine.
|
|
423
|
+
|
|
424
|
+
**Q: How much do AI features cost?**
|
|
425
|
+
A:
|
|
426
|
+
- **Ollama**: Free! Runs locally, no API costs
|
|
427
|
+
- **OpenAI**: ~$0.01-0.05 per scan (GPT-4o-mini). Use `cloud-cost-cli costs` to track spending.
|
|
428
|
+
|
|
227
429
|
**Q: Can I run this in CI/CD?**
|
|
228
430
|
A: Yes. Use `--output json` and parse the results to fail builds if savings exceed a threshold.
|
|
229
431
|
|
|
432
|
+
**Q: Do I need AI features to use the tool?**
|
|
433
|
+
A: No! AI features are completely optional. The core cost scanning works without any AI setup.
|
|
434
|
+
|
|
230
435
|
---
|
|
231
436
|
|
|
232
437
|
**Star this repo if it saves you money!** ⭐
|
|
@@ -172,6 +172,14 @@ async function scanAzure(options) {
|
|
|
172
172
|
else {
|
|
173
173
|
(0, logger_1.info)('Scanning all locations (no filter specified)');
|
|
174
174
|
}
|
|
175
|
+
// Test Azure credentials before scanning
|
|
176
|
+
try {
|
|
177
|
+
await client.testConnection();
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
(0, logger_1.error)(err.message);
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
175
183
|
if (options.accurate) {
|
|
176
184
|
(0, logger_1.info)('Note: --accurate flag is not yet implemented. Using estimated pricing.');
|
|
177
185
|
}
|
|
@@ -12,6 +12,7 @@ export declare class AzureClient {
|
|
|
12
12
|
subscriptionId: string;
|
|
13
13
|
location: string;
|
|
14
14
|
constructor(config?: AzureClientConfig);
|
|
15
|
+
testConnection(): Promise<void>;
|
|
15
16
|
getComputeClient(): ComputeManagementClient;
|
|
16
17
|
getStorageClient(): StorageManagementClient;
|
|
17
18
|
getSqlClient(): SqlManagementClient;
|
|
@@ -22,6 +22,29 @@ class AzureClient {
|
|
|
22
22
|
// Default to East US if no location specified
|
|
23
23
|
this.location = config.location || '';
|
|
24
24
|
}
|
|
25
|
+
// Test Azure credentials by making a lightweight API call
|
|
26
|
+
async testConnection() {
|
|
27
|
+
try {
|
|
28
|
+
const computeClient = this.getComputeClient();
|
|
29
|
+
// Try to list VMs (we'll just get an iterator, not actually iterate)
|
|
30
|
+
const vmsIterator = computeClient.virtualMachines.listAll();
|
|
31
|
+
// Get first page to test auth
|
|
32
|
+
await vmsIterator.next();
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const errorMsg = error.message || '';
|
|
36
|
+
if (errorMsg.includes('No subscriptions found') ||
|
|
37
|
+
errorMsg.includes('authentication') ||
|
|
38
|
+
errorMsg.includes('credentials') ||
|
|
39
|
+
errorMsg.includes('login') ||
|
|
40
|
+
error.statusCode === 401 ||
|
|
41
|
+
error.code === 'CredentialUnavailableError') {
|
|
42
|
+
throw new Error('Azure authentication failed. Please run "az login" first or set up service principal credentials.\n' +
|
|
43
|
+
'See: https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli');
|
|
44
|
+
}
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
25
48
|
getComputeClient() {
|
|
26
49
|
return new arm_compute_1.ComputeManagementClient(this.credential, this.subscriptionId);
|
|
27
50
|
}
|