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
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
This guide covers local development, testing, and the technical implementation of CDK Cost Analyzer.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Build the project
|
|
12
|
+
npm run build
|
|
13
|
+
|
|
14
|
+
# Run tests
|
|
15
|
+
npm run test
|
|
16
|
+
|
|
17
|
+
# Run linting
|
|
18
|
+
npm run lint
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
The application follows a modular, layered architecture:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────────────────────────────────────────┐
|
|
27
|
+
│ Entry Points │
|
|
28
|
+
│ (CLI: src/cli, API: src/api) │
|
|
29
|
+
└──────────────────┬──────────────────────────┘
|
|
30
|
+
│
|
|
31
|
+
┌──────────────────▼──────────────────────────┐
|
|
32
|
+
│ Main Orchestration │
|
|
33
|
+
│ (analyzeCosts function in api/index.ts) │
|
|
34
|
+
└──────┬─────────┬──────────┬─────────────────┘
|
|
35
|
+
│ │ │
|
|
36
|
+
┌───▼───┐ ┌──▼──┐ ┌────▼────┐ ┌──────────┐
|
|
37
|
+
│Parser │ │Diff │ │Pricing │ │Reporter │
|
|
38
|
+
│ │ │ │ │Service │ │ │
|
|
39
|
+
└───────┘ └─────┘ └────┬────┘ └──────────┘
|
|
40
|
+
│
|
|
41
|
+
┌────▼────┐
|
|
42
|
+
│AWS API │
|
|
43
|
+
└─────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Project Structure
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
cdk-cost-analyzer/
|
|
50
|
+
├── src/
|
|
51
|
+
│ ├── api/ # Programmatic API
|
|
52
|
+
│ ├── cli/ # Command-line interface
|
|
53
|
+
│ ├── diff/ # Template comparison
|
|
54
|
+
│ ├── parser/ # CloudFormation parsing
|
|
55
|
+
│ ├── pricing/ # Cost calculation
|
|
56
|
+
│ │ └── calculators/ # Resource-specific calculators
|
|
57
|
+
│ └── reporter/ # Report formatting
|
|
58
|
+
├── test/ # Mirror structure with tests
|
|
59
|
+
├── dist/ # Built JavaScript (after npm run build)
|
|
60
|
+
├── examples/ # Example CDK projects
|
|
61
|
+
├── docs/ # Documentation
|
|
62
|
+
├── package.json
|
|
63
|
+
├── tsconfig.json
|
|
64
|
+
└── vitest.config.mts
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Module Descriptions
|
|
68
|
+
|
|
69
|
+
### Parser Module (`src/parser/`)
|
|
70
|
+
|
|
71
|
+
Parses CloudFormation templates from JSON or YAML format.
|
|
72
|
+
|
|
73
|
+
**Files**:
|
|
74
|
+
- `TemplateParser.ts`: Main parser implementation
|
|
75
|
+
- `types.ts`: Type definitions for CloudFormation templates
|
|
76
|
+
- `index.ts`: Module exports
|
|
77
|
+
|
|
78
|
+
**Key Features**:
|
|
79
|
+
- Supports both JSON and YAML formats
|
|
80
|
+
- Validates template structure (requires Resources section)
|
|
81
|
+
- Provides detailed error messages for malformed templates
|
|
82
|
+
|
|
83
|
+
### Diff Module (`src/diff/`)
|
|
84
|
+
|
|
85
|
+
Compares two CloudFormation templates and identifies changes.
|
|
86
|
+
|
|
87
|
+
**Files**:
|
|
88
|
+
- `DiffEngine.ts`: Template comparison logic
|
|
89
|
+
- `types.ts`: Type definitions for diff results
|
|
90
|
+
- `index.ts`: Module exports
|
|
91
|
+
|
|
92
|
+
**Key Features**:
|
|
93
|
+
- Identifies added resources (in target, not in base)
|
|
94
|
+
- Identifies removed resources (in base, not in target)
|
|
95
|
+
- Identifies modified resources (properties changed)
|
|
96
|
+
- Deep comparison of nested properties
|
|
97
|
+
|
|
98
|
+
### Pricing Module (`src/pricing/`)
|
|
99
|
+
|
|
100
|
+
Calculates AWS resource costs using the AWS Pricing API.
|
|
101
|
+
|
|
102
|
+
**Files**:
|
|
103
|
+
- `PricingService.ts`: Main service orchestrating cost calculations
|
|
104
|
+
- `PricingClient.ts`: AWS Pricing API client with caching and retry logic
|
|
105
|
+
- `types.ts`: Type definitions for costs and pricing
|
|
106
|
+
- `calculators/*.ts`: Resource-specific cost calculators
|
|
107
|
+
|
|
108
|
+
**Key Features**:
|
|
109
|
+
- Pluggable calculator architecture (easy to add new resource types)
|
|
110
|
+
- Caching to reduce API calls
|
|
111
|
+
- Retry logic with exponential backoff (3 retries)
|
|
112
|
+
- Graceful fallback to cached data on API failures
|
|
113
|
+
- Confidence levels for cost estimates
|
|
114
|
+
- Documented assumptions for usage-based pricing
|
|
115
|
+
|
|
116
|
+
### Reporter Module (`src/reporter/`)
|
|
117
|
+
|
|
118
|
+
Formats cost analysis results for output.
|
|
119
|
+
|
|
120
|
+
**Files**:
|
|
121
|
+
- `Reporter.ts`: Report generation in multiple formats
|
|
122
|
+
- `types.ts`: Type definitions for reporting
|
|
123
|
+
- `index.ts`: Module exports
|
|
124
|
+
|
|
125
|
+
**Key Features**:
|
|
126
|
+
- Text format: Human-readable console output
|
|
127
|
+
- JSON format: Structured data for programmatic use
|
|
128
|
+
- Markdown format: GitLab merge request comments
|
|
129
|
+
- Configuration summary with thresholds and assumptions
|
|
130
|
+
- Multi-stack support with per-stack breakdowns
|
|
131
|
+
- Resources sorted by cost impact
|
|
132
|
+
|
|
133
|
+
### API Module (`src/api/`)
|
|
134
|
+
|
|
135
|
+
Provides programmatic TypeScript/JavaScript API.
|
|
136
|
+
|
|
137
|
+
**Files**:
|
|
138
|
+
- `index.ts`: Main `analyzeCosts` function
|
|
139
|
+
- `types.ts`: Type definitions for API
|
|
140
|
+
|
|
141
|
+
**Key Features**:
|
|
142
|
+
- Simple, promise-based interface
|
|
143
|
+
- Full TypeScript type definitions
|
|
144
|
+
- Error handling with typed exceptions
|
|
145
|
+
- Orchestrates all components
|
|
146
|
+
|
|
147
|
+
### CLI Module (`src/cli/`)
|
|
148
|
+
|
|
149
|
+
Provides command-line interface.
|
|
150
|
+
|
|
151
|
+
**Files**:
|
|
152
|
+
- `index.ts`: CLI implementation using Commander
|
|
153
|
+
|
|
154
|
+
**Key Features**:
|
|
155
|
+
- Template file paths as arguments
|
|
156
|
+
- Region flag (--region, default: eu-central-1)
|
|
157
|
+
- Format flag (--format, default: text)
|
|
158
|
+
- Exit codes: 0 for success, 1 for errors
|
|
159
|
+
|
|
160
|
+
## Data Flow
|
|
161
|
+
|
|
162
|
+
1. **Input**: User provides two CloudFormation templates (base and target)
|
|
163
|
+
2. **Parsing**: Templates are parsed into structured objects
|
|
164
|
+
3. **Diffing**: Templates are compared to identify changes
|
|
165
|
+
4. **Cost Calculation**:
|
|
166
|
+
- For each added/removed/modified resource
|
|
167
|
+
- Calculator is selected based on resource type
|
|
168
|
+
- AWS Pricing API is queried (with caching and retries)
|
|
169
|
+
- Monthly cost is calculated
|
|
170
|
+
5. **Aggregation**: Total cost delta is calculated
|
|
171
|
+
6. **Reporting**: Results are formatted and output
|
|
172
|
+
|
|
173
|
+
## Error Handling Strategy
|
|
174
|
+
|
|
175
|
+
### Input Errors (Fail Fast)
|
|
176
|
+
- Invalid template syntax → TemplateParseError with details
|
|
177
|
+
- Missing Resources section → TemplateParseError
|
|
178
|
+
- Invalid file paths → Error message to stderr, exit code 1
|
|
179
|
+
|
|
180
|
+
### API Errors (Retry with Fallback)
|
|
181
|
+
- Transient failures → Retry up to 3 times with exponential backoff
|
|
182
|
+
- No cached data → PricingAPIError after retries exhausted
|
|
183
|
+
- Cached data available → Use cached data, log warning
|
|
184
|
+
|
|
185
|
+
### Calculation Errors (Graceful Degradation)
|
|
186
|
+
- Unsupported resource type → Mark as "unknown" cost, continue
|
|
187
|
+
- Missing pricing data → Mark as "unknown" confidence, continue
|
|
188
|
+
- Calculator errors → Mark as "unknown" cost, continue
|
|
189
|
+
|
|
190
|
+
## Testing
|
|
191
|
+
|
|
192
|
+
### Running Tests
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Run all tests
|
|
196
|
+
npm run test
|
|
197
|
+
|
|
198
|
+
# Run tests silently (minimal output)
|
|
199
|
+
npm run test:silent
|
|
200
|
+
|
|
201
|
+
# Run tests in watch mode
|
|
202
|
+
npm run test:watch
|
|
203
|
+
|
|
204
|
+
# Run specific test file
|
|
205
|
+
npx vitest run test/parser/TemplateParser.test.ts
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Test Structure
|
|
209
|
+
|
|
210
|
+
- **Unit Tests**: Test specific behaviors and edge cases
|
|
211
|
+
- **Property-Based Tests**: Use fast-check to verify universal properties
|
|
212
|
+
- **Integration Tests**: Test complete workflows
|
|
213
|
+
|
|
214
|
+
### Test Coverage
|
|
215
|
+
|
|
216
|
+
- Parser: 2 test files (13 unit tests + 2 properties)
|
|
217
|
+
- Diff: 2 test files (7 unit tests + 2 properties)
|
|
218
|
+
- Pricing: 3 test files (unit + property + calculator tests)
|
|
219
|
+
- Reporter: 2 test files (10 unit tests + 4 properties)
|
|
220
|
+
- API: 2 test files (6 unit tests + 2 properties)
|
|
221
|
+
- CLI: 1 test file (3 unit tests + property tests)
|
|
222
|
+
|
|
223
|
+
## AWS Credentials Setup
|
|
224
|
+
|
|
225
|
+
The tool requires AWS credentials to query the Pricing API:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# Option 1: Environment variables
|
|
229
|
+
export AWS_ACCESS_KEY_ID=your_access_key
|
|
230
|
+
export AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
231
|
+
|
|
232
|
+
# Option 2: AWS CLI configuration
|
|
233
|
+
aws configure
|
|
234
|
+
|
|
235
|
+
# Option 3: IAM role (when running in AWS)
|
|
236
|
+
# Credentials are automatically available
|
|
237
|
+
|
|
238
|
+
# Verify credentials
|
|
239
|
+
aws sts get-caller-identity --no-cli-pager
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Required IAM permissions:
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"Version": "2012-10-17",
|
|
246
|
+
"Statement": [
|
|
247
|
+
{
|
|
248
|
+
"Effect": "Allow",
|
|
249
|
+
"Action": [
|
|
250
|
+
"pricing:GetProducts"
|
|
251
|
+
],
|
|
252
|
+
"Resource": "*"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Building and Running
|
|
259
|
+
|
|
260
|
+
### Development Build
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Build TypeScript to JavaScript
|
|
264
|
+
npm run build
|
|
265
|
+
|
|
266
|
+
# Watch mode for development
|
|
267
|
+
npm run watch
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### CLI Usage
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Basic usage
|
|
274
|
+
node dist/cli/index.js base.json target.json --region eu-central-1
|
|
275
|
+
|
|
276
|
+
# JSON output
|
|
277
|
+
node dist/cli/index.js base.json target.json --region eu-central-1 --format json
|
|
278
|
+
|
|
279
|
+
# Different region
|
|
280
|
+
node dist/cli/index.js base.json target.json --region us-east-1
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Programmatic Usage
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { analyzeCosts } from 'cdk-cost-analyzer';
|
|
287
|
+
|
|
288
|
+
const result = await analyzeCosts({
|
|
289
|
+
baseTemplate: baseContent,
|
|
290
|
+
targetTemplate: targetContent,
|
|
291
|
+
region: 'eu-central-1',
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
console.log(`Total Delta: ${result.totalDelta.amount}`);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Extensibility
|
|
298
|
+
|
|
299
|
+
### Adding New Resource Types
|
|
300
|
+
|
|
301
|
+
1. Create new calculator in `src/pricing/calculators/`
|
|
302
|
+
2. Implement `ResourceCostCalculator` interface
|
|
303
|
+
3. Register in `PricingService` constructor
|
|
304
|
+
4. Add tests
|
|
305
|
+
|
|
306
|
+
Example:
|
|
307
|
+
```typescript
|
|
308
|
+
export class DynamoDBCalculator implements ResourceCostCalculator {
|
|
309
|
+
supports(resourceType: string): boolean {
|
|
310
|
+
return resourceType === 'AWS::DynamoDB::Table';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async calculateCost(resource, region, pricingClient): Promise<MonthlyCost> {
|
|
314
|
+
// Implementation
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Adding New Report Formats
|
|
320
|
+
|
|
321
|
+
1. Add format to `ReportFormat` type in `src/reporter/types.ts`
|
|
322
|
+
2. Implement format method in `Reporter` class
|
|
323
|
+
3. Add tests
|
|
324
|
+
|
|
325
|
+
## Troubleshooting
|
|
326
|
+
|
|
327
|
+
### Build Errors
|
|
328
|
+
|
|
329
|
+
Check Node.js version (>= 18.0.0):
|
|
330
|
+
```bash
|
|
331
|
+
node --version
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Clear and reinstall dependencies:
|
|
335
|
+
```bash
|
|
336
|
+
rm -rf node_modules package-lock.json
|
|
337
|
+
npm install
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Test Failures
|
|
341
|
+
|
|
342
|
+
Run tests with verbose output:
|
|
343
|
+
```bash
|
|
344
|
+
npx vitest run --reporter=verbose
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Check AWS credentials if pricing tests fail:
|
|
348
|
+
```bash
|
|
349
|
+
aws sts get-caller-identity --no-cli-pager
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Runtime Errors
|
|
353
|
+
|
|
354
|
+
- Verify AWS credentials are configured
|
|
355
|
+
- Check template file paths are correct
|
|
356
|
+
- Ensure region is valid AWS region
|
|
357
|
+
- Review error messages in stderr
|
|
358
|
+
|
|
359
|
+
## Code Quality Standards
|
|
360
|
+
|
|
361
|
+
- TypeScript strict mode enabled
|
|
362
|
+
- No implicit any
|
|
363
|
+
- All functions have return types
|
|
364
|
+
- Comprehensive error handling
|
|
365
|
+
- Descriptive variable names
|
|
366
|
+
- Comments for complex logic
|
|
367
|
+
- Exported interfaces for extensibility
|
|
368
|
+
|
|
369
|
+
## Dependencies
|
|
370
|
+
|
|
371
|
+
### Production
|
|
372
|
+
- `@aws-sdk/client-pricing`: AWS Pricing API client
|
|
373
|
+
- `js-yaml`: YAML template parsing
|
|
374
|
+
- `commander`: CLI argument parsing
|
|
375
|
+
|
|
376
|
+
### Development
|
|
377
|
+
- `typescript`: TypeScript compiler
|
|
378
|
+
- `vitest`: Testing framework
|
|
379
|
+
- `fast-check`: Property-based testing
|
|
380
|
+
- `@types/*`: Type definitions
|
|
381
|
+
|
|
382
|
+
## Additional Resources
|
|
383
|
+
|
|
384
|
+
- [Configuration Guide](./CONFIGURATION.md) - Detailed configuration options
|
|
385
|
+
- [Calculator Reference](./CALCULATORS.md) - Resource calculator documentation
|
|
386
|
+
- [Troubleshooting Guide](./TROUBLESHOOTING.md) - Common issues and solutions
|
|
387
|
+
- [Release Process](./RELEASE.md) - How to release new versions
|
package/docs/RELEASE.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Release Process
|
|
2
|
+
|
|
3
|
+
This document describes the release process for the CDK Cost Analyzer package.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The project uses Projen for package management and GitLab CI/CD for automated releases. Releases are triggered by pushing version tags to the repository.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- Maintainer access to the GitLab repository
|
|
12
|
+
- NPM account with publish permissions (for NPM releases)
|
|
13
|
+
- NPM_TOKEN configured in GitLab CI/CD variables
|
|
14
|
+
|
|
15
|
+
## Release Types
|
|
16
|
+
|
|
17
|
+
Following [Semantic Versioning](https://semver.org/):
|
|
18
|
+
|
|
19
|
+
- **Major (X.0.0)**: Breaking changes to API or CLI
|
|
20
|
+
- **Minor (0.X.0)**: New features, backward compatible
|
|
21
|
+
- **Patch (0.0.X)**: Bug fixes, backward compatible
|
|
22
|
+
|
|
23
|
+
## Automated Release Process
|
|
24
|
+
|
|
25
|
+
### 1. Prepare the Release
|
|
26
|
+
|
|
27
|
+
Ensure all changes are merged to the main branch and all tests pass:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Pull latest changes
|
|
31
|
+
git checkout main
|
|
32
|
+
git pull origin main
|
|
33
|
+
|
|
34
|
+
# Verify tests pass
|
|
35
|
+
npm run test
|
|
36
|
+
|
|
37
|
+
# Verify build succeeds
|
|
38
|
+
npm run build
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Update CHANGELOG.md
|
|
42
|
+
|
|
43
|
+
Update the CHANGELOG.md file with release notes:
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
## [X.Y.Z] - YYYY-MM-DD
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
- New feature descriptions
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Modified functionality descriptions
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
- Bug fix descriptions
|
|
56
|
+
|
|
57
|
+
### Breaking Changes
|
|
58
|
+
- Breaking change descriptions (for major versions)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Commit the changelog:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git add CHANGELOG.md
|
|
65
|
+
git commit -m "docs: update changelog for vX.Y.Z"
|
|
66
|
+
git push origin main
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. Create Version Tag
|
|
70
|
+
|
|
71
|
+
Use Projen to bump the version and create a tag:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# For patch version (1.0.0 -> 1.0.1)
|
|
75
|
+
npm version patch -m "chore: release v%s"
|
|
76
|
+
|
|
77
|
+
# For minor version (1.0.0 -> 1.1.0)
|
|
78
|
+
npm version minor -m "feat: release v%s"
|
|
79
|
+
|
|
80
|
+
# For major version (1.0.0 -> 2.0.0)
|
|
81
|
+
npm version major -m "feat!: release v%s"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This will:
|
|
85
|
+
- Update the version in package.json
|
|
86
|
+
- Create a git commit
|
|
87
|
+
- Create a git tag
|
|
88
|
+
|
|
89
|
+
### 4. Push Tag to Trigger Release
|
|
90
|
+
|
|
91
|
+
Push the tag to GitLab to trigger the release pipeline:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
git push --follow-tags
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 5. Monitor Release Pipeline
|
|
98
|
+
|
|
99
|
+
The GitLab CI/CD pipeline will automatically:
|
|
100
|
+
|
|
101
|
+
1. **Test Stage**: Run all tests and quality gates
|
|
102
|
+
2. **Build Stage**: Compile and package the application
|
|
103
|
+
3. **Release Stage**:
|
|
104
|
+
- Publish to GitLab Package Registry (automatic)
|
|
105
|
+
- Create GitLab Release with release notes (automatic)
|
|
106
|
+
- Publish to NPM (manual approval required)
|
|
107
|
+
|
|
108
|
+
### 6. Approve NPM Publication
|
|
109
|
+
|
|
110
|
+
Navigate to the GitLab pipeline and manually approve the `publish:npm` job to publish to the NPM registry.
|
|
111
|
+
|
|
112
|
+
## Manual Release Process
|
|
113
|
+
|
|
114
|
+
If automated release fails, you can publish manually:
|
|
115
|
+
|
|
116
|
+
### Publish to NPM
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Build the package
|
|
120
|
+
npm run build
|
|
121
|
+
|
|
122
|
+
# Login to NPM
|
|
123
|
+
npm login
|
|
124
|
+
|
|
125
|
+
# Publish
|
|
126
|
+
npm publish --access public
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Publish to GitLab Package Registry
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Configure GitLab Package Registry
|
|
133
|
+
echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}" > .npmrc
|
|
134
|
+
|
|
135
|
+
# Publish
|
|
136
|
+
npm publish
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Post-Release Tasks
|
|
140
|
+
|
|
141
|
+
1. Verify the package is available on NPM: https://www.npmjs.com/package/cdk-cost-analyzer
|
|
142
|
+
2. Verify the GitLab release was created: Project → Releases
|
|
143
|
+
3. Test installation: `npm install -g cdk-cost-analyzer@X.Y.Z`
|
|
144
|
+
4. Announce the release in relevant channels
|
|
145
|
+
|
|
146
|
+
## Rollback
|
|
147
|
+
|
|
148
|
+
If a release has critical issues:
|
|
149
|
+
|
|
150
|
+
1. Deprecate the problematic version on NPM:
|
|
151
|
+
```bash
|
|
152
|
+
npm deprecate cdk-cost-analyzer@X.Y.Z "Critical bug, use vX.Y.Z+1 instead"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
2. Create a hotfix release with the fix
|
|
156
|
+
|
|
157
|
+
3. Publish the hotfix following the normal release process
|
|
158
|
+
|
|
159
|
+
## Troubleshooting
|
|
160
|
+
|
|
161
|
+
### Pipeline Fails at Test Stage
|
|
162
|
+
|
|
163
|
+
- Review test failures in the pipeline logs
|
|
164
|
+
- Fix issues locally and push fixes
|
|
165
|
+
- Create a new tag after fixes are merged
|
|
166
|
+
|
|
167
|
+
### Pipeline Fails at Build Stage
|
|
168
|
+
|
|
169
|
+
- Check compilation errors in the pipeline logs
|
|
170
|
+
- Verify TypeScript configuration
|
|
171
|
+
- Ensure all dependencies are correctly specified
|
|
172
|
+
|
|
173
|
+
### NPM Publish Fails
|
|
174
|
+
|
|
175
|
+
- Verify NPM_TOKEN is configured in GitLab CI/CD variables
|
|
176
|
+
- Check NPM account has publish permissions
|
|
177
|
+
- Verify package name is not already taken
|
|
178
|
+
- Check for version conflicts
|
|
179
|
+
|
|
180
|
+
### GitLab Package Registry Publish Fails
|
|
181
|
+
|
|
182
|
+
- Verify CI_JOB_TOKEN has correct permissions
|
|
183
|
+
- Check GitLab Package Registry is enabled for the project
|
|
184
|
+
- Verify package name follows GitLab naming conventions
|
|
185
|
+
|
|
186
|
+
## Configuration
|
|
187
|
+
|
|
188
|
+
### GitLab CI/CD Variables
|
|
189
|
+
|
|
190
|
+
Required variables for automated releases:
|
|
191
|
+
|
|
192
|
+
- `NPM_TOKEN`: NPM authentication token for publishing
|
|
193
|
+
- Scope: Protected
|
|
194
|
+
- Masked: Yes
|
|
195
|
+
- Environment: All
|
|
196
|
+
|
|
197
|
+
### NPM Token Setup
|
|
198
|
+
|
|
199
|
+
1. Login to NPM: https://www.npmjs.com/
|
|
200
|
+
2. Navigate to Access Tokens
|
|
201
|
+
3. Generate new token with "Automation" type
|
|
202
|
+
4. Add token to GitLab CI/CD variables as `NPM_TOKEN`
|
|
203
|
+
|
|
204
|
+
## Version Numbering Guidelines
|
|
205
|
+
|
|
206
|
+
- Use semantic versioning strictly
|
|
207
|
+
- Breaking changes require major version bump
|
|
208
|
+
- New features require minor version bump
|
|
209
|
+
- Bug fixes require patch version bump
|
|
210
|
+
- Pre-release versions: `X.Y.Z-beta.N`, `X.Y.Z-rc.N`
|
|
211
|
+
|
|
212
|
+
## Release Checklist
|
|
213
|
+
|
|
214
|
+
- [ ] All tests pass locally
|
|
215
|
+
- [ ] CHANGELOG.md updated
|
|
216
|
+
- [ ] Version bumped appropriately
|
|
217
|
+
- [ ] Tag created and pushed
|
|
218
|
+
- [ ] Pipeline completed successfully
|
|
219
|
+
- [ ] NPM publication approved (if applicable)
|
|
220
|
+
- [ ] Package verified on NPM
|
|
221
|
+
- [ ] GitLab release created
|
|
222
|
+
- [ ] Installation tested
|
|
223
|
+
- [ ] Release announced
|