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**: [AWS CLI configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) or environment variables
66
- - **Azure**: [Azure CLI logged in](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli) or environment variables
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
- # Set Azure subscription ID (or use --subscription-id flag)
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
- Summary: 47 resources analyzed | 12 idle | 8 oversized | 5 unused
241
+ AI explanations powered by OpenAI GPT-4o-mini (cost: $0.02)
242
+ ```
243
+
244
+ ---
245
+
246
+ ## AI Features Setup
130
247
 
131
- 💡 Note: Cost estimates based on us-east-1 pricing and may vary by region.
132
- For more accurate estimates, actual costs depend on your usage and region.
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloud-cost-cli",
3
- "version": "0.3.0-beta.1",
3
+ "version": "0.3.0",
4
4
  "description": "Optimize your cloud spend in seconds",
5
5
  "main": "dist/index.js",
6
6
  "bin": {