cloud-cost-cli 0.1.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/LICENSE +21 -0
- package/README.md +235 -0
- package/dist/bin/cloud-cost-cli.d.ts +2 -0
- package/dist/bin/cloud-cost-cli.js +23 -0
- package/dist/src/analyzers/cost-estimator.d.ts +21 -0
- package/dist/src/analyzers/cost-estimator.js +86 -0
- package/dist/src/commands/scan.d.ts +12 -0
- package/dist/src/commands/scan.js +111 -0
- package/dist/src/providers/aws/client.d.ts +27 -0
- package/dist/src/providers/aws/client.js +53 -0
- package/dist/src/providers/aws/ebs.d.ts +3 -0
- package/dist/src/providers/aws/ebs.js +41 -0
- package/dist/src/providers/aws/ec2.d.ts +3 -0
- package/dist/src/providers/aws/ec2.js +75 -0
- package/dist/src/providers/aws/eip.d.ts +3 -0
- package/dist/src/providers/aws/eip.js +38 -0
- package/dist/src/providers/aws/elb.d.ts +3 -0
- package/dist/src/providers/aws/elb.js +66 -0
- package/dist/src/providers/aws/rds.d.ts +3 -0
- package/dist/src/providers/aws/rds.js +92 -0
- package/dist/src/providers/aws/s3.d.ts +3 -0
- package/dist/src/providers/aws/s3.js +54 -0
- package/dist/src/reporters/json.d.ts +2 -0
- package/dist/src/reporters/json.js +6 -0
- package/dist/src/reporters/table.d.ts +2 -0
- package/dist/src/reporters/table.js +41 -0
- package/dist/src/types/index.d.ts +2 -0
- package/dist/src/types/index.js +18 -0
- package/dist/src/types/opportunity.d.ts +31 -0
- package/dist/src/types/opportunity.js +2 -0
- package/dist/src/types/provider.d.ts +15 -0
- package/dist/src/types/provider.js +2 -0
- package/dist/src/utils/formatter.d.ts +3 -0
- package/dist/src/utils/formatter.js +16 -0
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/index.js +18 -0
- package/dist/src/utils/logger.d.ts +6 -0
- package/dist/src/utils/logger.js +30 -0
- package/docs/RELEASE.md +143 -0
- package/docs/contributing.md +201 -0
- package/docs/iam-policy.json +25 -0
- package/docs/installation.md +208 -0
- package/package.json +69 -0
package/docs/RELEASE.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Release Process
|
|
2
|
+
|
|
3
|
+
This document describes how to publish a new version of cloud-cost-cli.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
### 1. NPM Granular Access Token
|
|
8
|
+
|
|
9
|
+
npm now uses "Granular Access Tokens" instead of automation tokens.
|
|
10
|
+
|
|
11
|
+
**Create the token:**
|
|
12
|
+
1. Go to https://www.npmjs.com/settings/YOUR_USERNAME/tokens
|
|
13
|
+
2. Click **"Generate New Token"** → **"Granular Access Token"**
|
|
14
|
+
3. Configure the token:
|
|
15
|
+
- **Token name**: `cloud-cost-cli-publish` (or any name)
|
|
16
|
+
- **Expiration**: 1 year (or No expiration)
|
|
17
|
+
- **Packages and scopes**: Select packages → Choose `cloud-cost-cli`
|
|
18
|
+
- **Permissions**: Read and write
|
|
19
|
+
4. Click **"Generate Token"**
|
|
20
|
+
5. Copy the token (starts with `npm_...`)
|
|
21
|
+
|
|
22
|
+
### 2. Add Token to GitHub Secrets
|
|
23
|
+
|
|
24
|
+
1. Go to https://github.com/vuhp/cloud-cost-cli/settings/secrets/actions
|
|
25
|
+
2. Click **"New repository secret"**
|
|
26
|
+
3. Name: `NPM_TOKEN`
|
|
27
|
+
4. Value: (paste the `npm_...` token)
|
|
28
|
+
5. Click **"Add secret"**
|
|
29
|
+
|
|
30
|
+
## Steps to Release
|
|
31
|
+
|
|
32
|
+
### 1. Update Version
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Bump version (choose one)
|
|
36
|
+
npm version patch # 0.1.0 → 0.1.1 (bug fixes)
|
|
37
|
+
npm version minor # 0.1.0 → 0.2.0 (new features)
|
|
38
|
+
npm version major # 0.1.0 → 1.0.0 (breaking changes)
|
|
39
|
+
|
|
40
|
+
# Push version commit and tag
|
|
41
|
+
git push && git push --tags
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Create GitHub Release
|
|
45
|
+
|
|
46
|
+
**Option A: Via GitHub UI**
|
|
47
|
+
1. Go to https://github.com/vuhp/cloud-cost-cli/releases/new
|
|
48
|
+
2. Choose the version tag (e.g., `v0.1.0`)
|
|
49
|
+
3. Title: `v0.1.0 - Initial Release`
|
|
50
|
+
4. Description: Add release notes (features, fixes, breaking changes)
|
|
51
|
+
5. Click **Publish release**
|
|
52
|
+
|
|
53
|
+
**Option B: Via GitHub CLI**
|
|
54
|
+
```bash
|
|
55
|
+
gh release create v0.1.0 \
|
|
56
|
+
--title "v0.1.0 - Initial Release" \
|
|
57
|
+
--notes "First public release with AWS support"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Automated Publishing
|
|
61
|
+
|
|
62
|
+
Once you publish the GitHub release:
|
|
63
|
+
- GitHub Actions workflow triggers automatically
|
|
64
|
+
- Builds the TypeScript code
|
|
65
|
+
- Publishes to npm with provenance
|
|
66
|
+
- Package is live at https://www.npmjs.com/package/cloud-cost-cli
|
|
67
|
+
|
|
68
|
+
### 4. Verify
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Check npm
|
|
72
|
+
npm view cloud-cost-cli
|
|
73
|
+
|
|
74
|
+
# Test installation
|
|
75
|
+
npx cloud-cost-cli@latest --version
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Release Notes Template
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
## What's New
|
|
82
|
+
|
|
83
|
+
### Features
|
|
84
|
+
- ✨ Add XYZ analyzer
|
|
85
|
+
- 🚀 Improve performance by 2x
|
|
86
|
+
|
|
87
|
+
### Bug Fixes
|
|
88
|
+
- 🐛 Fix region handling for profiles
|
|
89
|
+
- 🐛 Correct cost calculation for RDS
|
|
90
|
+
|
|
91
|
+
### Documentation
|
|
92
|
+
- 📝 Add examples for GCP
|
|
93
|
+
- 📝 Update IAM policy
|
|
94
|
+
|
|
95
|
+
### Breaking Changes
|
|
96
|
+
- ⚠️ Rename `--days` to `--period`
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
\`\`\`bash
|
|
101
|
+
npm install -g cloud-cost-cli
|
|
102
|
+
# or
|
|
103
|
+
npx cloud-cost-cli scan
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
**Full Changelog**: https://github.com/vuhp/cloud-cost-cli/compare/v0.0.9...v0.1.0
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Rollback
|
|
110
|
+
|
|
111
|
+
If something goes wrong:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Deprecate the broken version
|
|
115
|
+
npm deprecate cloud-cost-cli@0.1.0 "Broken release, use 0.1.1"
|
|
116
|
+
|
|
117
|
+
# Publish a patch
|
|
118
|
+
npm version patch
|
|
119
|
+
git push && git push --tags
|
|
120
|
+
# Then create new GitHub release
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Manual Publishing (Emergency Only)
|
|
124
|
+
|
|
125
|
+
If GitHub Actions fails:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm run build
|
|
129
|
+
npm login
|
|
130
|
+
npm publish --access public
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Checklist
|
|
134
|
+
|
|
135
|
+
Before releasing:
|
|
136
|
+
- [ ] All tests pass
|
|
137
|
+
- [ ] Version bumped in package.json
|
|
138
|
+
- [ ] CHANGELOG.md updated
|
|
139
|
+
- [ ] README.md reflects new features
|
|
140
|
+
- [ ] Git tag created
|
|
141
|
+
- [ ] GitHub release published
|
|
142
|
+
- [ ] npm package verified
|
|
143
|
+
- [ ] Announcement posted (Twitter, HN, etc.)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Contributing to Cloud Cost CLI
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This project welcomes contributions of all kinds.
|
|
4
|
+
|
|
5
|
+
## Ways to Contribute
|
|
6
|
+
|
|
7
|
+
- 🐛 Report bugs or issues
|
|
8
|
+
- 💡 Suggest new features or analyzers
|
|
9
|
+
- 📝 Improve documentation
|
|
10
|
+
- 🧪 Add tests
|
|
11
|
+
- 💻 Submit code improvements or new cloud providers
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Development Setup
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- Node.js >= 18
|
|
20
|
+
- Git
|
|
21
|
+
- AWS account (for testing)
|
|
22
|
+
|
|
23
|
+
### Clone and Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/vuhp/cloud-cost-cli.git
|
|
27
|
+
cd cloud-cost-cli
|
|
28
|
+
npm install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Run Locally
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm run dev -- scan --profile your-aws-profile
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Build
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run build
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Output will be in `dist/` directory.
|
|
44
|
+
|
|
45
|
+
### Run Tests
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Project Structure
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
cloud-cost-cli/
|
|
57
|
+
├── bin/ # CLI entry point
|
|
58
|
+
├── src/
|
|
59
|
+
│ ├── commands/ # Command implementations (scan, etc.)
|
|
60
|
+
│ ├── providers/ # Cloud provider integrations
|
|
61
|
+
│ │ └── aws/ # AWS-specific analyzers
|
|
62
|
+
│ ├── analyzers/ # Shared analysis logic
|
|
63
|
+
│ ├── reporters/ # Output formatters (table, JSON, markdown)
|
|
64
|
+
│ ├── types/ # TypeScript type definitions
|
|
65
|
+
│ └── utils/ # Helper functions
|
|
66
|
+
├── docs/ # Documentation
|
|
67
|
+
└── tests/ # Unit and integration tests
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Adding a New Analyzer
|
|
73
|
+
|
|
74
|
+
Example: Add a Lambda cost analyzer for AWS.
|
|
75
|
+
|
|
76
|
+
### 1. Create analyzer file
|
|
77
|
+
|
|
78
|
+
`src/providers/aws/lambda.ts`
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { AWSClient } from './client';
|
|
82
|
+
import { SavingsOpportunity } from '../../types';
|
|
83
|
+
|
|
84
|
+
export async function analyzeLambdaFunctions(
|
|
85
|
+
client: AWSClient
|
|
86
|
+
): Promise<SavingsOpportunity[]> {
|
|
87
|
+
// Implementation here
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Update scan command
|
|
93
|
+
|
|
94
|
+
`src/commands/scan.ts`
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { analyzeLambdaFunctions } from '../providers/aws/lambda';
|
|
98
|
+
|
|
99
|
+
// In scanCommand function, add:
|
|
100
|
+
const lambdaOpportunities = await analyzeLambdaFunctions(client);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Add tests
|
|
104
|
+
|
|
105
|
+
`tests/unit/providers/aws/lambda.test.ts`
|
|
106
|
+
|
|
107
|
+
### 4. Update README
|
|
108
|
+
|
|
109
|
+
Document the new analyzer and what it checks.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Adding a New Cloud Provider
|
|
114
|
+
|
|
115
|
+
Example: Add GCP support.
|
|
116
|
+
|
|
117
|
+
### 1. Create provider directory
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
src/providers/gcp/
|
|
121
|
+
├── client.ts
|
|
122
|
+
├── compute.ts
|
|
123
|
+
├── storage.ts
|
|
124
|
+
└── ...
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 2. Implement analyzers
|
|
128
|
+
|
|
129
|
+
Follow the same pattern as AWS analyzers.
|
|
130
|
+
|
|
131
|
+
### 3. Update scan command
|
|
132
|
+
|
|
133
|
+
Add GCP-specific logic to `src/commands/scan.ts`.
|
|
134
|
+
|
|
135
|
+
### 4. Update CLI options
|
|
136
|
+
|
|
137
|
+
Add `gcp` to `--provider` flag in `bin/cloud-cost-cli.ts`.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Code Style
|
|
142
|
+
|
|
143
|
+
- **TypeScript**: Use strict mode, explicit types
|
|
144
|
+
- **Formatting**: Run `npm run format` before committing
|
|
145
|
+
- **Linting**: Run `npm run lint` to catch issues
|
|
146
|
+
- **Naming**: Use descriptive variable and function names
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Commit Messages
|
|
151
|
+
|
|
152
|
+
Follow conventional commits:
|
|
153
|
+
|
|
154
|
+
- `feat: add Lambda analyzer`
|
|
155
|
+
- `fix: correct RDS cost calculation`
|
|
156
|
+
- `docs: update installation guide`
|
|
157
|
+
- `test: add EBS analyzer tests`
|
|
158
|
+
- `chore: update dependencies`
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Pull Request Process
|
|
163
|
+
|
|
164
|
+
1. **Fork** the repository
|
|
165
|
+
2. **Create a branch**: `git checkout -b feature/my-feature`
|
|
166
|
+
3. **Make changes** and commit with clear messages
|
|
167
|
+
4. **Test** locally: `npm run build && npm test`
|
|
168
|
+
5. **Push** to your fork: `git push origin feature/my-feature`
|
|
169
|
+
6. **Open a PR** with:
|
|
170
|
+
- Clear description of changes
|
|
171
|
+
- Screenshots (if UI-related)
|
|
172
|
+
- Test results
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Reporting Issues
|
|
177
|
+
|
|
178
|
+
When reporting bugs, please include:
|
|
179
|
+
|
|
180
|
+
- CLI version (`cloud-cost-cli --version`)
|
|
181
|
+
- Node.js version (`node --version`)
|
|
182
|
+
- Cloud provider and region
|
|
183
|
+
- Command you ran
|
|
184
|
+
- Full error message
|
|
185
|
+
- Expected vs actual behavior
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Questions?
|
|
190
|
+
|
|
191
|
+
- Open a discussion: https://github.com/vuhp/cloud-cost-cli/discussions
|
|
192
|
+
- Join Discord: (link if available)
|
|
193
|
+
- Email: vuhuuphuong@gmail.com
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
200
|
+
|
|
201
|
+
Thank you for making cloud cost optimization better for everyone! 🚀
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Version": "2012-10-17",
|
|
3
|
+
"Statement": [
|
|
4
|
+
{
|
|
5
|
+
"Sid": "CloudCostCLIReadOnly",
|
|
6
|
+
"Effect": "Allow",
|
|
7
|
+
"Action": [
|
|
8
|
+
"ec2:DescribeInstances",
|
|
9
|
+
"ec2:DescribeVolumes",
|
|
10
|
+
"ec2:DescribeAddresses",
|
|
11
|
+
"ec2:DescribeRegions",
|
|
12
|
+
"rds:DescribeDBInstances",
|
|
13
|
+
"s3:ListAllMyBuckets",
|
|
14
|
+
"s3:GetBucketLocation",
|
|
15
|
+
"s3:GetBucketLifecycleConfiguration",
|
|
16
|
+
"elasticloadbalancing:DescribeLoadBalancers",
|
|
17
|
+
"elasticloadbalancing:DescribeTargetGroups",
|
|
18
|
+
"elasticloadbalancing:DescribeTargetHealth",
|
|
19
|
+
"cloudwatch:GetMetricStatistics",
|
|
20
|
+
"ce:GetCostAndUsage"
|
|
21
|
+
],
|
|
22
|
+
"Resource": "*"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Cloud Cost CLI - Installation & Usage
|
|
2
|
+
|
|
3
|
+
## Quick Start
|
|
4
|
+
|
|
5
|
+
### Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js >= 18
|
|
8
|
+
- AWS account with configured credentials
|
|
9
|
+
- IAM permissions (see [iam-policy.json](./iam-policy.json))
|
|
10
|
+
|
|
11
|
+
### Installation
|
|
12
|
+
|
|
13
|
+
**Option 1: npm (recommended)**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g cloud-cost-cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Option 2: npx (no install)**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx cloud-cost-cli scan
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Option 3: Clone and run locally**
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/vuhp/cloud-cost-cli.git
|
|
29
|
+
cd cloud-cost-cli
|
|
30
|
+
npm install
|
|
31
|
+
npm run dev -- scan
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## AWS Credentials Setup
|
|
37
|
+
|
|
38
|
+
The CLI uses standard AWS credential resolution. Choose one method:
|
|
39
|
+
|
|
40
|
+
### Method 1: AWS CLI (easiest)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
aws configure
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Enter your AWS Access Key ID, Secret Access Key, and default region.
|
|
47
|
+
|
|
48
|
+
### Method 2: Environment variables
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
export AWS_ACCESS_KEY_ID="your-access-key"
|
|
52
|
+
export AWS_SECRET_ACCESS_KEY="your-secret-key"
|
|
53
|
+
export AWS_DEFAULT_REGION="us-east-1"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Method 3: Named profile
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# In ~/.aws/credentials:
|
|
60
|
+
[production]
|
|
61
|
+
aws_access_key_id = your-access-key
|
|
62
|
+
aws_secret_access_key = your-secret-key
|
|
63
|
+
|
|
64
|
+
# Use with CLI:
|
|
65
|
+
cloud-cost-cli scan --profile production
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## IAM Permissions
|
|
71
|
+
|
|
72
|
+
Create an IAM user or role with the following policy for read-only access:
|
|
73
|
+
|
|
74
|
+
[**View full IAM policy**](./iam-policy.json)
|
|
75
|
+
|
|
76
|
+
**Summary of required permissions:**
|
|
77
|
+
- EC2: DescribeInstances, DescribeVolumes, DescribeAddresses
|
|
78
|
+
- RDS: DescribeDBInstances
|
|
79
|
+
- S3: ListAllMyBuckets, GetBucketLifecycleConfiguration
|
|
80
|
+
- ELB: DescribeLoadBalancers, DescribeTargetGroups, DescribeTargetHealth
|
|
81
|
+
- CloudWatch: GetMetricStatistics
|
|
82
|
+
- Cost Explorer: GetCostAndUsage
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Usage Examples
|
|
87
|
+
|
|
88
|
+
### Basic scan (default region)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cloud-cost-cli scan
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Scan specific region
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cloud-cost-cli scan --region us-west-2
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Show top 10 opportunities
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cloud-cost-cli scan --top 10
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### JSON output (for scripting)
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cloud-cost-cli scan --output json > report.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Filter by minimum savings
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cloud-cost-cli scan --min-savings 50
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Only show opportunities that save >= $50/month.
|
|
119
|
+
|
|
120
|
+
### Custom analysis period
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
cloud-cost-cli scan --days 60
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Analyze usage over the last 60 days instead of default 30.
|
|
127
|
+
|
|
128
|
+
### Use with specific AWS profile
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
cloud-cost-cli scan --profile production
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Sample Output
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Cloud Cost Optimization Report
|
|
140
|
+
Provider: aws | Region: us-east-1 | Account: 123456789012
|
|
141
|
+
Analyzed: 2026-01-01 to 2026-01-31
|
|
142
|
+
|
|
143
|
+
Top 5 Savings Opportunities (est. $1,245.00/month):
|
|
144
|
+
|
|
145
|
+
┌───┬──────┬─────────────────────────┬──────────────────────────────────────────────────┬─────────────┐
|
|
146
|
+
│ # │ Type │ Resource ID │ Recommendation │ Savings/mo │
|
|
147
|
+
├───┼──────┼─────────────────────────┼──────────────────────────────────────────────────┼─────────────┤
|
|
148
|
+
│ 1 │ S3 │ logs-bucket-2023 │ Enable lifecycle policy (Intelligent-Tiering or… │ $938.00 │
|
|
149
|
+
│ 2 │ RDS │ mydb-production │ Downsize to db.t3.large (avg CPU: 15.0%, avg c… │ $180.00 │
|
|
150
|
+
│ 3 │ EC2 │ i-0abc123def456 │ Stop instance or downsize to t3.small (avg CPU:… │ $65.00 │
|
|
151
|
+
│ 4 │ EBS │ vol-0xyz789abc │ Snapshot and delete, or delete if redundant (ag… │ $40.00 │
|
|
152
|
+
│ 5 │ ELB │ my-old-alb │ Delete unused load balancer (no active targets) │ $22.00 │
|
|
153
|
+
└───┴──────┴─────────────────────────┴──────────────────────────────────────────────────┴─────────────┘
|
|
154
|
+
|
|
155
|
+
Total potential savings: $1,245.00/month ($14,940.00/year)
|
|
156
|
+
|
|
157
|
+
Summary: 42 resources analyzed | 3 idle | 2 oversized | 5 unused
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Troubleshooting
|
|
163
|
+
|
|
164
|
+
### Error: AWS credentials not found
|
|
165
|
+
|
|
166
|
+
**Solution:** Run `aws configure` or set environment variables as shown above.
|
|
167
|
+
|
|
168
|
+
### Error: Access Denied
|
|
169
|
+
|
|
170
|
+
**Solution:** Ensure your IAM user/role has the required read-only permissions. See [iam-policy.json](./iam-policy.json).
|
|
171
|
+
|
|
172
|
+
### Error: Region not enabled
|
|
173
|
+
|
|
174
|
+
**Solution:** The specified region is not enabled in your AWS account. Try a different region or enable it in the AWS Console.
|
|
175
|
+
|
|
176
|
+
### No opportunities found
|
|
177
|
+
|
|
178
|
+
**Possible reasons:**
|
|
179
|
+
- Your account is already well-optimized!
|
|
180
|
+
- Analysis period might be too short (try `--days 60`)
|
|
181
|
+
- Minimum savings filter is too high (remove `--min-savings` or lower the threshold)
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## CI/CD Integration
|
|
186
|
+
|
|
187
|
+
Use the CLI in your CI pipeline to catch cost issues early:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# In GitHub Actions, GitLab CI, etc.
|
|
191
|
+
npx cloud-cost-cli scan --output json --min-savings 100 > cost-report.json
|
|
192
|
+
|
|
193
|
+
# Fail the build if savings exceed threshold
|
|
194
|
+
SAVINGS=$(jq '.totalPotentialSavings' cost-report.json)
|
|
195
|
+
if (( $(echo "$SAVINGS > 500" | bc -l) )); then
|
|
196
|
+
echo "WARNING: Potential savings of \$${SAVINGS}/month detected!"
|
|
197
|
+
exit 1
|
|
198
|
+
fi
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Next Steps
|
|
204
|
+
|
|
205
|
+
- Star the repo: https://github.com/vuhp/cloud-cost-cli
|
|
206
|
+
- Sponsor the project: https://github.com/sponsors/vuhp
|
|
207
|
+
- Report issues: https://github.com/vuhp/cloud-cost-cli/issues
|
|
208
|
+
- Contribute: https://github.com/vuhp/cloud-cost-cli/pulls
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cloud-cost-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Optimize your cloud spend in seconds",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cloud-cost-cli": "dist/bin/cloud-cost-cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "tsx bin/cloud-cost-cli.ts",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"lint": "eslint src/**/*.ts",
|
|
14
|
+
"format": "prettier --write src/**/*.ts"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cloud",
|
|
18
|
+
"aws",
|
|
19
|
+
"cost",
|
|
20
|
+
"optimization",
|
|
21
|
+
"cli",
|
|
22
|
+
"finops",
|
|
23
|
+
"cost-optimization",
|
|
24
|
+
"aws-cli",
|
|
25
|
+
"devops",
|
|
26
|
+
"cloud-cost"
|
|
27
|
+
],
|
|
28
|
+
"author": "Phuong Vu <vuhuuphuong@gmail.com>",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/vuhp/cloud-cost-cli.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/vuhp/cloud-cost-cli/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/vuhp/cloud-cost-cli#readme",
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"docs"
|
|
42
|
+
],
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@aws-sdk/client-cloudwatch": "^3.712.0",
|
|
46
|
+
"@aws-sdk/client-cost-explorer": "^3.712.0",
|
|
47
|
+
"@aws-sdk/client-ec2": "^3.712.0",
|
|
48
|
+
"@aws-sdk/client-elastic-load-balancing-v2": "^3.712.0",
|
|
49
|
+
"@aws-sdk/client-rds": "^3.712.0",
|
|
50
|
+
"@aws-sdk/client-s3": "^3.712.0",
|
|
51
|
+
"@aws-sdk/credential-providers": "^3.712.0",
|
|
52
|
+
"chalk": "^5.3.0",
|
|
53
|
+
"cli-table3": "^0.6.5",
|
|
54
|
+
"commander": "^12.1.0",
|
|
55
|
+
"dayjs": "^1.11.13",
|
|
56
|
+
"ini": "^6.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/ini": "^4.1.1",
|
|
60
|
+
"@types/node": "^22.10.5",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
62
|
+
"@typescript-eslint/parser": "^8.19.1",
|
|
63
|
+
"eslint": "^8.57.1",
|
|
64
|
+
"prettier": "^3.4.2",
|
|
65
|
+
"tsx": "^4.19.2",
|
|
66
|
+
"typescript": "^5.7.3",
|
|
67
|
+
"vitest": "^1.6.0"
|
|
68
|
+
}
|
|
69
|
+
}
|