cdk-cost-analyzer 0.1.1
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 +12 -0
- package/.gitlab-ci.yml +214 -0
- package/.husky/pre-commit +12 -0
- package/.kiro/hooks/accessibility-audit.kiro.hook +18 -0
- package/.kiro/hooks/api-schema-validation.kiro.hook +21 -0
- package/.kiro/hooks/auto-test-on-save.kiro.hook +19 -0
- package/.kiro/hooks/cdk-synth-on-change.kiro.hook +20 -0
- package/.kiro/hooks/code-coverage-check.kiro.hook +14 -0
- package/.kiro/hooks/commit-message-helper.kiro.hook +14 -0
- package/.kiro/hooks/dependency-update-check.kiro.hook +14 -0
- package/.kiro/hooks/env-file-validation.kiro.hook +18 -0
- package/.kiro/hooks/lint-and-format-on-save.kiro.hook +21 -0
- package/.kiro/hooks/mcp-config-validation.kiro.hook +17 -0
- package/.kiro/hooks/mcp-server-test.kiro.hook +14 -0
- package/.kiro/hooks/performance-analysis.kiro.hook +14 -0
- package/.kiro/hooks/readme-spell-check.kiro.hook +14 -0
- package/.kiro/hooks/security-scan-on-dependency-change.kiro.hook +21 -0
- package/.kiro/hooks/translation-update.kiro.hook +18 -0
- package/.kiro/hooks/update-documentation.kiro.hook +18 -0
- package/.kiro/settings/mcp.json +20 -0
- package/.kiro/specs/cdk-cost-analyzer/design.md +620 -0
- package/.kiro/specs/cdk-cost-analyzer/requirements.md +183 -0
- package/.kiro/specs/cdk-cost-analyzer/tasks.md +357 -0
- package/.kiro/specs/github-actions-ci/design.md +281 -0
- package/.kiro/specs/github-actions-ci/requirements.md +86 -0
- package/.kiro/specs/github-actions-ci/tasks.md +115 -0
- package/.kiro/specs/nlb-calculator-test-coverage/design.md +190 -0
- package/.kiro/specs/nlb-calculator-test-coverage/requirements.md +84 -0
- package/.kiro/specs/nlb-calculator-test-coverage/tasks.md +150 -0
- package/.kiro/specs/production-readiness/design.md +1213 -0
- package/.kiro/specs/production-readiness/requirements.md +312 -0
- package/.kiro/specs/production-readiness/tasks.md +269 -0
- package/.kiro/specs/repository-cleanup/design.md +283 -0
- package/.kiro/specs/repository-cleanup/requirements.md +74 -0
- package/.kiro/specs/repository-cleanup/tasks.md +64 -0
- package/.kiro/steering/aws-cli-best-practices.md +41 -0
- package/.kiro/steering/cdk-best-practices.md +49 -0
- package/.kiro/steering/development-standards.md +54 -0
- package/.kiro/steering/docker-best-practices.md +34 -0
- package/.kiro/steering/documentation-style.md +151 -0
- package/.kiro/steering/git-best-practices.md +37 -0
- package/.kiro/steering/mcp-best-practices.md +95 -0
- package/.kiro/steering/python-best-practices.md +48 -0
- package/.kiro/steering/react-best-practices.md +44 -0
- package/.kiro/steering/security-best-practices.md +41 -0
- package/.kiro/steering/testing-best-practices.md +59 -0
- package/.kiro/steering/typescript-best-practices.md +40 -0
- package/CHANGELOG.md +49 -0
- package/CONTRIBUTING.md +258 -0
- package/LICENSE +19 -0
- package/README.md +480 -0
- package/SECURITY.md +117 -0
- package/dist/api/index.d.ts +11 -0
- package/dist/api/index.js +65 -0
- package/dist/api/types.d.ts +15 -0
- package/dist/api/types.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +262 -0
- package/dist/config/ConfigManager.d.ts +40 -0
- package/dist/config/ConfigManager.js +238 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +19 -0
- package/dist/config/types.d.ts +72 -0
- package/dist/config/types.js +15 -0
- package/dist/diff/DiffEngine.d.ts +7 -0
- package/dist/diff/DiffEngine.js +73 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +21 -0
- package/dist/diff/types.d.ts +20 -0
- package/dist/diff/types.js +3 -0
- package/dist/integrations/GitLabIntegration.d.ts +7 -0
- package/dist/integrations/GitLabIntegration.js +45 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +21 -0
- package/dist/integrations/types.d.ts +11 -0
- package/dist/integrations/types.js +13 -0
- package/dist/parser/TemplateParser.d.ts +8 -0
- package/dist/parser/TemplateParser.js +75 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.js +22 -0
- package/dist/parser/types.d.ts +30 -0
- package/dist/parser/types.js +3 -0
- package/dist/pipeline/PipelineOrchestrator.d.ts +23 -0
- package/dist/pipeline/PipelineOrchestrator.js +191 -0
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +19 -0
- package/dist/pipeline/types.d.ts +41 -0
- package/dist/pipeline/types.js +13 -0
- package/dist/pricing/CacheManager.d.ts +75 -0
- package/dist/pricing/CacheManager.js +195 -0
- package/dist/pricing/PricingClient.d.ts +17 -0
- package/dist/pricing/PricingClient.js +122 -0
- package/dist/pricing/PricingService.d.ts +16 -0
- package/dist/pricing/PricingService.js +149 -0
- package/dist/pricing/calculators/ALBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/ALBCalculator.js +163 -0
- package/dist/pricing/calculators/APIGatewayCalculator.d.ts +10 -0
- package/dist/pricing/calculators/APIGatewayCalculator.js +177 -0
- package/dist/pricing/calculators/CloudFrontCalculator.d.ts +59 -0
- package/dist/pricing/calculators/CloudFrontCalculator.js +151 -0
- package/dist/pricing/calculators/DynamoDBCalculator.d.ts +9 -0
- package/dist/pricing/calculators/DynamoDBCalculator.js +146 -0
- package/dist/pricing/calculators/EC2Calculator.d.ts +7 -0
- package/dist/pricing/calculators/EC2Calculator.js +80 -0
- package/dist/pricing/calculators/ECSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/ECSCalculator.js +116 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.d.ts +8 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.js +106 -0
- package/dist/pricing/calculators/LambdaCalculator.d.ts +13 -0
- package/dist/pricing/calculators/LambdaCalculator.js +111 -0
- package/dist/pricing/calculators/NLBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/NLBCalculator.js +138 -0
- package/dist/pricing/calculators/NatGatewayCalculator.d.ts +12 -0
- package/dist/pricing/calculators/NatGatewayCalculator.js +116 -0
- package/dist/pricing/calculators/RDSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/RDSCalculator.js +103 -0
- package/dist/pricing/calculators/S3Calculator.d.ts +8 -0
- package/dist/pricing/calculators/S3Calculator.js +68 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.d.ts +12 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.js +129 -0
- package/dist/pricing/index.d.ts +10 -0
- package/dist/pricing/index.js +37 -0
- package/dist/pricing/types.d.ts +53 -0
- package/dist/pricing/types.js +22 -0
- package/dist/releasetag.txt +1 -0
- package/dist/reporter/Reporter.d.ts +18 -0
- package/dist/reporter/Reporter.js +412 -0
- package/dist/reporter/index.d.ts +2 -0
- package/dist/reporter/index.js +21 -0
- package/dist/reporter/types.d.ts +72 -0
- package/dist/reporter/types.js +3 -0
- package/dist/synthesis/SynthesisOrchestrator.d.ts +26 -0
- package/dist/synthesis/SynthesisOrchestrator.js +243 -0
- package/dist/synthesis/index.d.ts +2 -0
- package/dist/synthesis/index.js +19 -0
- package/dist/synthesis/types.d.ts +17 -0
- package/dist/synthesis/types.js +13 -0
- package/dist/threshold/ThresholdEnforcer.d.ts +29 -0
- package/dist/threshold/ThresholdEnforcer.js +143 -0
- package/dist/threshold/index.d.ts +2 -0
- package/dist/threshold/index.js +19 -0
- package/dist/threshold/types.d.ts +15 -0
- package/dist/threshold/types.js +17 -0
- package/docs/CALCULATORS.md +820 -0
- package/docs/CI_CD.md +608 -0
- package/docs/CONFIGURATION.md +407 -0
- package/docs/DEVELOPMENT.md +387 -0
- package/docs/RELEASE.md +223 -0
- package/docs/TROUBLESHOOTING.md +847 -0
- package/examples/.cdk-cost-analyzer.yml +85 -0
- package/examples/.gitlab-ci.yml +125 -0
- package/examples/api-usage.js +26 -0
- package/examples/complex/base.json +16 -0
- package/examples/complex/target.json +29 -0
- package/examples/monorepo/.gitlab-ci.yml +251 -0
- package/examples/monorepo/README.md +341 -0
- package/examples/monorepo/package.json +27 -0
- package/examples/monorepo/packages/backend-infra/.cdk-cost-analyzer.yml +34 -0
- package/examples/monorepo/packages/backend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/backend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/backend-infra/lib/backend-stack.ts +128 -0
- package/examples/monorepo/packages/backend-infra/package.json +30 -0
- package/examples/monorepo/packages/backend-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/data-infra/.cdk-cost-analyzer.yml +38 -0
- package/examples/monorepo/packages/data-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/data-infra/cdk.json +7 -0
- package/examples/monorepo/packages/data-infra/lib/data-stack.ts +121 -0
- package/examples/monorepo/packages/data-infra/package.json +30 -0
- package/examples/monorepo/packages/data-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/frontend-infra/.cdk-cost-analyzer.yml +31 -0
- package/examples/monorepo/packages/frontend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/frontend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/frontend-infra/lib/frontend-stack.ts +60 -0
- package/examples/monorepo/packages/frontend-infra/package.json +30 -0
- package/examples/monorepo/packages/frontend-infra/tsconfig.json +11 -0
- package/examples/monorepo/tsconfig.json +35 -0
- package/examples/multi-stack/.cdk-cost-analyzer.yml +72 -0
- package/examples/multi-stack/.gitlab-ci.yml +184 -0
- package/examples/multi-stack/README.md +279 -0
- package/examples/multi-stack/bin/app.ts +36 -0
- package/examples/multi-stack/cdk.json +72 -0
- package/examples/multi-stack/lib/compute-stack.ts +128 -0
- package/examples/multi-stack/lib/networking-stack.ts +69 -0
- package/examples/multi-stack/lib/storage-stack.ts +141 -0
- package/examples/multi-stack/package-lock.json +4437 -0
- package/examples/multi-stack/package.json +42 -0
- package/examples/multi-stack/tsconfig.json +34 -0
- package/examples/simple/base.json +8 -0
- package/examples/simple/target.json +14 -0
- package/examples/single-stack/.NVP +0 -0
- package/examples/single-stack/.cdk-cost-analyzer.yml +52 -0
- package/examples/single-stack/.gitlab-ci.yml +126 -0
- package/examples/single-stack/README.md +184 -0
- package/examples/single-stack/UeK +0 -0
- package/examples/single-stack/bin/app.ts +16 -0
- package/examples/single-stack/cdk.json +72 -0
- package/examples/single-stack/lib/infrastructure-stack.ts +119 -0
- package/examples/single-stack/package-lock.json +4443 -0
- package/examples/single-stack/package.json +38 -0
- package/examples/single-stack/tsconfig.json +34 -0
- package/package.json +139 -0
- package/test-cdk-project/README-COMPUTE.md +141 -0
- package/test-cdk-project/README.md +95 -0
- package/test-cdk-project/app-with-compute.js +102 -0
- package/test-cdk-project/app.js +81 -0
- package/test-cdk-project/cdk-compute.json +3 -0
- package/test-cdk-project/cdk.context.json +7 -0
- package/test-cdk-project/cdk.json +3 -0
- package/test-cdk-project/cdk.out/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out/cdk.out +1 -0
- package/test-cdk-project/cdk.out/manifest.json +503 -0
- package/test-cdk-project/cdk.out/tree.json +1 -0
- package/test-cdk-project/cdk.out.base/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.base/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out.base/cdk.out +1 -0
- package/test-cdk-project/cdk.out.base/manifest.json +503 -0
- package/test-cdk-project/cdk.out.base/tree.json +1 -0
- package/test-cdk-project/cdk.out.target/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.target/TestStack.template.json +183 -0
- package/test-cdk-project/cdk.out.target/cdk.out +1 -0
- package/test-cdk-project/cdk.out.target/manifest.json +521 -0
- package/test-cdk-project/cdk.out.target/tree.json +1 -0
- package/test-cdk-project/package-lock.json +422 -0
- package/test-cdk-project/package.json +17 -0
- package/tools/workflows/README.md +102 -0
- package/tools/workflows/validate-workflows.js +109 -0
- package/tools/workflows/workflow-utils.ts +181 -0
package/README.md
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# CDK Cost Analyzer
|
|
2
|
+
|
|
3
|
+
[](https://github.com/buildinginthecloud/cdk-cost-analyzer/actions/workflows/test.yml)
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- **Template Comparison**: Parse and diff CloudFormation templates (JSON/YAML) to identify added, removed, and modified resources
|
|
10
|
+
- **Cost Estimation**: Calculate monthly costs for AWS resources using real-time AWS Pricing API data
|
|
11
|
+
- **Automatic CDK Synthesis**: Optionally synthesize CDK applications in CI/CD pipelines
|
|
12
|
+
- **Cost Threshold Enforcement**: Fail pipelines when cost increases exceed configured thresholds
|
|
13
|
+
- **Configuration Management**: Project-specific configuration for thresholds, usage assumptions, and exclusions
|
|
14
|
+
- **Dual Interface**: Use as a CLI tool for quick analysis or import as a library for programmatic integration
|
|
15
|
+
- **Clear Reporting**: Generate formatted cost reports in text, JSON, or Markdown formats
|
|
16
|
+
- **GitLab Integration**: Post cost analysis reports as comments on GitLab merge requests
|
|
17
|
+
- **FinOps Awareness**: Help developers understand cost implications during the development cycle
|
|
18
|
+
|
|
19
|
+
## Use Cases
|
|
20
|
+
|
|
21
|
+
- Analyze infrastructure changes in GitLab merge requests
|
|
22
|
+
- Estimate costs before deploying CDK applications
|
|
23
|
+
- Enforce cost approval gates in CI/CD pipelines
|
|
24
|
+
- Compare different infrastructure configurations
|
|
25
|
+
- Promote cost-conscious development practices
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install cdk-cost-analyzer
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
- **[Configuration Guide](docs/CONFIGURATION.md)** - Configure thresholds, usage assumptions, and exclusions
|
|
36
|
+
- **[CI/CD Integration](docs/CI_CD.md)** - GitHub Actions and GitLab CI/CD setup guides
|
|
37
|
+
- **[Resource Calculator Reference](docs/CALCULATORS.md)** - Detailed cost calculation methods and assumptions
|
|
38
|
+
- **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
39
|
+
- **[Development Guide](docs/DEVELOPMENT.md)** - Local development, testing, and architecture
|
|
40
|
+
- **[Release Process](docs/RELEASE.md)** - How to release new versions
|
|
41
|
+
- **[Examples](examples/)** - Example templates and API usage demonstrations
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
### CLI Usage
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Compare two CloudFormation templates
|
|
49
|
+
cdk-cost-analyzer base-template.json target-template.json --region eu-central-1
|
|
50
|
+
|
|
51
|
+
# Use pipeline command with automatic synthesis
|
|
52
|
+
cdk-cost-analyzer pipeline \
|
|
53
|
+
--synth \
|
|
54
|
+
--cdk-app-path ./infrastructure \
|
|
55
|
+
--region eu-central-1 \
|
|
56
|
+
--config .cdk-cost-analyzer.yml
|
|
57
|
+
|
|
58
|
+
# Generate Markdown output
|
|
59
|
+
cdk-cost-analyzer compare base.yaml target.yaml --region us-east-1 --format markdown
|
|
60
|
+
|
|
61
|
+
# Show help
|
|
62
|
+
cdk-cost-analyzer --help
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Configuration File
|
|
66
|
+
|
|
67
|
+
Create `.cdk-cost-analyzer.yml` in your project:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# Cost thresholds
|
|
71
|
+
thresholds:
|
|
72
|
+
default:
|
|
73
|
+
warning: 50 # USD per month
|
|
74
|
+
error: 200
|
|
75
|
+
environments:
|
|
76
|
+
production:
|
|
77
|
+
warning: 25
|
|
78
|
+
error: 100
|
|
79
|
+
|
|
80
|
+
# Custom usage assumptions
|
|
81
|
+
usageAssumptions:
|
|
82
|
+
s3:
|
|
83
|
+
storageGB: 500
|
|
84
|
+
natGateway:
|
|
85
|
+
dataProcessedGB: 500
|
|
86
|
+
alb:
|
|
87
|
+
newConnectionsPerSecond: 50
|
|
88
|
+
processedBytesGB: 1000
|
|
89
|
+
|
|
90
|
+
# Resource exclusions
|
|
91
|
+
exclusions:
|
|
92
|
+
resourceTypes:
|
|
93
|
+
- AWS::IAM::Role
|
|
94
|
+
- AWS::Logs::LogGroup
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See the [Configuration Guide](docs/CONFIGURATION.md) for complete documentation.
|
|
98
|
+
|
|
99
|
+
### GitLab CI/CD Integration
|
|
100
|
+
|
|
101
|
+
Add to your `.gitlab-ci.yml`:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
cost-analysis:
|
|
105
|
+
stage: cost-analysis
|
|
106
|
+
image: node:18
|
|
107
|
+
before_script:
|
|
108
|
+
- npm install -g cdk-cost-analyzer
|
|
109
|
+
script:
|
|
110
|
+
- |
|
|
111
|
+
cdk-cost-analyzer pipeline \
|
|
112
|
+
--synth \
|
|
113
|
+
--cdk-app-path ./infrastructure \
|
|
114
|
+
--region $AWS_REGION \
|
|
115
|
+
--config .cdk-cost-analyzer.yml \
|
|
116
|
+
--format markdown \
|
|
117
|
+
--post-to-gitlab
|
|
118
|
+
only:
|
|
119
|
+
- merge_requests
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
See the [CI/CD Integration Guide](docs/CI_CD.md) for complete documentation.
|
|
123
|
+
|
|
124
|
+
### GitHub Actions Integration
|
|
125
|
+
|
|
126
|
+
Add to your `.github/workflows/ci.yml`:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
name: CI
|
|
130
|
+
|
|
131
|
+
on:
|
|
132
|
+
push:
|
|
133
|
+
branches: ['**']
|
|
134
|
+
pull_request:
|
|
135
|
+
branches: ['**']
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
test:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@v4
|
|
142
|
+
- uses: actions/setup-node@v4
|
|
143
|
+
with:
|
|
144
|
+
node-version: '18.x'
|
|
145
|
+
cache: 'npm'
|
|
146
|
+
- run: npm ci
|
|
147
|
+
- run: npm run eslint
|
|
148
|
+
- run: npm run lint
|
|
149
|
+
- run: npm run build
|
|
150
|
+
- run: npm run test:silent
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The GitHub Actions workflow automatically runs on every push and pull request, executing linting, type checking, build verification, and the complete test suite. See the [CI/CD Integration Guide](docs/CI_CD.md) for complete documentation.
|
|
154
|
+
|
|
155
|
+
### Programmatic Usage
|
|
156
|
+
|
|
157
|
+
See [examples/api-usage.js](examples/api-usage.js) for a complete working example.
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { analyzeCosts } from 'cdk-cost-analyzer';
|
|
161
|
+
|
|
162
|
+
const result = await analyzeCosts({
|
|
163
|
+
baseTemplate: baseTemplateContent,
|
|
164
|
+
targetTemplate: targetTemplateContent,
|
|
165
|
+
region: 'eu-central-1',
|
|
166
|
+
format: 'text' // or 'json', 'markdown'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
console.log(`Cost delta: ${result.totalDelta} ${result.currency}`);
|
|
170
|
+
console.log(`Added resources: ${result.addedResources.length}`);
|
|
171
|
+
console.log(`Removed resources: ${result.removedResources.length}`);
|
|
172
|
+
console.log(`Modified resources: ${result.modifiedResources.length}`);
|
|
173
|
+
console.log(result.summary); // Formatted report
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### GitLab Integration
|
|
177
|
+
|
|
178
|
+
Post cost analysis reports as comments on GitLab merge requests:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { analyzeCosts, GitLabIntegration } from 'cdk-cost-analyzer';
|
|
182
|
+
|
|
183
|
+
// Analyze costs
|
|
184
|
+
const result = await analyzeCosts({
|
|
185
|
+
baseTemplate: baseTemplateContent,
|
|
186
|
+
targetTemplate: targetTemplateContent,
|
|
187
|
+
region: 'eu-central-1',
|
|
188
|
+
format: 'markdown'
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Post to GitLab MR
|
|
192
|
+
const gitlab = GitLabIntegration.fromEnvironment();
|
|
193
|
+
await gitlab.postMergeRequestComment(
|
|
194
|
+
process.env.CI_PROJECT_ID!,
|
|
195
|
+
process.env.CI_MERGE_REQUEST_IID!,
|
|
196
|
+
result.summary
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Configure in `.gitlab-ci.yml`:
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
cost-analysis:
|
|
204
|
+
stage: test
|
|
205
|
+
script:
|
|
206
|
+
- npm install cdk-cost-analyzer
|
|
207
|
+
- cdk-cost-analyzer base.json target.json --format markdown > cost-report.md
|
|
208
|
+
- node -e "require('cdk-cost-analyzer').GitLabIntegration.fromEnvironment().postMergeRequestComment(process.env.CI_PROJECT_ID, process.env.CI_MERGE_REQUEST_IID, require('fs').readFileSync('cost-report.md', 'utf8'))"
|
|
209
|
+
only:
|
|
210
|
+
- merge_requests
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Supported Resource Types
|
|
214
|
+
|
|
215
|
+
### Core Resources (Phase 1 & 2)
|
|
216
|
+
|
|
217
|
+
- **AWS::EC2::Instance** - EC2 instances with on-demand pricing
|
|
218
|
+
- **AWS::S3::Bucket** - S3 buckets with storage and request costs
|
|
219
|
+
- **AWS::Lambda::Function** - Lambda functions with invocation and duration costs
|
|
220
|
+
- **AWS::RDS::DBInstance** - RDS database instances
|
|
221
|
+
- **AWS::DynamoDB::Table** - DynamoDB tables with provisioned or on-demand billing
|
|
222
|
+
- **AWS::ECS::Service** - ECS services with Fargate or EC2 launch types
|
|
223
|
+
- **AWS::ApiGateway::RestApi** - API Gateway REST APIs
|
|
224
|
+
- **AWS::ApiGatewayV2::Api** - API Gateway HTTP and WebSocket APIs
|
|
225
|
+
|
|
226
|
+
### Networking Resources (Phase 3 - Current)
|
|
227
|
+
|
|
228
|
+
- **AWS::EC2::NatGateway** - NAT Gateways with hourly and data processing costs
|
|
229
|
+
- **AWS::ElasticLoadBalancingV2::LoadBalancer** - Application and Network Load Balancers with LCU costs
|
|
230
|
+
- **AWS::EC2::VPCEndpoint** - VPC Endpoints (interface and gateway types)
|
|
231
|
+
|
|
232
|
+
### Content Delivery & Caching (Phase 3 - Current)
|
|
233
|
+
|
|
234
|
+
- **AWS::CloudFront::Distribution** - CloudFront distributions with data transfer and request costs
|
|
235
|
+
|
|
236
|
+
### Coming Soon
|
|
237
|
+
|
|
238
|
+
- ElastiCache clusters
|
|
239
|
+
- EKS clusters
|
|
240
|
+
- And more...
|
|
241
|
+
|
|
242
|
+
## Cost Calculation Assumptions
|
|
243
|
+
|
|
244
|
+
For resources with usage-based pricing, the following default assumptions are used:
|
|
245
|
+
|
|
246
|
+
### Phase 1 Resources
|
|
247
|
+
- **S3 Buckets**: 100 GB standard storage, 10,000 GET requests/month
|
|
248
|
+
- **Lambda Functions**: 1 million invocations/month, average 1-second duration
|
|
249
|
+
- **RDS Instances**: 100 GB storage, single-AZ deployment
|
|
250
|
+
- **EC2 Instances**: 730 hours/month (full month), on-demand pricing
|
|
251
|
+
|
|
252
|
+
### Phase 2 Resources
|
|
253
|
+
- **DynamoDB Tables (Provisioned)**: 5 read capacity units, 5 write capacity units
|
|
254
|
+
- **DynamoDB Tables (On-Demand)**: 10M read requests, 1M write requests per month
|
|
255
|
+
- **ECS Services (Fargate)**: 0.25 vCPU, 0.5 GB memory per task
|
|
256
|
+
- **API Gateway (REST)**: 1M requests per month
|
|
257
|
+
- **API Gateway (HTTP)**: 1M requests per month
|
|
258
|
+
- **API Gateway (WebSocket)**: 1M messages, 100K connection minutes per month
|
|
259
|
+
|
|
260
|
+
### Phase 3 Resources
|
|
261
|
+
- **NAT Gateway**: 500 GB data processed per month
|
|
262
|
+
- **Application Load Balancer**: 50 new connections/sec, 5,000 active connections/min, 1,000 GB processed
|
|
263
|
+
- **Network Load Balancer**: 100 new connections/sec, 10,000 active connections/min, 1,000 GB processed
|
|
264
|
+
- **VPC Endpoint (Interface)**: 100 GB data processed per month
|
|
265
|
+
- **CloudFront Distribution**: 100 GB data transfer out, 1M HTTP/HTTPS requests per month
|
|
266
|
+
|
|
267
|
+
These assumptions are documented in cost reports and can be customized via configuration file or by extending the calculator classes.
|
|
268
|
+
|
|
269
|
+
## Report Formats
|
|
270
|
+
|
|
271
|
+
### Text Format (Default)
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
============================================================
|
|
275
|
+
CDK Cost Analysis Report
|
|
276
|
+
============================================================
|
|
277
|
+
|
|
278
|
+
Total Cost Delta: +$245.60
|
|
279
|
+
|
|
280
|
+
ADDED RESOURCES:
|
|
281
|
+
------------------------------------------------------------
|
|
282
|
+
• MyEC2Instance (AWS::EC2::Instance): $30.40 [high]
|
|
283
|
+
• MyRDSInstance (AWS::RDS::DBInstance): $215.20 [high]
|
|
284
|
+
|
|
285
|
+
REMOVED RESOURCES:
|
|
286
|
+
------------------------------------------------------------
|
|
287
|
+
(none)
|
|
288
|
+
|
|
289
|
+
MODIFIED RESOURCES:
|
|
290
|
+
------------------------------------------------------------
|
|
291
|
+
(none)
|
|
292
|
+
|
|
293
|
+
============================================================
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Markdown Format
|
|
297
|
+
|
|
298
|
+
Perfect for GitLab merge request comments:
|
|
299
|
+
|
|
300
|
+
```markdown
|
|
301
|
+
# CDK Cost Analysis Report
|
|
302
|
+
|
|
303
|
+
**Total Cost Delta:** +$245.60
|
|
304
|
+
|
|
305
|
+
## Added Resources
|
|
306
|
+
|
|
307
|
+
| Logical ID | Type | Monthly Cost |
|
|
308
|
+
|------------|------|--------------|
|
|
309
|
+
| MyEC2Instance | AWS::EC2::Instance | $30.40 |
|
|
310
|
+
| MyRDSInstance | AWS::RDS::DBInstance | $215.20 |
|
|
311
|
+
|
|
312
|
+
## Modified Resources
|
|
313
|
+
|
|
314
|
+
| Logical ID | Type | Old Cost | New Cost | Delta |
|
|
315
|
+
|------------|------|----------|----------|-------|
|
|
316
|
+
| MyFunction | AWS::Lambda::Function | $50.00 | $75.00 | +$25.00 |
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### JSON Format
|
|
320
|
+
|
|
321
|
+
For programmatic processing and integration:
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"totalDelta": 245.60,
|
|
326
|
+
"currency": "USD",
|
|
327
|
+
"addedCosts": [...],
|
|
328
|
+
"removedCosts": [...],
|
|
329
|
+
"modifiedCosts": [...]
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Configuration
|
|
334
|
+
|
|
335
|
+
### AWS Credentials
|
|
336
|
+
|
|
337
|
+
The tool uses the AWS SDK default credential chain. Ensure you have AWS credentials configured:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# Via environment variables
|
|
341
|
+
export AWS_ACCESS_KEY_ID=your_access_key
|
|
342
|
+
export AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
343
|
+
|
|
344
|
+
# Or via AWS CLI configuration
|
|
345
|
+
aws configure
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Region
|
|
349
|
+
|
|
350
|
+
Specify the AWS region for pricing data:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# CLI
|
|
354
|
+
cdk-cost-analyzer base.json target.json --region eu-central-1
|
|
355
|
+
|
|
356
|
+
# API
|
|
357
|
+
analyzeCosts({ baseTemplate, targetTemplate, region: 'eu-central-1' })
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Default region: `eu-central-1`
|
|
361
|
+
|
|
362
|
+
### GitLab Configuration
|
|
363
|
+
|
|
364
|
+
For GitLab integration, the following environment variables are used:
|
|
365
|
+
|
|
366
|
+
- `CI_JOB_TOKEN` or `GITLAB_TOKEN`: GitLab API authentication token
|
|
367
|
+
- `CI_API_V4_URL`: GitLab API URL (defaults to `https://gitlab.com/api/v4`)
|
|
368
|
+
- `CI_PROJECT_ID`: Project ID (automatically set in GitLab CI)
|
|
369
|
+
- `CI_MERGE_REQUEST_IID`: Merge request IID (automatically set in GitLab CI)
|
|
370
|
+
|
|
371
|
+
## Error Handling
|
|
372
|
+
|
|
373
|
+
The tool handles errors gracefully:
|
|
374
|
+
|
|
375
|
+
- **Invalid templates**: Clear error messages for malformed JSON/YAML
|
|
376
|
+
- **Missing pricing data**: Resources marked as "unknown cost" with warnings
|
|
377
|
+
- **API failures**: Automatic retry with exponential backoff, fallback to cached data
|
|
378
|
+
- **Unsupported resources**: Marked as "unknown cost", analysis continues
|
|
379
|
+
- **GitLab API errors**: Descriptive error messages with HTTP status codes
|
|
380
|
+
|
|
381
|
+
## Development Roadmap
|
|
382
|
+
|
|
383
|
+
### Phase 1 (MVP) ✓
|
|
384
|
+
|
|
385
|
+
- Core template parsing and diffing
|
|
386
|
+
- Basic resource costing (EC2, S3, Lambda, RDS)
|
|
387
|
+
- CLI and programmatic API
|
|
388
|
+
- AWS Pricing API integration
|
|
389
|
+
- Text and JSON report formats
|
|
390
|
+
|
|
391
|
+
### Phase 2 ✓
|
|
392
|
+
|
|
393
|
+
- Markdown report formatter for GitLab MR comments
|
|
394
|
+
- GitLab integration module for posting reports
|
|
395
|
+
- Extended resource support (DynamoDB, ECS, API Gateway)
|
|
396
|
+
- Property-based testing with fast-check
|
|
397
|
+
- Comprehensive unit tests for all new features
|
|
398
|
+
|
|
399
|
+
### Phase 3 (Production Readiness) ✓
|
|
400
|
+
|
|
401
|
+
- **Automatic CDK Synthesis**: Synthesize CDK applications in CI/CD pipelines
|
|
402
|
+
- **Cost Threshold Enforcement**: Fail pipelines when costs exceed configured limits
|
|
403
|
+
- **Configuration Management**: Project-specific configuration files
|
|
404
|
+
- **Additional Resource Calculators**: NAT Gateway, ALB, NLB, VPC Endpoints
|
|
405
|
+
- **Enhanced CLI**: Pipeline command with synthesis and threshold support
|
|
406
|
+
- **Comprehensive Documentation**: Configuration guide, GitLab CI/CD examples
|
|
407
|
+
|
|
408
|
+
### Phase 4 (Planned)
|
|
409
|
+
|
|
410
|
+
- Multi-region cost analysis with regional breakdowns
|
|
411
|
+
- Historical cost tracking and trend analysis
|
|
412
|
+
- Cost optimization recommendations
|
|
413
|
+
- Support for Savings Plans and Reserved Instances
|
|
414
|
+
- Additional resource types (CloudFront, ElastiCache, EKS)
|
|
415
|
+
- GitHub Actions integration
|
|
416
|
+
- Slack/Teams notifications
|
|
417
|
+
|
|
418
|
+
## Testing
|
|
419
|
+
|
|
420
|
+
The project includes comprehensive test coverage with both unit and property-based tests:
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# Run all tests
|
|
424
|
+
npm test
|
|
425
|
+
|
|
426
|
+
# Run tests in watch mode
|
|
427
|
+
npm run test:watch
|
|
428
|
+
|
|
429
|
+
# Build the project
|
|
430
|
+
npm run build
|
|
431
|
+
|
|
432
|
+
# Type checking
|
|
433
|
+
npm run lint
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Contributing
|
|
437
|
+
|
|
438
|
+
Contributions are welcome! Please see the [implementation plan](.kiro/specs/cdk-cost-analyzer/tasks.md) for current development tasks.
|
|
439
|
+
|
|
440
|
+
### Development Setup
|
|
441
|
+
|
|
442
|
+
This project uses [Projen](https://projen.io/) for project management. All project configuration is managed through `.projenrc.ts`.
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# Clone the repository
|
|
446
|
+
git clone https://gitlab.com/anwb/cdk-cost-analyzer.git
|
|
447
|
+
cd cdk-cost-analyzer
|
|
448
|
+
|
|
449
|
+
# Install dependencies
|
|
450
|
+
npm install
|
|
451
|
+
|
|
452
|
+
# Synthesize project files (after modifying .projenrc.ts)
|
|
453
|
+
npx projen
|
|
454
|
+
|
|
455
|
+
# Build the project
|
|
456
|
+
npx projen build
|
|
457
|
+
|
|
458
|
+
# Run tests
|
|
459
|
+
npx projen test
|
|
460
|
+
|
|
461
|
+
# Run linting
|
|
462
|
+
npx projen lint
|
|
463
|
+
|
|
464
|
+
# Compile TypeScript
|
|
465
|
+
npx projen compile
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
**Important**: Never manually edit generated files like `package.json`, `tsconfig.json`, or `.gitignore`. Always modify `.projenrc.ts` and run `npx projen` to regenerate these files.
|
|
469
|
+
|
|
470
|
+
### Release Process
|
|
471
|
+
|
|
472
|
+
See [docs/RELEASE.md](docs/RELEASE.md) for detailed release instructions.
|
|
473
|
+
|
|
474
|
+
## License
|
|
475
|
+
|
|
476
|
+
MIT
|
|
477
|
+
|
|
478
|
+
## Acknowledgments
|
|
479
|
+
|
|
480
|
+
Inspired by [Infracost](https://www.infracost.io/) for Terraform. Built for ANWB's CDK and GitLab CI/CD workflows.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
We release patches for security vulnerabilities in the following versions:
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
| ------- | ------------------ |
|
|
9
|
+
| 0.x.x | :white_check_mark: |
|
|
10
|
+
|
|
11
|
+
## Reporting a Vulnerability
|
|
12
|
+
|
|
13
|
+
We take security vulnerabilities seriously. If you discover a security issue, please report it responsibly.
|
|
14
|
+
|
|
15
|
+
### How to Report
|
|
16
|
+
|
|
17
|
+
**Do not** create a public GitHub issue for security vulnerabilities.
|
|
18
|
+
|
|
19
|
+
Instead, please report security vulnerabilities by emailing:
|
|
20
|
+
|
|
21
|
+
**yvo@buildinginthecloud.com**
|
|
22
|
+
|
|
23
|
+
Include the following information:
|
|
24
|
+
- Description of the vulnerability
|
|
25
|
+
- Steps to reproduce the issue
|
|
26
|
+
- Potential impact
|
|
27
|
+
- Suggested fix (if available)
|
|
28
|
+
|
|
29
|
+
### What to Expect
|
|
30
|
+
|
|
31
|
+
- **Acknowledgment**: We will acknowledge receipt of your report within 48 hours
|
|
32
|
+
- **Assessment**: We will assess the vulnerability and determine its severity
|
|
33
|
+
- **Fix**: We will work on a fix and coordinate disclosure timing with you
|
|
34
|
+
- **Credit**: We will credit you in the security advisory (unless you prefer to remain anonymous)
|
|
35
|
+
|
|
36
|
+
### Security Best Practices
|
|
37
|
+
|
|
38
|
+
When using CDK Cost Analyzer:
|
|
39
|
+
|
|
40
|
+
1. **AWS Credentials**: Never commit AWS credentials to version control
|
|
41
|
+
- Use environment variables or AWS credential files
|
|
42
|
+
- Use IAM roles when running in AWS environments
|
|
43
|
+
- Follow the principle of least privilege
|
|
44
|
+
|
|
45
|
+
2. **Dependencies**: Keep dependencies up to date
|
|
46
|
+
- Run `npm audit` regularly
|
|
47
|
+
- Update dependencies when security patches are available
|
|
48
|
+
|
|
49
|
+
3. **CI/CD**: Secure your CI/CD pipelines
|
|
50
|
+
- Use secrets management for tokens and credentials
|
|
51
|
+
- Limit access to CI/CD variables
|
|
52
|
+
- Use protected branches for production deployments
|
|
53
|
+
|
|
54
|
+
4. **GitLab Integration**: Protect your GitLab tokens
|
|
55
|
+
- Use project or group access tokens with minimal scope
|
|
56
|
+
- Store tokens in CI/CD variables (masked and protected)
|
|
57
|
+
- Rotate tokens regularly
|
|
58
|
+
|
|
59
|
+
5. **Command Execution**: The tool executes CDK synthesis commands securely
|
|
60
|
+
- Commands are executed without shell interpretation to prevent injection attacks
|
|
61
|
+
- Arguments are passed as arrays rather than concatenated strings
|
|
62
|
+
|
|
63
|
+
## Security Considerations
|
|
64
|
+
|
|
65
|
+
### AWS Pricing API
|
|
66
|
+
|
|
67
|
+
The tool requires AWS credentials with `pricing:GetProducts` permission. This is a read-only permission with minimal security risk.
|
|
68
|
+
|
|
69
|
+
Recommended IAM policy:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"Version": "2012-10-17",
|
|
73
|
+
"Statement": [
|
|
74
|
+
{
|
|
75
|
+
"Effect": "Allow",
|
|
76
|
+
"Action": [
|
|
77
|
+
"pricing:GetProducts"
|
|
78
|
+
],
|
|
79
|
+
"Resource": "*"
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### GitLab API Access
|
|
86
|
+
|
|
87
|
+
When using GitLab integration, the tool requires a token with `api` scope to post merge request comments. Use project or group access tokens instead of personal access tokens when possible.
|
|
88
|
+
|
|
89
|
+
### Template Analysis
|
|
90
|
+
|
|
91
|
+
The tool parses CloudFormation templates but does not execute them or make changes to your AWS infrastructure. Template analysis is performed locally and does not send template content to external services (except AWS Pricing API for cost data).
|
|
92
|
+
|
|
93
|
+
## Known Security Considerations
|
|
94
|
+
|
|
95
|
+
- The tool caches AWS Pricing API responses in memory to reduce API calls. Cached data is not persisted to disk.
|
|
96
|
+
- GitLab API tokens are read from environment variables and not logged or stored.
|
|
97
|
+
- CloudFormation templates may contain sensitive information. Ensure proper access controls on repositories containing templates.
|
|
98
|
+
- CDK synthesis commands are executed with `shell: false` to prevent command injection vulnerabilities.
|
|
99
|
+
|
|
100
|
+
## Disclosure Policy
|
|
101
|
+
|
|
102
|
+
We follow coordinated vulnerability disclosure:
|
|
103
|
+
|
|
104
|
+
1. Security issues are fixed in private
|
|
105
|
+
2. A security advisory is prepared
|
|
106
|
+
3. A new version is released with the fix
|
|
107
|
+
4. The security advisory is published
|
|
108
|
+
5. Credit is given to the reporter (if desired)
|
|
109
|
+
|
|
110
|
+
## Security Updates
|
|
111
|
+
|
|
112
|
+
Security updates are released as patch versions and announced through:
|
|
113
|
+
- GitHub Security Advisories
|
|
114
|
+
- Release notes in CHANGELOG.md
|
|
115
|
+
- NPM package updates
|
|
116
|
+
|
|
117
|
+
Subscribe to repository notifications to stay informed about security updates.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AnalyzeOptions, CostAnalysisResult } from './types';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export { TemplateParseError } from '../parser/TemplateParser';
|
|
4
|
+
export { PricingAPIError, UnsupportedResourceError } from '../pricing/types';
|
|
5
|
+
export * from '../integrations';
|
|
6
|
+
export * from '../reporter/types';
|
|
7
|
+
export * from '../config';
|
|
8
|
+
export * from '../synthesis';
|
|
9
|
+
export * from '../threshold';
|
|
10
|
+
export * from '../pipeline';
|
|
11
|
+
export declare function analyzeCosts(options: AnalyzeOptions): Promise<CostAnalysisResult>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.UnsupportedResourceError = exports.PricingAPIError = exports.TemplateParseError = void 0;
|
|
18
|
+
exports.analyzeCosts = analyzeCosts;
|
|
19
|
+
const DiffEngine_1 = require("../diff/DiffEngine");
|
|
20
|
+
const TemplateParser_1 = require("../parser/TemplateParser");
|
|
21
|
+
const PricingService_1 = require("../pricing/PricingService");
|
|
22
|
+
const Reporter_1 = require("../reporter/Reporter");
|
|
23
|
+
__exportStar(require("./types"), exports);
|
|
24
|
+
var TemplateParser_2 = require("../parser/TemplateParser");
|
|
25
|
+
Object.defineProperty(exports, "TemplateParseError", { enumerable: true, get: function () { return TemplateParser_2.TemplateParseError; } });
|
|
26
|
+
var types_1 = require("../pricing/types");
|
|
27
|
+
Object.defineProperty(exports, "PricingAPIError", { enumerable: true, get: function () { return types_1.PricingAPIError; } });
|
|
28
|
+
Object.defineProperty(exports, "UnsupportedResourceError", { enumerable: true, get: function () { return types_1.UnsupportedResourceError; } });
|
|
29
|
+
__exportStar(require("../integrations"), exports);
|
|
30
|
+
__exportStar(require("../reporter/types"), exports);
|
|
31
|
+
__exportStar(require("../config"), exports);
|
|
32
|
+
__exportStar(require("../synthesis"), exports);
|
|
33
|
+
__exportStar(require("../threshold"), exports);
|
|
34
|
+
__exportStar(require("../pipeline"), exports);
|
|
35
|
+
async function analyzeCosts(options) {
|
|
36
|
+
const region = options.region || 'eu-central-1';
|
|
37
|
+
const format = options.format || 'text';
|
|
38
|
+
if (!options.baseTemplate || !options.targetTemplate) {
|
|
39
|
+
throw new Error('Both baseTemplate and targetTemplate are required');
|
|
40
|
+
}
|
|
41
|
+
const parser = new TemplateParser_1.TemplateParser();
|
|
42
|
+
const diffEngine = new DiffEngine_1.DiffEngine();
|
|
43
|
+
const pricingService = new PricingService_1.PricingService();
|
|
44
|
+
const reporter = new Reporter_1.Reporter();
|
|
45
|
+
try {
|
|
46
|
+
const baseTemplateObj = parser.parse(options.baseTemplate);
|
|
47
|
+
const targetTemplateObj = parser.parse(options.targetTemplate);
|
|
48
|
+
const diff = diffEngine.diff(baseTemplateObj, targetTemplateObj);
|
|
49
|
+
const costDelta = await pricingService.getCostDelta(diff, region);
|
|
50
|
+
const summary = reporter.generateReport(costDelta, format);
|
|
51
|
+
return {
|
|
52
|
+
totalDelta: costDelta.totalDelta,
|
|
53
|
+
currency: costDelta.currency,
|
|
54
|
+
addedResources: costDelta.addedCosts,
|
|
55
|
+
removedResources: costDelta.removedCosts,
|
|
56
|
+
modifiedResources: costDelta.modifiedCosts,
|
|
57
|
+
summary,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
// Clean up resources to prevent hanging connections
|
|
62
|
+
pricingService.destroy();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBLG9DQW1DQztBQWxERCxtREFBZ0Q7QUFDaEQsNkRBQTBEO0FBQzFELDhEQUEyRDtBQUMzRCxtREFBZ0Q7QUFFaEQsMENBQXdCO0FBQ3hCLDJEQUE4RDtBQUFyRCxvSEFBQSxrQkFBa0IsT0FBQTtBQUMzQiwwQ0FBNkU7QUFBcEUsd0dBQUEsZUFBZSxPQUFBO0FBQUUsaUhBQUEsd0JBQXdCLE9BQUE7QUFDbEQsa0RBQWdDO0FBQ2hDLG9EQUFrQztBQUNsQyw0Q0FBMEI7QUFDMUIsK0NBQTZCO0FBQzdCLCtDQUE2QjtBQUM3Qiw4Q0FBNEI7QUFFckIsS0FBSyxVQUFVLFlBQVksQ0FBQyxPQUF1QjtJQUN4RCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLGNBQWMsQ0FBQztJQUNoRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQztJQUV4QyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLElBQUksK0JBQWMsRUFBRSxDQUFDO0lBQ3BDLE1BQU0sVUFBVSxHQUFHLElBQUksdUJBQVUsRUFBRSxDQUFDO0lBQ3BDLE1BQU0sY0FBYyxHQUFHLElBQUksK0JBQWMsRUFBRSxDQUFDO0lBQzVDLE1BQU0sUUFBUSxHQUFHLElBQUksbUJBQVEsRUFBRSxDQUFDO0lBRWhDLElBQUksQ0FBQztRQUNILE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzNELE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFL0QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUVqRSxNQUFNLFNBQVMsR0FBRyxNQUFNLGNBQWMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRWxFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTNELE9BQU87WUFDTCxVQUFVLEVBQUUsU0FBUyxDQUFDLFVBQVU7WUFDaEMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzVCLGNBQWMsRUFBRSxTQUFTLENBQUMsVUFBVTtZQUNwQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsWUFBWTtZQUN4QyxpQkFBaUIsRUFBRSxTQUFTLENBQUMsYUFBYTtZQUMxQyxPQUFPO1NBQ1IsQ0FBQztJQUNKLENBQUM7WUFBUyxDQUFDO1FBQ1Qsb0RBQW9EO1FBQ3BELGNBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFuYWx5emVPcHRpb25zLCBDb3N0QW5hbHlzaXNSZXN1bHQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IERpZmZFbmdpbmUgfSBmcm9tICcuLi9kaWZmL0RpZmZFbmdpbmUnO1xuaW1wb3J0IHsgVGVtcGxhdGVQYXJzZXIgfSBmcm9tICcuLi9wYXJzZXIvVGVtcGxhdGVQYXJzZXInO1xuaW1wb3J0IHsgUHJpY2luZ1NlcnZpY2UgfSBmcm9tICcuLi9wcmljaW5nL1ByaWNpbmdTZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydGVyIH0gZnJvbSAnLi4vcmVwb3J0ZXIvUmVwb3J0ZXInO1xuXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcbmV4cG9ydCB7IFRlbXBsYXRlUGFyc2VFcnJvciB9IGZyb20gJy4uL3BhcnNlci9UZW1wbGF0ZVBhcnNlcic7XG5leHBvcnQgeyBQcmljaW5nQVBJRXJyb3IsIFVuc3VwcG9ydGVkUmVzb3VyY2VFcnJvciB9IGZyb20gJy4uL3ByaWNpbmcvdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi4vaW50ZWdyYXRpb25zJztcbmV4cG9ydCAqIGZyb20gJy4uL3JlcG9ydGVyL3R5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4uL2NvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuLi9zeW50aGVzaXMnO1xuZXhwb3J0ICogZnJvbSAnLi4vdGhyZXNob2xkJztcbmV4cG9ydCAqIGZyb20gJy4uL3BpcGVsaW5lJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFuYWx5emVDb3N0cyhvcHRpb25zOiBBbmFseXplT3B0aW9ucyk6IFByb21pc2U8Q29zdEFuYWx5c2lzUmVzdWx0PiB7XG4gIGNvbnN0IHJlZ2lvbiA9IG9wdGlvbnMucmVnaW9uIHx8ICdldS1jZW50cmFsLTEnO1xuICBjb25zdCBmb3JtYXQgPSBvcHRpb25zLmZvcm1hdCB8fCAndGV4dCc7XG5cbiAgaWYgKCFvcHRpb25zLmJhc2VUZW1wbGF0ZSB8fCAhb3B0aW9ucy50YXJnZXRUZW1wbGF0ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQm90aCBiYXNlVGVtcGxhdGUgYW5kIHRhcmdldFRlbXBsYXRlIGFyZSByZXF1aXJlZCcpO1xuICB9XG5cbiAgY29uc3QgcGFyc2VyID0gbmV3IFRlbXBsYXRlUGFyc2VyKCk7XG4gIGNvbnN0IGRpZmZFbmdpbmUgPSBuZXcgRGlmZkVuZ2luZSgpO1xuICBjb25zdCBwcmljaW5nU2VydmljZSA9IG5ldyBQcmljaW5nU2VydmljZSgpO1xuICBjb25zdCByZXBvcnRlciA9IG5ldyBSZXBvcnRlcigpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgYmFzZVRlbXBsYXRlT2JqID0gcGFyc2VyLnBhcnNlKG9wdGlvbnMuYmFzZVRlbXBsYXRlKTtcbiAgICBjb25zdCB0YXJnZXRUZW1wbGF0ZU9iaiA9IHBhcnNlci5wYXJzZShvcHRpb25zLnRhcmdldFRlbXBsYXRlKTtcblxuICAgIGNvbnN0IGRpZmYgPSBkaWZmRW5naW5lLmRpZmYoYmFzZVRlbXBsYXRlT2JqLCB0YXJnZXRUZW1wbGF0ZU9iaik7XG5cbiAgICBjb25zdCBjb3N0RGVsdGEgPSBhd2FpdCBwcmljaW5nU2VydmljZS5nZXRDb3N0RGVsdGEoZGlmZiwgcmVnaW9uKTtcblxuICAgIGNvbnN0IHN1bW1hcnkgPSByZXBvcnRlci5nZW5lcmF0ZVJlcG9ydChjb3N0RGVsdGEsIGZvcm1hdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxEZWx0YTogY29zdERlbHRhLnRvdGFsRGVsdGEsXG4gICAgICBjdXJyZW5jeTogY29zdERlbHRhLmN1cnJlbmN5LFxuICAgICAgYWRkZWRSZXNvdXJjZXM6IGNvc3REZWx0YS5hZGRlZENvc3RzLFxuICAgICAgcmVtb3ZlZFJlc291cmNlczogY29zdERlbHRhLnJlbW92ZWRDb3N0cyxcbiAgICAgIG1vZGlmaWVkUmVzb3VyY2VzOiBjb3N0RGVsdGEubW9kaWZpZWRDb3N0cyxcbiAgICAgIHN1bW1hcnksXG4gICAgfTtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBDbGVhbiB1cCByZXNvdXJjZXMgdG8gcHJldmVudCBoYW5naW5nIGNvbm5lY3Rpb25zXG4gICAgcHJpY2luZ1NlcnZpY2UuZGVzdHJveSgpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ResourceCost, ModifiedResourceCost } from '../pricing/types';
|
|
2
|
+
export interface AnalyzeOptions {
|
|
3
|
+
baseTemplate: string;
|
|
4
|
+
targetTemplate: string;
|
|
5
|
+
region?: string;
|
|
6
|
+
format?: 'text' | 'json' | 'markdown';
|
|
7
|
+
}
|
|
8
|
+
export interface CostAnalysisResult {
|
|
9
|
+
totalDelta: number;
|
|
10
|
+
currency: string;
|
|
11
|
+
addedResources: ResourceCost[];
|
|
12
|
+
removedResources: ResourceCost[];
|
|
13
|
+
modifiedResources: ModifiedResourceCost[];
|
|
14
|
+
summary: string;
|
|
15
|
+
}
|