cdk-cost-analyzer 0.1.12 → 0.1.14
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/.cdk-cost-analyzer-cache/metadata.json +8 -8
- package/README.md +37 -0
- package/dist/releasetag.txt +1 -1
- package/docs/CI_CD.md +514 -76
- package/docs/CONFIGURATION.md +2 -2
- package/docs/DEVELOPMENT.md +3 -3
- package/docs/NAT_GATEWAY_TESTING.md +10 -10
- package/docs/README.md +74 -0
- package/docs/TROUBLESHOOTING.md +3 -3
- package/docs/_config.yml +63 -0
- package/docs/index.md +307 -0
- package/package.json +2 -2
|
@@ -2,35 +2,35 @@
|
|
|
2
2
|
"entries": {
|
|
3
3
|
"AmazonS3:US East (N. Virginia):storageClass:General Purpose|volumeType:Standard": {
|
|
4
4
|
"price": 0.023,
|
|
5
|
-
"timestamp":
|
|
5
|
+
"timestamp": 1769682402214
|
|
6
6
|
},
|
|
7
7
|
"AmazonDynamoDB:US East (N. Virginia):group:DDB-ReadUnits|groupDescription:OnDemand ReadRequestUnits": {
|
|
8
8
|
"price": 0.023,
|
|
9
|
-
"timestamp":
|
|
9
|
+
"timestamp": 1769682402221
|
|
10
10
|
},
|
|
11
11
|
"AmazonDynamoDB:US East (N. Virginia):group:DDB-WriteUnits|groupDescription:OnDemand WriteRequestUnits": {
|
|
12
12
|
"price": 0.023,
|
|
13
|
-
"timestamp":
|
|
13
|
+
"timestamp": 1769682402221
|
|
14
14
|
},
|
|
15
15
|
"AmazonEC2:US East (N. Virginia):capacitystatus:Used|instanceType:t3.micro|operatingSystem:Linux|preInstalledSw:NA|tenancy:Shared": {
|
|
16
16
|
"price": 0.023,
|
|
17
|
-
"timestamp":
|
|
17
|
+
"timestamp": 1769682402229
|
|
18
18
|
},
|
|
19
19
|
"AWSLambda:US East (N. Virginia):group:AWS-Lambda-Requests": {
|
|
20
20
|
"price": 0.023,
|
|
21
|
-
"timestamp":
|
|
21
|
+
"timestamp": 1769682402234
|
|
22
22
|
},
|
|
23
23
|
"AWSLambda:US East (N. Virginia):group:AWS-Lambda-Duration": {
|
|
24
24
|
"price": 0.023,
|
|
25
|
-
"timestamp":
|
|
25
|
+
"timestamp": 1769682402234
|
|
26
26
|
},
|
|
27
27
|
"AmazonS3:EU (Frankfurt):storageClass:General Purpose|volumeType:Standard": {
|
|
28
28
|
"price": 0.023,
|
|
29
|
-
"timestamp":
|
|
29
|
+
"timestamp": 1769682421898
|
|
30
30
|
},
|
|
31
31
|
"AmazonS3:invalid-region-123:storageClass:General Purpose|volumeType:Standard": {
|
|
32
32
|
"price": 0.023,
|
|
33
|
-
"timestamp":
|
|
33
|
+
"timestamp": 1769682421939
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
package/README.md
CHANGED
|
@@ -34,6 +34,43 @@ A TypeScript package that analyzes AWS CDK infrastructure changes and provides c
|
|
|
34
34
|
npm install cdk-cost-analyzer
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
## AWS Credentials
|
|
38
|
+
|
|
39
|
+
CDK Cost Analyzer requires AWS credentials to query the AWS Pricing API for real-time cost data.
|
|
40
|
+
|
|
41
|
+
### Configure Credentials
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Via environment variables
|
|
45
|
+
export AWS_ACCESS_KEY_ID=your_access_key
|
|
46
|
+
export AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
47
|
+
|
|
48
|
+
# Or via AWS CLI configuration
|
|
49
|
+
aws configure
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Required IAM Permissions
|
|
53
|
+
|
|
54
|
+
The AWS credentials must have permission to call the Pricing API:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"Version": "2012-10-17",
|
|
59
|
+
"Statement": [
|
|
60
|
+
{
|
|
61
|
+
"Effect": "Allow",
|
|
62
|
+
"Action": [
|
|
63
|
+
"pricing:GetProducts",
|
|
64
|
+
"pricing:DescribeServices"
|
|
65
|
+
],
|
|
66
|
+
"Resource": "*"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For CI/CD environments, configure credentials as secrets/variables in your pipeline. See the [CI/CD Integration Guide](docs/CI_CD.md) for detailed setup instructions.
|
|
73
|
+
|
|
37
74
|
## Documentation
|
|
38
75
|
|
|
39
76
|
- **[Configuration Guide](docs/CONFIGURATION.md)** - Configure thresholds, usage assumptions, and exclusions
|
package/dist/releasetag.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v0.1.
|
|
1
|
+
v0.1.14
|
package/docs/CI_CD.md
CHANGED
|
@@ -12,164 +12,578 @@ This guide covers integrating CDK Cost Analyzer into your CI/CD pipelines for au
|
|
|
12
12
|
|
|
13
13
|
## GitHub Actions
|
|
14
14
|
|
|
15
|
-
### Basic
|
|
15
|
+
### Basic Cost Analysis Workflow
|
|
16
16
|
|
|
17
|
-
Create `.github/workflows/
|
|
17
|
+
Create `.github/workflows/cost-analysis.yml`:
|
|
18
18
|
|
|
19
19
|
```yaml
|
|
20
|
-
name:
|
|
20
|
+
name: Cost Analysis
|
|
21
21
|
|
|
22
22
|
on:
|
|
23
|
-
push:
|
|
24
|
-
branches: ['**']
|
|
25
23
|
pull_request:
|
|
26
|
-
branches: [
|
|
24
|
+
branches: [main]
|
|
25
|
+
paths:
|
|
26
|
+
- 'infrastructure/**'
|
|
27
|
+
- 'cdk.json'
|
|
28
|
+
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
pull-requests: write
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
analyze-costs:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout code
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0 # Fetch all history for comparison
|
|
41
|
+
|
|
42
|
+
- name: Setup Node.js
|
|
43
|
+
uses: actions/setup-node@v4
|
|
44
|
+
with:
|
|
45
|
+
node-version: '20.x'
|
|
46
|
+
cache: 'npm'
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: npm ci
|
|
50
|
+
|
|
51
|
+
- name: Install CDK Cost Analyzer
|
|
52
|
+
run: npm install -g cdk-cost-analyzer
|
|
53
|
+
|
|
54
|
+
- name: Configure AWS credentials
|
|
55
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
56
|
+
with:
|
|
57
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
58
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
59
|
+
aws-region: us-east-1
|
|
60
|
+
|
|
61
|
+
- name: Synthesize base template
|
|
62
|
+
run: |
|
|
63
|
+
git checkout ${{ github.event.pull_request.base.sha }}
|
|
64
|
+
cd infrastructure
|
|
65
|
+
npx cdk synth --all --output ../cdk.out.base
|
|
66
|
+
|
|
67
|
+
- name: Synthesize target template
|
|
68
|
+
run: |
|
|
69
|
+
git checkout ${{ github.event.pull_request.head.sha }}
|
|
70
|
+
cd infrastructure
|
|
71
|
+
npx cdk synth --all --output ../cdk.out.target
|
|
72
|
+
|
|
73
|
+
- name: Analyze cost changes
|
|
74
|
+
id: cost-analysis
|
|
75
|
+
run: |
|
|
76
|
+
cdk-cost-analyzer compare \
|
|
77
|
+
cdk.out.base/MyStack.template.json \
|
|
78
|
+
cdk.out.target/MyStack.template.json \
|
|
79
|
+
--region us-east-1 \
|
|
80
|
+
--format markdown > cost-report.md
|
|
81
|
+
|
|
82
|
+
- name: Comment PR with cost analysis
|
|
83
|
+
uses: actions/github-script@v7
|
|
84
|
+
with:
|
|
85
|
+
script: |
|
|
86
|
+
const fs = require('fs');
|
|
87
|
+
const report = fs.readFileSync('cost-report.md', 'utf8');
|
|
88
|
+
|
|
89
|
+
github.rest.issues.createComment({
|
|
90
|
+
issue_number: context.issue.number,
|
|
91
|
+
owner: context.repo.owner,
|
|
92
|
+
repo: context.repo.repo,
|
|
93
|
+
body: report
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Using Pipeline Command with Synthesis
|
|
98
|
+
|
|
99
|
+
For automatic CDK synthesis:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
name: Cost Analysis
|
|
103
|
+
|
|
104
|
+
on:
|
|
105
|
+
pull_request:
|
|
106
|
+
branches: [main]
|
|
107
|
+
|
|
108
|
+
permissions:
|
|
109
|
+
contents: read
|
|
110
|
+
pull-requests: write
|
|
27
111
|
|
|
28
112
|
jobs:
|
|
29
|
-
|
|
113
|
+
analyze-costs:
|
|
30
114
|
runs-on: ubuntu-latest
|
|
31
115
|
steps:
|
|
32
116
|
- uses: actions/checkout@v4
|
|
117
|
+
|
|
33
118
|
- uses: actions/setup-node@v4
|
|
34
119
|
with:
|
|
35
|
-
node-version: '
|
|
120
|
+
node-version: '20.x'
|
|
36
121
|
cache: 'npm'
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
122
|
+
|
|
123
|
+
- name: Install dependencies
|
|
124
|
+
run: npm ci
|
|
125
|
+
|
|
126
|
+
- name: Install CDK Cost Analyzer
|
|
127
|
+
run: npm install -g cdk-cost-analyzer
|
|
128
|
+
|
|
129
|
+
- name: Configure AWS credentials
|
|
130
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
131
|
+
with:
|
|
132
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
133
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
134
|
+
aws-region: us-east-1
|
|
135
|
+
|
|
136
|
+
- name: Run cost analysis
|
|
137
|
+
id: cost-analysis
|
|
138
|
+
run: |
|
|
139
|
+
cdk-cost-analyzer pipeline \
|
|
140
|
+
--synth \
|
|
141
|
+
--cdk-app-path ./infrastructure \
|
|
142
|
+
--region us-east-1 \
|
|
143
|
+
--config .cdk-cost-analyzer.yml \
|
|
144
|
+
--format markdown > cost-report.md
|
|
145
|
+
|
|
146
|
+
- name: Comment PR
|
|
147
|
+
uses: actions/github-script@v7
|
|
148
|
+
with:
|
|
149
|
+
script: |
|
|
150
|
+
const fs = require('fs');
|
|
151
|
+
const report = fs.readFileSync('cost-report.md', 'utf8');
|
|
152
|
+
|
|
153
|
+
github.rest.issues.createComment({
|
|
154
|
+
issue_number: context.issue.number,
|
|
155
|
+
owner: context.repo.owner,
|
|
156
|
+
repo: context.repo.repo,
|
|
157
|
+
body: report
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Single Template Analysis
|
|
162
|
+
|
|
163
|
+
Analyze a single template without comparison:
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
name: Cost Estimation
|
|
167
|
+
|
|
168
|
+
on:
|
|
169
|
+
pull_request:
|
|
170
|
+
branches: [main]
|
|
171
|
+
|
|
172
|
+
jobs:
|
|
173
|
+
estimate-costs:
|
|
174
|
+
runs-on: ubuntu-latest
|
|
175
|
+
steps:
|
|
176
|
+
- uses: actions/checkout@v4
|
|
177
|
+
|
|
178
|
+
- uses: actions/setup-node@v4
|
|
179
|
+
with:
|
|
180
|
+
node-version: '20.x'
|
|
181
|
+
|
|
182
|
+
- name: Install CDK Cost Analyzer
|
|
183
|
+
run: npm install -g cdk-cost-analyzer
|
|
184
|
+
|
|
185
|
+
- name: Configure AWS credentials
|
|
186
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
187
|
+
with:
|
|
188
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
189
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
190
|
+
aws-region: us-east-1
|
|
191
|
+
|
|
192
|
+
- name: Analyze template
|
|
193
|
+
run: |
|
|
194
|
+
cdk-cost-analyzer analyze infrastructure/template.json \
|
|
195
|
+
--region us-east-1 \
|
|
196
|
+
--format markdown > cost-estimate.md
|
|
197
|
+
|
|
198
|
+
- name: Comment PR
|
|
199
|
+
uses: actions/github-script@v7
|
|
200
|
+
with:
|
|
201
|
+
script: |
|
|
202
|
+
const fs = require('fs');
|
|
203
|
+
const report = fs.readFileSync('cost-estimate.md', 'utf8');
|
|
204
|
+
|
|
205
|
+
github.rest.issues.createComment({
|
|
206
|
+
issue_number: context.issue.number,
|
|
207
|
+
owner: context.repo.owner,
|
|
208
|
+
repo: context.repo.repo,
|
|
209
|
+
body: report
|
|
210
|
+
});
|
|
42
211
|
```
|
|
43
212
|
|
|
44
213
|
### Configuration Options
|
|
45
214
|
|
|
215
|
+
#### AWS Credentials Setup
|
|
216
|
+
|
|
217
|
+
**Important**: CDK Cost Analyzer requires AWS credentials to query the AWS Pricing API for real-time cost data. Without valid credentials, the tool cannot fetch pricing information.
|
|
218
|
+
|
|
219
|
+
**Required IAM Permissions**:
|
|
220
|
+
|
|
221
|
+
The AWS credentials must have permission to call the Pricing API:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"Version": "2012-10-17",
|
|
226
|
+
"Statement": [
|
|
227
|
+
{
|
|
228
|
+
"Effect": "Allow",
|
|
229
|
+
"Action": [
|
|
230
|
+
"pricing:GetProducts",
|
|
231
|
+
"pricing:DescribeServices"
|
|
232
|
+
],
|
|
233
|
+
"Resource": "*"
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**GitHub Repository Secrets**:
|
|
240
|
+
|
|
241
|
+
Store AWS credentials as GitHub repository secrets:
|
|
242
|
+
|
|
243
|
+
1. Go to **Settings** → **Secrets and variables** → **Actions**
|
|
244
|
+
2. Add secrets:
|
|
245
|
+
- `AWS_ACCESS_KEY_ID` - AWS access key with Pricing API permissions
|
|
246
|
+
- `AWS_SECRET_ACCESS_KEY` - AWS secret access key
|
|
247
|
+
- `AWS_REGION` (optional, can be set in workflow)
|
|
248
|
+
|
|
249
|
+
**Note**: The Pricing API is a global service, but credentials must be configured. The region parameter in the workflow determines which regional pricing data to fetch, not which AWS region to authenticate against.
|
|
250
|
+
|
|
46
251
|
#### Trigger Events
|
|
47
252
|
|
|
48
253
|
```yaml
|
|
49
254
|
# Run on all branches
|
|
50
255
|
on:
|
|
51
|
-
push:
|
|
52
|
-
branches: ['**']
|
|
53
256
|
pull_request:
|
|
54
257
|
branches: ['**']
|
|
55
258
|
|
|
56
259
|
# Run only on specific branches
|
|
57
260
|
on:
|
|
58
|
-
push:
|
|
59
|
-
branches: [main, develop]
|
|
60
261
|
pull_request:
|
|
61
|
-
branches: [main]
|
|
262
|
+
branches: [main, develop]
|
|
62
263
|
|
|
63
264
|
# Run on specific paths
|
|
64
265
|
on:
|
|
65
|
-
|
|
266
|
+
pull_request:
|
|
66
267
|
paths:
|
|
67
|
-
- '
|
|
68
|
-
- '
|
|
69
|
-
- '
|
|
268
|
+
- 'infrastructure/**'
|
|
269
|
+
- 'cdk.json'
|
|
270
|
+
- '.cdk-cost-analyzer.yml'
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### Cost Threshold Enforcement
|
|
274
|
+
|
|
275
|
+
Fail the workflow if costs exceed thresholds:
|
|
276
|
+
|
|
277
|
+
```yaml
|
|
278
|
+
name: Cost Analysis with Thresholds
|
|
279
|
+
|
|
280
|
+
on:
|
|
281
|
+
pull_request:
|
|
282
|
+
branches: [main]
|
|
283
|
+
|
|
284
|
+
jobs:
|
|
285
|
+
analyze-costs:
|
|
286
|
+
runs-on: ubuntu-latest
|
|
287
|
+
steps:
|
|
288
|
+
- uses: actions/checkout@v4
|
|
289
|
+
|
|
290
|
+
- uses: actions/setup-node@v4
|
|
291
|
+
with:
|
|
292
|
+
node-version: '20.x'
|
|
293
|
+
|
|
294
|
+
- name: Install CDK Cost Analyzer
|
|
295
|
+
run: npm install -g cdk-cost-analyzer
|
|
296
|
+
|
|
297
|
+
- name: Configure AWS credentials
|
|
298
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
299
|
+
with:
|
|
300
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
301
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
302
|
+
aws-region: us-east-1
|
|
303
|
+
|
|
304
|
+
- name: Run cost analysis with thresholds
|
|
305
|
+
run: |
|
|
306
|
+
cdk-cost-analyzer pipeline \
|
|
307
|
+
--synth \
|
|
308
|
+
--cdk-app-path ./infrastructure \
|
|
309
|
+
--region us-east-1 \
|
|
310
|
+
--config .cdk-cost-analyzer.yml \
|
|
311
|
+
--environment production \
|
|
312
|
+
--format markdown > cost-report.md
|
|
313
|
+
# Exit code 2 means threshold exceeded
|
|
314
|
+
continue-on-error: true
|
|
315
|
+
id: cost-check
|
|
316
|
+
|
|
317
|
+
- name: Comment PR
|
|
318
|
+
uses: actions/github-script@v7
|
|
319
|
+
with:
|
|
320
|
+
script: |
|
|
321
|
+
const fs = require('fs');
|
|
322
|
+
const report = fs.readFileSync('cost-report.md', 'utf8');
|
|
323
|
+
|
|
324
|
+
github.rest.issues.createComment({
|
|
325
|
+
issue_number: context.issue.number,
|
|
326
|
+
owner: context.repo.owner,
|
|
327
|
+
repo: context.repo.repo,
|
|
328
|
+
body: report
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
- name: Fail if threshold exceeded
|
|
332
|
+
if: steps.cost-check.outcome == 'failure'
|
|
333
|
+
run: |
|
|
334
|
+
echo "Cost threshold exceeded - requires approval"
|
|
335
|
+
exit 1
|
|
70
336
|
```
|
|
71
337
|
|
|
72
|
-
#### Multi-
|
|
338
|
+
#### Multi-Stack Analysis
|
|
339
|
+
|
|
340
|
+
Analyze multiple stacks in a monorepo:
|
|
73
341
|
|
|
74
342
|
```yaml
|
|
343
|
+
name: Multi-Stack Cost Analysis
|
|
344
|
+
|
|
345
|
+
on:
|
|
346
|
+
pull_request:
|
|
347
|
+
branches: [main]
|
|
348
|
+
|
|
75
349
|
jobs:
|
|
76
|
-
|
|
350
|
+
analyze-costs:
|
|
77
351
|
runs-on: ubuntu-latest
|
|
78
352
|
strategy:
|
|
79
353
|
matrix:
|
|
80
|
-
|
|
354
|
+
stack:
|
|
355
|
+
- name: NetworkStack
|
|
356
|
+
path: packages/network
|
|
357
|
+
- name: ComputeStack
|
|
358
|
+
path: packages/compute
|
|
359
|
+
- name: StorageStack
|
|
360
|
+
path: packages/storage
|
|
81
361
|
steps:
|
|
82
362
|
- uses: actions/checkout@v4
|
|
363
|
+
|
|
83
364
|
- uses: actions/setup-node@v4
|
|
84
365
|
with:
|
|
85
|
-
node-version:
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
366
|
+
node-version: '20.x'
|
|
367
|
+
|
|
368
|
+
- name: Install CDK Cost Analyzer
|
|
369
|
+
run: npm install -g cdk-cost-analyzer
|
|
370
|
+
|
|
371
|
+
- name: Configure AWS credentials
|
|
372
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
373
|
+
with:
|
|
374
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
375
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
376
|
+
aws-region: us-east-1
|
|
377
|
+
|
|
378
|
+
- name: Analyze ${{ matrix.stack.name }}
|
|
379
|
+
run: |
|
|
380
|
+
cdk-cost-analyzer pipeline \
|
|
381
|
+
--synth \
|
|
382
|
+
--cdk-app-path ${{ matrix.stack.path }} \
|
|
383
|
+
--region us-east-1 \
|
|
384
|
+
--format markdown > cost-${{ matrix.stack.name }}.md
|
|
385
|
+
|
|
386
|
+
- name: Comment PR with ${{ matrix.stack.name }} costs
|
|
387
|
+
uses: actions/github-script@v7
|
|
388
|
+
with:
|
|
389
|
+
script: |
|
|
390
|
+
const fs = require('fs');
|
|
391
|
+
const report = fs.readFileSync('cost-${{ matrix.stack.name }}.md', 'utf8');
|
|
392
|
+
|
|
393
|
+
github.rest.issues.createComment({
|
|
394
|
+
issue_number: context.issue.number,
|
|
395
|
+
owner: context.repo.owner,
|
|
396
|
+
repo: context.repo.repo,
|
|
397
|
+
body: `## ${{ matrix.stack.name }} Cost Analysis\n\n${report}`
|
|
398
|
+
});
|
|
90
399
|
```
|
|
91
400
|
|
|
92
|
-
####
|
|
401
|
+
#### Caching for Faster Builds
|
|
402
|
+
|
|
403
|
+
Cache pricing data and dependencies:
|
|
93
404
|
|
|
94
405
|
```yaml
|
|
406
|
+
name: Cost Analysis with Caching
|
|
407
|
+
|
|
408
|
+
on:
|
|
409
|
+
pull_request:
|
|
410
|
+
branches: [main]
|
|
411
|
+
|
|
95
412
|
jobs:
|
|
96
|
-
|
|
413
|
+
analyze-costs:
|
|
97
414
|
runs-on: ubuntu-latest
|
|
98
415
|
steps:
|
|
99
416
|
- uses: actions/checkout@v4
|
|
417
|
+
|
|
100
418
|
- uses: actions/setup-node@v4
|
|
101
419
|
with:
|
|
102
|
-
node-version: '
|
|
420
|
+
node-version: '20.x'
|
|
103
421
|
cache: 'npm'
|
|
104
|
-
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
- name: Upload coverage
|
|
108
|
-
uses: codecov/codecov-action@v4
|
|
422
|
+
|
|
423
|
+
- name: Cache pricing data
|
|
424
|
+
uses: actions/cache@v4
|
|
109
425
|
with:
|
|
110
|
-
|
|
111
|
-
|
|
426
|
+
path: .cdk-cost-analyzer-cache
|
|
427
|
+
key: pricing-cache-${{ runner.os }}-${{ hashFiles('.cdk-cost-analyzer.yml') }}
|
|
428
|
+
restore-keys: |
|
|
429
|
+
pricing-cache-${{ runner.os }}-
|
|
430
|
+
|
|
431
|
+
- name: Install dependencies
|
|
432
|
+
run: npm ci
|
|
433
|
+
|
|
434
|
+
- name: Install CDK Cost Analyzer
|
|
435
|
+
run: npm install -g cdk-cost-analyzer
|
|
112
436
|
|
|
437
|
+
- name: Configure AWS credentials
|
|
438
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
439
|
+
with:
|
|
440
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
441
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
442
|
+
aws-region: us-east-1
|
|
443
|
+
|
|
444
|
+
- name: Run cost analysis
|
|
445
|
+
run: |
|
|
446
|
+
cdk-cost-analyzer pipeline \
|
|
447
|
+
--synth \
|
|
448
|
+
--cdk-app-path ./infrastructure \
|
|
449
|
+
--region us-east-1 \
|
|
450
|
+
--format markdown > cost-report.md
|
|
451
|
+
|
|
452
|
+
- name: Comment PR
|
|
453
|
+
uses: actions/github-script@v7
|
|
454
|
+
with:
|
|
455
|
+
script: |
|
|
456
|
+
const fs = require('fs');
|
|
457
|
+
const report = fs.readFileSync('cost-report.md', 'utf8');
|
|
458
|
+
|
|
459
|
+
github.rest.issues.createComment({
|
|
460
|
+
issue_number: context.issue.number,
|
|
461
|
+
owner: context.repo.owner,
|
|
462
|
+
repo: context.repo.repo,
|
|
463
|
+
body: report
|
|
464
|
+
});
|
|
465
|
+
```
|
|
113
466
|
### Status Badge
|
|
114
467
|
|
|
115
|
-
Add to your README:
|
|
468
|
+
Add a status badge to your README:
|
|
116
469
|
|
|
117
470
|
```markdown
|
|
118
|
-
[](https://github.com/USERNAME/REPOSITORY/actions/workflows/cost-analysis.yml)
|
|
119
472
|
```
|
|
120
473
|
|
|
121
474
|
### Complete Example
|
|
122
475
|
|
|
476
|
+
Full workflow with all features:
|
|
477
|
+
|
|
123
478
|
```yaml
|
|
124
|
-
name:
|
|
479
|
+
name: Cost Analysis
|
|
125
480
|
|
|
126
481
|
on:
|
|
127
|
-
push:
|
|
128
|
-
branches: ['**']
|
|
129
|
-
paths:
|
|
130
|
-
- 'src/**'
|
|
131
|
-
- 'test/**'
|
|
132
|
-
- 'package.json'
|
|
133
|
-
- 'package-lock.json'
|
|
134
482
|
pull_request:
|
|
135
|
-
branches: [
|
|
483
|
+
branches: [main]
|
|
484
|
+
paths:
|
|
485
|
+
- 'infrastructure/**'
|
|
486
|
+
- 'cdk.json'
|
|
487
|
+
- '.cdk-cost-analyzer.yml'
|
|
488
|
+
|
|
489
|
+
permissions:
|
|
490
|
+
contents: read
|
|
491
|
+
pull-requests: write
|
|
136
492
|
|
|
137
493
|
concurrency:
|
|
138
|
-
group:
|
|
494
|
+
group: cost-analysis-${{ github.ref }}
|
|
139
495
|
cancel-in-progress: true
|
|
140
496
|
|
|
141
497
|
jobs:
|
|
142
|
-
|
|
498
|
+
analyze-costs:
|
|
143
499
|
runs-on: ubuntu-latest
|
|
144
|
-
strategy:
|
|
145
|
-
fail-fast: true
|
|
146
|
-
matrix:
|
|
147
|
-
node-version: [18.x, 20.x, 22.x]
|
|
148
|
-
|
|
149
500
|
steps:
|
|
150
501
|
- name: Checkout code
|
|
151
502
|
uses: actions/checkout@v4
|
|
152
|
-
|
|
503
|
+
|
|
153
504
|
- name: Setup Node.js
|
|
154
505
|
uses: actions/setup-node@v4
|
|
155
506
|
with:
|
|
156
|
-
node-version:
|
|
507
|
+
node-version: '20.x'
|
|
157
508
|
cache: 'npm'
|
|
158
|
-
|
|
509
|
+
|
|
510
|
+
- name: Cache pricing data
|
|
511
|
+
uses: actions/cache@v4
|
|
512
|
+
with:
|
|
513
|
+
path: .cdk-cost-analyzer-cache
|
|
514
|
+
key: pricing-cache-${{ runner.os }}-${{ hashFiles('.cdk-cost-analyzer.yml') }}
|
|
515
|
+
restore-keys: |
|
|
516
|
+
pricing-cache-${{ runner.os }}-
|
|
517
|
+
|
|
159
518
|
- name: Install dependencies
|
|
160
519
|
run: npm ci
|
|
161
|
-
|
|
162
|
-
- name:
|
|
163
|
-
run: npm
|
|
164
|
-
|
|
165
|
-
- name:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
520
|
+
|
|
521
|
+
- name: Install CDK Cost Analyzer
|
|
522
|
+
run: npm install -g cdk-cost-analyzer
|
|
523
|
+
|
|
524
|
+
- name: Configure AWS credentials
|
|
525
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
526
|
+
with:
|
|
527
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
528
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
529
|
+
aws-region: us-east-1
|
|
530
|
+
|
|
531
|
+
- name: Run cost analysis
|
|
532
|
+
id: cost-analysis
|
|
533
|
+
continue-on-error: true
|
|
534
|
+
run: |
|
|
535
|
+
cdk-cost-analyzer pipeline \
|
|
536
|
+
--synth \
|
|
537
|
+
--cdk-app-path ./infrastructure \
|
|
538
|
+
--region us-east-1 \
|
|
539
|
+
--config .cdk-cost-analyzer.yml \
|
|
540
|
+
--environment production \
|
|
541
|
+
--format markdown > cost-report.md
|
|
542
|
+
|
|
543
|
+
- name: Comment PR with results
|
|
544
|
+
uses: actions/github-script@v7
|
|
545
|
+
with:
|
|
546
|
+
script: |
|
|
547
|
+
const fs = require('fs');
|
|
548
|
+
const report = fs.readFileSync('cost-report.md', 'utf8');
|
|
549
|
+
|
|
550
|
+
// Find existing comment
|
|
551
|
+
const { data: comments } = await github.rest.issues.listComments({
|
|
552
|
+
owner: context.repo.owner,
|
|
553
|
+
repo: context.repo.repo,
|
|
554
|
+
issue_number: context.issue.number,
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
const botComment = comments.find(comment =>
|
|
558
|
+
comment.user.type === 'Bot' &&
|
|
559
|
+
comment.body.includes('Cost Analysis')
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
const commentBody = `## 💰 Cost Analysis\n\n${report}\n\n---\n*Updated: ${new Date().toISOString()}*`;
|
|
563
|
+
|
|
564
|
+
if (botComment) {
|
|
565
|
+
// Update existing comment
|
|
566
|
+
await github.rest.issues.updateComment({
|
|
567
|
+
owner: context.repo.owner,
|
|
568
|
+
repo: context.repo.repo,
|
|
569
|
+
comment_id: botComment.id,
|
|
570
|
+
body: commentBody
|
|
571
|
+
});
|
|
572
|
+
} else {
|
|
573
|
+
// Create new comment
|
|
574
|
+
await github.rest.issues.createComment({
|
|
575
|
+
owner: context.repo.owner,
|
|
576
|
+
repo: context.repo.repo,
|
|
577
|
+
issue_number: context.issue.number,
|
|
578
|
+
body: commentBody
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
- name: Check threshold status
|
|
583
|
+
if: steps.cost-analysis.outcome == 'failure'
|
|
584
|
+
run: |
|
|
585
|
+
echo "::error::Cost threshold exceeded - requires approval"
|
|
586
|
+
exit 1
|
|
173
587
|
```
|
|
174
588
|
|
|
175
589
|
---
|
|
@@ -225,10 +639,34 @@ cost-analysis:
|
|
|
225
639
|
|
|
226
640
|
### AWS Credentials
|
|
227
641
|
|
|
642
|
+
**Important**: CDK Cost Analyzer requires AWS credentials to query the AWS Pricing API for real-time cost data.
|
|
643
|
+
|
|
644
|
+
**Required IAM Permissions**:
|
|
645
|
+
|
|
646
|
+
```json
|
|
647
|
+
{
|
|
648
|
+
"Version": "2012-10-17",
|
|
649
|
+
"Statement": [
|
|
650
|
+
{
|
|
651
|
+
"Effect": "Allow",
|
|
652
|
+
"Action": [
|
|
653
|
+
"pricing:GetProducts",
|
|
654
|
+
"pricing:DescribeServices"
|
|
655
|
+
],
|
|
656
|
+
"Resource": "*"
|
|
657
|
+
}
|
|
658
|
+
]
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**GitLab CI/CD Variables**:
|
|
663
|
+
|
|
228
664
|
Configure in **Settings > CI/CD > Variables**:
|
|
229
|
-
- `AWS_ACCESS_KEY_ID` (masked)
|
|
230
|
-
- `AWS_SECRET_ACCESS_KEY` (masked)
|
|
231
|
-
- `AWS_REGION`
|
|
665
|
+
- `AWS_ACCESS_KEY_ID` (masked) - AWS access key with Pricing API permissions
|
|
666
|
+
- `AWS_SECRET_ACCESS_KEY` (masked) - AWS secret access key
|
|
667
|
+
- `AWS_REGION` - Target region for pricing data (e.g., us-east-1, eu-central-1)
|
|
668
|
+
|
|
669
|
+
**Note**: The Pricing API is a global service. The region variable determines which regional pricing data to fetch, not authentication region.
|
|
232
670
|
|
|
233
671
|
### Cost Analysis Options
|
|
234
672
|
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -195,8 +195,8 @@ synthesis:
|
|
|
195
195
|
```
|
|
196
196
|
|
|
197
197
|
**Timeout Behavior:**
|
|
198
|
-
- CDK synthesis has a built-in
|
|
199
|
-
- Process receives SIGTERM for graceful termination, followed by SIGKILL after
|
|
198
|
+
- CDK synthesis has a built-in 15-second timeout to prevent hanging processes
|
|
199
|
+
- Process receives SIGTERM for graceful termination, followed by SIGKILL after 1 second
|
|
200
200
|
- If synthesis requires more time, use a custom command with extended timeout:
|
|
201
201
|
```yaml
|
|
202
202
|
synthesis:
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -202,7 +202,7 @@ npm run test:silent
|
|
|
202
202
|
npm run test:watch
|
|
203
203
|
|
|
204
204
|
# Run specific test file
|
|
205
|
-
npx
|
|
205
|
+
npx jest test/parser/TemplateParser.test.ts
|
|
206
206
|
```
|
|
207
207
|
|
|
208
208
|
### Test Structure
|
|
@@ -326,7 +326,7 @@ export class DynamoDBCalculator implements ResourceCostCalculator {
|
|
|
326
326
|
|
|
327
327
|
### Build Errors
|
|
328
328
|
|
|
329
|
-
Check Node.js version (>=
|
|
329
|
+
Check Node.js version (>= 20.0.0):
|
|
330
330
|
```bash
|
|
331
331
|
node --version
|
|
332
332
|
```
|
|
@@ -375,7 +375,7 @@ aws sts get-caller-identity --no-cli-pager
|
|
|
375
375
|
|
|
376
376
|
### Development
|
|
377
377
|
- `typescript`: TypeScript compiler
|
|
378
|
-
- `
|
|
378
|
+
- `jest`: Testing framework
|
|
379
379
|
- `fast-check`: Property-based testing
|
|
380
380
|
- `@types/*`: Type definitions
|
|
381
381
|
|
|
@@ -7,14 +7,14 @@ This guide provides information on testing and debugging the NAT Gateway pricing
|
|
|
7
7
|
The NAT Gateway calculator had an issue with region prefix formatting that prevented it from fetching correct pricing data from the AWS Pricing API.
|
|
8
8
|
|
|
9
9
|
### Problem
|
|
10
|
-
- **Before**: UsageType format was `EUC1NatGateway-Hours` (missing hyphen)
|
|
11
|
-
- **After**: UsageType format is `EUC1-
|
|
10
|
+
- **Before**: UsageType format was `EUC1NatGateway-Hours` (missing hyphen and "Regional")
|
|
11
|
+
- **After**: UsageType format is `EUC1-RegionalNatGateway-Hours` (correct format)
|
|
12
12
|
|
|
13
13
|
### Changes Made
|
|
14
14
|
|
|
15
15
|
1. **Fixed UsageType Format** (NatGatewayCalculator.ts)
|
|
16
|
-
- Changed from `${regionPrefix}NatGateway-Hours` to `${regionPrefix}-
|
|
17
|
-
- Changed from `${regionPrefix}NatGateway-Bytes` to `${regionPrefix}-
|
|
16
|
+
- Changed from `${regionPrefix}NatGateway-Hours` to `${regionPrefix}-RegionalNatGateway-Hours`
|
|
17
|
+
- Changed from `${regionPrefix}NatGateway-Bytes` to `${regionPrefix}-RegionalNatGateway-Bytes`
|
|
18
18
|
|
|
19
19
|
2. **Expanded Region Coverage**
|
|
20
20
|
- Added comprehensive region prefix mappings for all AWS commercial and government regions
|
|
@@ -116,7 +116,7 @@ npx ts-node tools/discover-nat-gateway-pricing.ts
|
|
|
116
116
|
|
|
117
117
|
1. **Tests Multiple Format Combinations**:
|
|
118
118
|
- Different region prefix formats (EUC1, EUC1-, EU-Central-1, etc.)
|
|
119
|
-
- Different usage type formats (NatGateway-Hours, NGW-Hours, etc.)
|
|
119
|
+
- Different usage type formats (RegionalNatGateway-Hours, NatGateway-Hours, NGW-Hours, etc.)
|
|
120
120
|
|
|
121
121
|
2. **Lists All NAT Gateway Products**: Shows all available NAT Gateway products without filters
|
|
122
122
|
|
|
@@ -136,10 +136,10 @@ npx ts-node tools/discover-nat-gateway-pricing.ts
|
|
|
136
136
|
|
|
137
137
|
Testing different filter combinations...
|
|
138
138
|
|
|
139
|
-
Trying prefix "EUC1" with usageType: EUC1-
|
|
139
|
+
Trying prefix "EUC1" with usageType: EUC1-RegionalNatGateway-Hours
|
|
140
140
|
✅ SUCCESS! Found pricing data
|
|
141
141
|
Region: EU (Frankfurt)
|
|
142
|
-
UsageType: EUC1-
|
|
142
|
+
UsageType: EUC1-RegionalNatGateway-Hours
|
|
143
143
|
Operation: NatGateway
|
|
144
144
|
Description: $0.045 per NAT Gateway Hour
|
|
145
145
|
Price: $0.045/Hrs
|
|
@@ -148,9 +148,9 @@ Trying prefix "EUC1" with usageType: EUC1-NatGateway-Hours
|
|
|
148
148
|
Found 200+ NAT Gateway products
|
|
149
149
|
|
|
150
150
|
📍 Found NAT Gateway products for EU (Frankfurt):
|
|
151
|
-
- UsageType: EUC1-
|
|
151
|
+
- UsageType: EUC1-RegionalNatGateway-Hours
|
|
152
152
|
Description: $0.045 per NAT Gateway Hour
|
|
153
|
-
- UsageType: EUC1-
|
|
153
|
+
- UsageType: EUC1-RegionalNatGateway-Bytes
|
|
154
154
|
Description: $0.045 per GB - data processed by NAT Gateways
|
|
155
155
|
```
|
|
156
156
|
|
|
@@ -201,7 +201,7 @@ When debug logging is enabled, you'll see:
|
|
|
201
201
|
[DEBUG 2025-01-09T10:30:02.000Z] NAT Gateway hourly rate retrieved
|
|
202
202
|
{
|
|
203
203
|
"hourlyRate": 0.045,
|
|
204
|
-
"usageType": "EUC1-
|
|
204
|
+
"usageType": "EUC1-RegionalNatGateway-Hours"
|
|
205
205
|
}
|
|
206
206
|
```
|
|
207
207
|
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# CDK Cost Analyzer Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains the documentation for CDK Cost Analyzer, published to GitHub Pages.
|
|
4
|
+
|
|
5
|
+
## Documentation Structure
|
|
6
|
+
|
|
7
|
+
- **index.md** - Homepage with overview and quick start
|
|
8
|
+
- **CONFIGURATION.md** - Configuration guide for thresholds, usage assumptions, and exclusions
|
|
9
|
+
- **CI_CD.md** - CI/CD integration guide for GitHub Actions and GitLab CI
|
|
10
|
+
- **CALCULATORS.md** - Resource calculator reference with cost calculation methods
|
|
11
|
+
- **TROUBLESHOOTING.md** - Common issues and solutions
|
|
12
|
+
- **DEVELOPMENT.md** - Local development, testing, and architecture
|
|
13
|
+
- **RELEASE.md** - Release process documentation
|
|
14
|
+
- **SINGLE-TEMPLATE-ANALYSIS.md** - Single template analysis guide
|
|
15
|
+
- **NAT_GATEWAY_TESTING.md** - NAT Gateway testing and debugging guide
|
|
16
|
+
|
|
17
|
+
## GitHub Pages Setup
|
|
18
|
+
|
|
19
|
+
The documentation is automatically published to GitHub Pages when changes are pushed to the `main` branch.
|
|
20
|
+
|
|
21
|
+
### Configuration Files
|
|
22
|
+
|
|
23
|
+
- **_config.yml** - Jekyll configuration for GitHub Pages
|
|
24
|
+
- **.github/workflows/pages.yml** - GitHub Actions workflow for deployment
|
|
25
|
+
|
|
26
|
+
### Viewing the Documentation
|
|
27
|
+
|
|
28
|
+
The documentation is available at: https://buildinginthecloud.github.io/cdk-cost-analyzer/
|
|
29
|
+
|
|
30
|
+
### Local Preview
|
|
31
|
+
|
|
32
|
+
To preview the documentation locally:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Install Jekyll (requires Ruby)
|
|
36
|
+
gem install bundler jekyll
|
|
37
|
+
|
|
38
|
+
# Navigate to docs directory
|
|
39
|
+
cd docs
|
|
40
|
+
|
|
41
|
+
# Serve the site locally
|
|
42
|
+
jekyll serve
|
|
43
|
+
|
|
44
|
+
# Open http://localhost:4000 in your browser
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Theme
|
|
48
|
+
|
|
49
|
+
The documentation uses the Cayman theme, which provides:
|
|
50
|
+
- Clean, professional appearance
|
|
51
|
+
- Responsive design for mobile devices
|
|
52
|
+
- Syntax highlighting for code blocks
|
|
53
|
+
- GitHub integration
|
|
54
|
+
|
|
55
|
+
## Updating Documentation
|
|
56
|
+
|
|
57
|
+
1. Edit the relevant Markdown files in the `docs/` directory
|
|
58
|
+
2. Commit and push changes to the `main` branch
|
|
59
|
+
3. GitHub Actions automatically rebuilds and deploys the site
|
|
60
|
+
4. Changes are live within a few minutes
|
|
61
|
+
|
|
62
|
+
## Documentation Standards
|
|
63
|
+
|
|
64
|
+
All documentation follows these standards:
|
|
65
|
+
|
|
66
|
+
- Professional, technical tone similar to AWS documentation
|
|
67
|
+
- Active voice and imperative mood for instructions
|
|
68
|
+
- US English spelling
|
|
69
|
+
- Code blocks with language specification
|
|
70
|
+
- No emojis or casual language
|
|
71
|
+
- Complete, working examples
|
|
72
|
+
- Proper AWS service name capitalization
|
|
73
|
+
|
|
74
|
+
See `.kiro/steering/documentation-style.md` for complete style guidelines.
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -14,11 +14,11 @@ This guide covers common issues and solutions when using CDK Cost Analyzer.
|
|
|
14
14
|
|
|
15
15
|
## CDK Synthesis Errors
|
|
16
16
|
|
|
17
|
-
### Error: CDK synthesis timed out after
|
|
17
|
+
### Error: CDK synthesis timed out after 15 seconds
|
|
18
18
|
|
|
19
19
|
**Symptoms:**
|
|
20
20
|
```
|
|
21
|
-
Error: CDK synthesis timed out after
|
|
21
|
+
Error: CDK synthesis timed out after 15 seconds
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
**Causes:**
|
|
@@ -64,7 +64,7 @@ cd infrastructure
|
|
|
64
64
|
time npx cdk synth --all # Measure synthesis time
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
**Note:** The
|
|
67
|
+
**Note:** The 15-second timeout is designed to prevent hanging processes in CI/CD environments while providing faster feedback. The timeout includes improved process cleanup with graceful termination (SIGTERM) followed by force termination (SIGKILL) after 1 second if needed. If your CDK application legitimately requires more time, consider optimizing the synthesis process or using a custom command with extended timeout.
|
|
68
68
|
|
|
69
69
|
### Error: CDK synthesis failed with exit code 1
|
|
70
70
|
|
package/docs/_config.yml
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
title: CDK Cost Analyzer
|
|
2
|
+
description: Analyze AWS CDK infrastructure changes and provide cost impact summaries
|
|
3
|
+
theme: jekyll-theme-cayman
|
|
4
|
+
show_downloads: true
|
|
5
|
+
|
|
6
|
+
# GitHub repository
|
|
7
|
+
repository: buildinginthecloud/cdk-cost-analyzer
|
|
8
|
+
|
|
9
|
+
# Navigation
|
|
10
|
+
navigation:
|
|
11
|
+
- title: Home
|
|
12
|
+
url: /
|
|
13
|
+
- title: Configuration
|
|
14
|
+
url: /CONFIGURATION
|
|
15
|
+
- title: CI/CD Integration
|
|
16
|
+
url: /CI_CD
|
|
17
|
+
- title: Calculators
|
|
18
|
+
url: /CALCULATORS
|
|
19
|
+
- title: Troubleshooting
|
|
20
|
+
url: /TROUBLESHOOTING
|
|
21
|
+
- title: Development
|
|
22
|
+
url: /DEVELOPMENT
|
|
23
|
+
- title: Release Process
|
|
24
|
+
url: /RELEASE
|
|
25
|
+
|
|
26
|
+
# Plugins
|
|
27
|
+
plugins:
|
|
28
|
+
- jekyll-relative-links
|
|
29
|
+
- jekyll-optional-front-matter
|
|
30
|
+
- jekyll-readme-index
|
|
31
|
+
- jekyll-titles-from-headings
|
|
32
|
+
- jekyll-github-metadata
|
|
33
|
+
|
|
34
|
+
# Relative links configuration
|
|
35
|
+
relative_links:
|
|
36
|
+
enabled: true
|
|
37
|
+
collections: true
|
|
38
|
+
|
|
39
|
+
# Optional front matter
|
|
40
|
+
optional_front_matter:
|
|
41
|
+
remove_originals: true
|
|
42
|
+
|
|
43
|
+
# Titles from headings
|
|
44
|
+
titles_from_headings:
|
|
45
|
+
enabled: true
|
|
46
|
+
strip_title: true
|
|
47
|
+
collections: true
|
|
48
|
+
|
|
49
|
+
# Markdown settings
|
|
50
|
+
markdown: kramdown
|
|
51
|
+
kramdown:
|
|
52
|
+
input: GFM
|
|
53
|
+
hard_wrap: false
|
|
54
|
+
syntax_highlighter: rouge
|
|
55
|
+
|
|
56
|
+
# Exclude from processing
|
|
57
|
+
exclude:
|
|
58
|
+
- node_modules
|
|
59
|
+
- vendor
|
|
60
|
+
- .git
|
|
61
|
+
- .github
|
|
62
|
+
- .gitignore
|
|
63
|
+
- README.md
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Home
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CDK Cost Analyzer
|
|
7
|
+
|
|
8
|
+
[](https://github.com/buildinginthecloud/cdk-cost-analyzer/actions/workflows/test.yml)
|
|
9
|
+
[](https://github.com/buildinginthecloud/cdk-cost-analyzer/actions/workflows/build.yml)
|
|
10
|
+
[](https://github.com/buildinginthecloud/cdk-cost-analyzer/actions/workflows/release.yml)
|
|
11
|
+
[](https://www.npmjs.com/package/cdk-cost-analyzer)
|
|
12
|
+
|
|
13
|
+
A TypeScript package that analyzes AWS CDK infrastructure changes and provides cost impact summaries. Compare CloudFormation templates to understand the financial implications of your infrastructure changes before deployment.
|
|
14
|
+
|
|
15
|
+
## Key Features
|
|
16
|
+
|
|
17
|
+
- **Single Template Analysis** - Analyze individual CloudFormation templates for estimated monthly costs without comparison
|
|
18
|
+
- **Template Comparison** - Parse and diff CloudFormation templates (JSON/YAML) to identify added, removed, and modified resources
|
|
19
|
+
- **Cost Estimation** - Calculate monthly costs for AWS resources using real-time AWS Pricing API data
|
|
20
|
+
- **Automatic CDK Synthesis** - Optionally synthesize CDK applications in CI/CD pipelines
|
|
21
|
+
- **Cost Threshold Enforcement** - Fail pipelines when cost increases exceed configured thresholds
|
|
22
|
+
- **Configuration Management** - Project-specific configuration for thresholds, usage assumptions, and exclusions
|
|
23
|
+
- **Dual Interface** - Use as a CLI tool for quick analysis or import as a library for programmatic integration
|
|
24
|
+
- **Clear Reporting** - Generate formatted cost reports in text, JSON, or Markdown formats
|
|
25
|
+
- **GitLab Integration** - Post cost analysis reports as comments on GitLab merge requests
|
|
26
|
+
- **FinOps Awareness** - Help developers understand cost implications during the development cycle
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install cdk-cost-analyzer
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### AWS Credentials
|
|
37
|
+
|
|
38
|
+
CDK Cost Analyzer requires AWS credentials to query the AWS Pricing API for real-time cost data.
|
|
39
|
+
|
|
40
|
+
**Configure credentials**:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Option 1: Environment variables
|
|
44
|
+
export AWS_ACCESS_KEY_ID=your_access_key
|
|
45
|
+
export AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
46
|
+
|
|
47
|
+
# Option 2: AWS CLI configuration
|
|
48
|
+
aws configure
|
|
49
|
+
|
|
50
|
+
# Option 3: IAM role (when running in AWS)
|
|
51
|
+
# Credentials are automatically available
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Required IAM permissions**:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"Version": "2012-10-17",
|
|
59
|
+
"Statement": [
|
|
60
|
+
{
|
|
61
|
+
"Effect": "Allow",
|
|
62
|
+
"Action": [
|
|
63
|
+
"pricing:GetProducts",
|
|
64
|
+
"pricing:DescribeServices"
|
|
65
|
+
],
|
|
66
|
+
"Resource": "*"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### CLI Usage
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Analyze a single CloudFormation template
|
|
76
|
+
cdk-cost-analyzer analyze template.json --region us-east-1
|
|
77
|
+
|
|
78
|
+
# Compare two CloudFormation templates
|
|
79
|
+
cdk-cost-analyzer compare base.json target.json --region eu-central-1
|
|
80
|
+
|
|
81
|
+
# Use pipeline command with automatic synthesis
|
|
82
|
+
cdk-cost-analyzer pipeline \
|
|
83
|
+
--synth \
|
|
84
|
+
--cdk-app-path ./infrastructure \
|
|
85
|
+
--region eu-central-1 \
|
|
86
|
+
--config .cdk-cost-analyzer.yml
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Programmatic Usage
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { analyzeSingleTemplate } from 'cdk-cost-analyzer';
|
|
93
|
+
|
|
94
|
+
const result = await analyzeSingleTemplate({
|
|
95
|
+
template: templateContent,
|
|
96
|
+
region: 'us-east-1',
|
|
97
|
+
format: 'text'
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log(`Total monthly cost: ${result.totalMonthlyCost} ${result.currency}`);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Documentation
|
|
104
|
+
|
|
105
|
+
### Getting Started
|
|
106
|
+
|
|
107
|
+
- [Installation & Quick Start](#quick-start)
|
|
108
|
+
- [Configuration Guide](CONFIGURATION.md) - Configure thresholds, usage assumptions, and exclusions
|
|
109
|
+
- [CI/CD Integration](CI_CD.md) - GitHub Actions and GitLab CI/CD setup guides
|
|
110
|
+
|
|
111
|
+
### Reference
|
|
112
|
+
|
|
113
|
+
- [Resource Calculator Reference](CALCULATORS.md) - Detailed cost calculation methods and assumptions
|
|
114
|
+
- [Single Template Analysis](SINGLE-TEMPLATE-ANALYSIS.md) - Analyze individual templates without comparison
|
|
115
|
+
- [NAT Gateway Testing](NAT_GATEWAY_TESTING.md) - Testing and debugging NAT Gateway pricing
|
|
116
|
+
|
|
117
|
+
### Operations
|
|
118
|
+
|
|
119
|
+
- [Troubleshooting Guide](TROUBLESHOOTING.md) - Common issues and solutions
|
|
120
|
+
- [Development Guide](DEVELOPMENT.md) - Local development, testing, and architecture
|
|
121
|
+
- [Release Process](RELEASE.md) - How to release new versions
|
|
122
|
+
|
|
123
|
+
## Supported Resource Types
|
|
124
|
+
|
|
125
|
+
### Compute & Storage
|
|
126
|
+
- AWS::EC2::Instance
|
|
127
|
+
- AWS::S3::Bucket
|
|
128
|
+
- AWS::Lambda::Function
|
|
129
|
+
- AWS::RDS::DBInstance
|
|
130
|
+
- AWS::DynamoDB::Table
|
|
131
|
+
- AWS::ECS::Service
|
|
132
|
+
|
|
133
|
+
### Networking
|
|
134
|
+
- AWS::EC2::NatGateway
|
|
135
|
+
- AWS::ElasticLoadBalancingV2::LoadBalancer (ALB & NLB)
|
|
136
|
+
- AWS::EC2::VPCEndpoint
|
|
137
|
+
|
|
138
|
+
### API & Content Delivery
|
|
139
|
+
- AWS::ApiGateway::RestApi
|
|
140
|
+
- AWS::ApiGatewayV2::Api (HTTP & WebSocket)
|
|
141
|
+
- AWS::CloudFront::Distribution
|
|
142
|
+
|
|
143
|
+
### Caching
|
|
144
|
+
- AWS::ElastiCache::CacheCluster
|
|
145
|
+
|
|
146
|
+
See the [Calculator Reference](CALCULATORS.md) for complete details on cost calculation methods and assumptions.
|
|
147
|
+
|
|
148
|
+
## Configuration Example
|
|
149
|
+
|
|
150
|
+
Create `.cdk-cost-analyzer.yml` in your project:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
# Cost thresholds
|
|
154
|
+
thresholds:
|
|
155
|
+
default:
|
|
156
|
+
warning: 50
|
|
157
|
+
error: 200
|
|
158
|
+
environments:
|
|
159
|
+
production:
|
|
160
|
+
warning: 25
|
|
161
|
+
error: 100
|
|
162
|
+
|
|
163
|
+
# Custom usage assumptions
|
|
164
|
+
usageAssumptions:
|
|
165
|
+
s3:
|
|
166
|
+
storageGB: 500
|
|
167
|
+
lambda:
|
|
168
|
+
invocationsPerMonth: 5000000
|
|
169
|
+
natGateway:
|
|
170
|
+
dataProcessedGB: 500
|
|
171
|
+
|
|
172
|
+
# Resource exclusions
|
|
173
|
+
exclusions:
|
|
174
|
+
resourceTypes:
|
|
175
|
+
- AWS::IAM::Role
|
|
176
|
+
- AWS::Logs::LogGroup
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
See the [Configuration Guide](CONFIGURATION.md) for complete documentation.
|
|
180
|
+
|
|
181
|
+
## CI/CD Integration
|
|
182
|
+
|
|
183
|
+
### GitLab CI
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
cost-analysis:
|
|
187
|
+
stage: cost-analysis
|
|
188
|
+
image: node:20
|
|
189
|
+
before_script:
|
|
190
|
+
- npm install -g cdk-cost-analyzer
|
|
191
|
+
script:
|
|
192
|
+
- |
|
|
193
|
+
cdk-cost-analyzer pipeline \
|
|
194
|
+
--synth \
|
|
195
|
+
--cdk-app-path ./infrastructure \
|
|
196
|
+
--region $AWS_REGION \
|
|
197
|
+
--format markdown \
|
|
198
|
+
--post-to-gitlab
|
|
199
|
+
only:
|
|
200
|
+
- merge_requests
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### GitHub Actions
|
|
204
|
+
|
|
205
|
+
```yaml
|
|
206
|
+
name: CI
|
|
207
|
+
on:
|
|
208
|
+
push:
|
|
209
|
+
branches: ['**']
|
|
210
|
+
pull_request:
|
|
211
|
+
branches: ['**']
|
|
212
|
+
|
|
213
|
+
jobs:
|
|
214
|
+
test:
|
|
215
|
+
runs-on: ubuntu-latest
|
|
216
|
+
steps:
|
|
217
|
+
- uses: actions/checkout@v4
|
|
218
|
+
- uses: actions/setup-node@v4
|
|
219
|
+
with:
|
|
220
|
+
node-version: '20.x'
|
|
221
|
+
cache: 'npm'
|
|
222
|
+
- run: npm ci
|
|
223
|
+
- run: npm run build
|
|
224
|
+
- run: npm run test:silent
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
See the [CI/CD Integration Guide](CI_CD.md) for complete documentation.
|
|
228
|
+
|
|
229
|
+
## Report Formats
|
|
230
|
+
|
|
231
|
+
### Text Format (Default)
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
============================================================
|
|
235
|
+
CDK Cost Analysis Report
|
|
236
|
+
============================================================
|
|
237
|
+
|
|
238
|
+
Total Cost Delta: +$245.60
|
|
239
|
+
|
|
240
|
+
ADDED RESOURCES:
|
|
241
|
+
------------------------------------------------------------
|
|
242
|
+
• MyEC2Instance (AWS::EC2::Instance): $30.40 [high]
|
|
243
|
+
• MyRDSInstance (AWS::RDS::DBInstance): $215.20 [high]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Markdown Format
|
|
247
|
+
|
|
248
|
+
Perfect for GitLab merge request comments:
|
|
249
|
+
|
|
250
|
+
```markdown
|
|
251
|
+
# CDK Cost Analysis Report
|
|
252
|
+
|
|
253
|
+
**Total Cost Delta:** +$245.60
|
|
254
|
+
|
|
255
|
+
## Added Resources
|
|
256
|
+
|
|
257
|
+
| Logical ID | Type | Monthly Cost |
|
|
258
|
+
|------------|------|--------------|
|
|
259
|
+
| MyEC2Instance | AWS::EC2::Instance | $30.40 |
|
|
260
|
+
| MyRDSInstance | AWS::RDS::DBInstance | $215.20 |
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### JSON Format
|
|
264
|
+
|
|
265
|
+
For programmatic processing:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"totalDelta": 245.60,
|
|
270
|
+
"currency": "USD",
|
|
271
|
+
"addedCosts": [...],
|
|
272
|
+
"removedCosts": [...],
|
|
273
|
+
"modifiedCosts": [...]
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Contributing
|
|
278
|
+
|
|
279
|
+
Contributions are welcome! This project uses [Projen](https://projen.io/) for project management.
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Clone the repository
|
|
283
|
+
git clone https://github.com/buildinginthecloud/cdk-cost-analyzer.git
|
|
284
|
+
cd cdk-cost-analyzer
|
|
285
|
+
|
|
286
|
+
# Install dependencies
|
|
287
|
+
npm install
|
|
288
|
+
|
|
289
|
+
# Build the project
|
|
290
|
+
npm run build
|
|
291
|
+
|
|
292
|
+
# Run tests
|
|
293
|
+
npm run test
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
See the [Development Guide](DEVELOPMENT.md) for detailed development instructions.
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
MIT
|
|
301
|
+
|
|
302
|
+
## Links
|
|
303
|
+
|
|
304
|
+
- [GitHub Repository](https://github.com/buildinginthecloud/cdk-cost-analyzer)
|
|
305
|
+
- [NPM Package](https://www.npmjs.com/package/cdk-cost-analyzer)
|
|
306
|
+
- [Issue Tracker](https://github.com/buildinginthecloud/cdk-cost-analyzer/issues)
|
|
307
|
+
- [Releases](https://github.com/buildinginthecloud/cdk-cost-analyzer/releases)
|
package/package.json
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"jest": "^30.2.0",
|
|
57
57
|
"jest-junit": "^16",
|
|
58
58
|
"lint-staged": "^15.0.0",
|
|
59
|
-
"projen": "^0.99.
|
|
59
|
+
"projen": "^0.99.8",
|
|
60
60
|
"ts-jest": "^29.4.6",
|
|
61
61
|
"ts-node": "^10.9.2",
|
|
62
62
|
"typescript": "^5.9.3"
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"publishConfig": {
|
|
83
83
|
"access": "public"
|
|
84
84
|
},
|
|
85
|
-
"version": "0.1.
|
|
85
|
+
"version": "0.1.14",
|
|
86
86
|
"bugs": {
|
|
87
87
|
"url": "https://github.com/buildinginthecloud/cdk-cost-analyzer/issues"
|
|
88
88
|
},
|