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.
Files changed (228) hide show
  1. package/.cdk-cost-analyzer-cache/metadata.json +12 -0
  2. package/.gitlab-ci.yml +214 -0
  3. package/.husky/pre-commit +12 -0
  4. package/.kiro/hooks/accessibility-audit.kiro.hook +18 -0
  5. package/.kiro/hooks/api-schema-validation.kiro.hook +21 -0
  6. package/.kiro/hooks/auto-test-on-save.kiro.hook +19 -0
  7. package/.kiro/hooks/cdk-synth-on-change.kiro.hook +20 -0
  8. package/.kiro/hooks/code-coverage-check.kiro.hook +14 -0
  9. package/.kiro/hooks/commit-message-helper.kiro.hook +14 -0
  10. package/.kiro/hooks/dependency-update-check.kiro.hook +14 -0
  11. package/.kiro/hooks/env-file-validation.kiro.hook +18 -0
  12. package/.kiro/hooks/lint-and-format-on-save.kiro.hook +21 -0
  13. package/.kiro/hooks/mcp-config-validation.kiro.hook +17 -0
  14. package/.kiro/hooks/mcp-server-test.kiro.hook +14 -0
  15. package/.kiro/hooks/performance-analysis.kiro.hook +14 -0
  16. package/.kiro/hooks/readme-spell-check.kiro.hook +14 -0
  17. package/.kiro/hooks/security-scan-on-dependency-change.kiro.hook +21 -0
  18. package/.kiro/hooks/translation-update.kiro.hook +18 -0
  19. package/.kiro/hooks/update-documentation.kiro.hook +18 -0
  20. package/.kiro/settings/mcp.json +20 -0
  21. package/.kiro/specs/cdk-cost-analyzer/design.md +620 -0
  22. package/.kiro/specs/cdk-cost-analyzer/requirements.md +183 -0
  23. package/.kiro/specs/cdk-cost-analyzer/tasks.md +357 -0
  24. package/.kiro/specs/github-actions-ci/design.md +281 -0
  25. package/.kiro/specs/github-actions-ci/requirements.md +86 -0
  26. package/.kiro/specs/github-actions-ci/tasks.md +115 -0
  27. package/.kiro/specs/nlb-calculator-test-coverage/design.md +190 -0
  28. package/.kiro/specs/nlb-calculator-test-coverage/requirements.md +84 -0
  29. package/.kiro/specs/nlb-calculator-test-coverage/tasks.md +150 -0
  30. package/.kiro/specs/production-readiness/design.md +1213 -0
  31. package/.kiro/specs/production-readiness/requirements.md +312 -0
  32. package/.kiro/specs/production-readiness/tasks.md +269 -0
  33. package/.kiro/specs/repository-cleanup/design.md +283 -0
  34. package/.kiro/specs/repository-cleanup/requirements.md +74 -0
  35. package/.kiro/specs/repository-cleanup/tasks.md +64 -0
  36. package/.kiro/steering/aws-cli-best-practices.md +41 -0
  37. package/.kiro/steering/cdk-best-practices.md +49 -0
  38. package/.kiro/steering/development-standards.md +54 -0
  39. package/.kiro/steering/docker-best-practices.md +34 -0
  40. package/.kiro/steering/documentation-style.md +151 -0
  41. package/.kiro/steering/git-best-practices.md +37 -0
  42. package/.kiro/steering/mcp-best-practices.md +95 -0
  43. package/.kiro/steering/python-best-practices.md +48 -0
  44. package/.kiro/steering/react-best-practices.md +44 -0
  45. package/.kiro/steering/security-best-practices.md +41 -0
  46. package/.kiro/steering/testing-best-practices.md +59 -0
  47. package/.kiro/steering/typescript-best-practices.md +40 -0
  48. package/CHANGELOG.md +49 -0
  49. package/CONTRIBUTING.md +258 -0
  50. package/LICENSE +19 -0
  51. package/README.md +480 -0
  52. package/SECURITY.md +117 -0
  53. package/dist/api/index.d.ts +11 -0
  54. package/dist/api/index.js +65 -0
  55. package/dist/api/types.d.ts +15 -0
  56. package/dist/api/types.js +3 -0
  57. package/dist/cli/index.d.ts +2 -0
  58. package/dist/cli/index.js +262 -0
  59. package/dist/config/ConfigManager.d.ts +40 -0
  60. package/dist/config/ConfigManager.js +238 -0
  61. package/dist/config/index.d.ts +2 -0
  62. package/dist/config/index.js +19 -0
  63. package/dist/config/types.d.ts +72 -0
  64. package/dist/config/types.js +15 -0
  65. package/dist/diff/DiffEngine.d.ts +7 -0
  66. package/dist/diff/DiffEngine.js +73 -0
  67. package/dist/diff/index.d.ts +2 -0
  68. package/dist/diff/index.js +21 -0
  69. package/dist/diff/types.d.ts +20 -0
  70. package/dist/diff/types.js +3 -0
  71. package/dist/integrations/GitLabIntegration.d.ts +7 -0
  72. package/dist/integrations/GitLabIntegration.js +45 -0
  73. package/dist/integrations/index.d.ts +2 -0
  74. package/dist/integrations/index.js +21 -0
  75. package/dist/integrations/types.d.ts +11 -0
  76. package/dist/integrations/types.js +13 -0
  77. package/dist/parser/TemplateParser.d.ts +8 -0
  78. package/dist/parser/TemplateParser.js +75 -0
  79. package/dist/parser/index.d.ts +2 -0
  80. package/dist/parser/index.js +22 -0
  81. package/dist/parser/types.d.ts +30 -0
  82. package/dist/parser/types.js +3 -0
  83. package/dist/pipeline/PipelineOrchestrator.d.ts +23 -0
  84. package/dist/pipeline/PipelineOrchestrator.js +191 -0
  85. package/dist/pipeline/index.d.ts +2 -0
  86. package/dist/pipeline/index.js +19 -0
  87. package/dist/pipeline/types.d.ts +41 -0
  88. package/dist/pipeline/types.js +13 -0
  89. package/dist/pricing/CacheManager.d.ts +75 -0
  90. package/dist/pricing/CacheManager.js +195 -0
  91. package/dist/pricing/PricingClient.d.ts +17 -0
  92. package/dist/pricing/PricingClient.js +122 -0
  93. package/dist/pricing/PricingService.d.ts +16 -0
  94. package/dist/pricing/PricingService.js +149 -0
  95. package/dist/pricing/calculators/ALBCalculator.d.ts +16 -0
  96. package/dist/pricing/calculators/ALBCalculator.js +163 -0
  97. package/dist/pricing/calculators/APIGatewayCalculator.d.ts +10 -0
  98. package/dist/pricing/calculators/APIGatewayCalculator.js +177 -0
  99. package/dist/pricing/calculators/CloudFrontCalculator.d.ts +59 -0
  100. package/dist/pricing/calculators/CloudFrontCalculator.js +151 -0
  101. package/dist/pricing/calculators/DynamoDBCalculator.d.ts +9 -0
  102. package/dist/pricing/calculators/DynamoDBCalculator.js +146 -0
  103. package/dist/pricing/calculators/EC2Calculator.d.ts +7 -0
  104. package/dist/pricing/calculators/EC2Calculator.js +80 -0
  105. package/dist/pricing/calculators/ECSCalculator.d.ts +9 -0
  106. package/dist/pricing/calculators/ECSCalculator.js +116 -0
  107. package/dist/pricing/calculators/ElastiCacheCalculator.d.ts +8 -0
  108. package/dist/pricing/calculators/ElastiCacheCalculator.js +106 -0
  109. package/dist/pricing/calculators/LambdaCalculator.d.ts +13 -0
  110. package/dist/pricing/calculators/LambdaCalculator.js +111 -0
  111. package/dist/pricing/calculators/NLBCalculator.d.ts +16 -0
  112. package/dist/pricing/calculators/NLBCalculator.js +138 -0
  113. package/dist/pricing/calculators/NatGatewayCalculator.d.ts +12 -0
  114. package/dist/pricing/calculators/NatGatewayCalculator.js +116 -0
  115. package/dist/pricing/calculators/RDSCalculator.d.ts +9 -0
  116. package/dist/pricing/calculators/RDSCalculator.js +103 -0
  117. package/dist/pricing/calculators/S3Calculator.d.ts +8 -0
  118. package/dist/pricing/calculators/S3Calculator.js +68 -0
  119. package/dist/pricing/calculators/VPCEndpointCalculator.d.ts +12 -0
  120. package/dist/pricing/calculators/VPCEndpointCalculator.js +129 -0
  121. package/dist/pricing/index.d.ts +10 -0
  122. package/dist/pricing/index.js +37 -0
  123. package/dist/pricing/types.d.ts +53 -0
  124. package/dist/pricing/types.js +22 -0
  125. package/dist/releasetag.txt +1 -0
  126. package/dist/reporter/Reporter.d.ts +18 -0
  127. package/dist/reporter/Reporter.js +412 -0
  128. package/dist/reporter/index.d.ts +2 -0
  129. package/dist/reporter/index.js +21 -0
  130. package/dist/reporter/types.d.ts +72 -0
  131. package/dist/reporter/types.js +3 -0
  132. package/dist/synthesis/SynthesisOrchestrator.d.ts +26 -0
  133. package/dist/synthesis/SynthesisOrchestrator.js +243 -0
  134. package/dist/synthesis/index.d.ts +2 -0
  135. package/dist/synthesis/index.js +19 -0
  136. package/dist/synthesis/types.d.ts +17 -0
  137. package/dist/synthesis/types.js +13 -0
  138. package/dist/threshold/ThresholdEnforcer.d.ts +29 -0
  139. package/dist/threshold/ThresholdEnforcer.js +143 -0
  140. package/dist/threshold/index.d.ts +2 -0
  141. package/dist/threshold/index.js +19 -0
  142. package/dist/threshold/types.d.ts +15 -0
  143. package/dist/threshold/types.js +17 -0
  144. package/docs/CALCULATORS.md +820 -0
  145. package/docs/CI_CD.md +608 -0
  146. package/docs/CONFIGURATION.md +407 -0
  147. package/docs/DEVELOPMENT.md +387 -0
  148. package/docs/RELEASE.md +223 -0
  149. package/docs/TROUBLESHOOTING.md +847 -0
  150. package/examples/.cdk-cost-analyzer.yml +85 -0
  151. package/examples/.gitlab-ci.yml +125 -0
  152. package/examples/api-usage.js +26 -0
  153. package/examples/complex/base.json +16 -0
  154. package/examples/complex/target.json +29 -0
  155. package/examples/monorepo/.gitlab-ci.yml +251 -0
  156. package/examples/monorepo/README.md +341 -0
  157. package/examples/monorepo/package.json +27 -0
  158. package/examples/monorepo/packages/backend-infra/.cdk-cost-analyzer.yml +34 -0
  159. package/examples/monorepo/packages/backend-infra/bin/app.ts +16 -0
  160. package/examples/monorepo/packages/backend-infra/cdk.json +7 -0
  161. package/examples/monorepo/packages/backend-infra/lib/backend-stack.ts +128 -0
  162. package/examples/monorepo/packages/backend-infra/package.json +30 -0
  163. package/examples/monorepo/packages/backend-infra/tsconfig.json +11 -0
  164. package/examples/monorepo/packages/data-infra/.cdk-cost-analyzer.yml +38 -0
  165. package/examples/monorepo/packages/data-infra/bin/app.ts +16 -0
  166. package/examples/monorepo/packages/data-infra/cdk.json +7 -0
  167. package/examples/monorepo/packages/data-infra/lib/data-stack.ts +121 -0
  168. package/examples/monorepo/packages/data-infra/package.json +30 -0
  169. package/examples/monorepo/packages/data-infra/tsconfig.json +11 -0
  170. package/examples/monorepo/packages/frontend-infra/.cdk-cost-analyzer.yml +31 -0
  171. package/examples/monorepo/packages/frontend-infra/bin/app.ts +16 -0
  172. package/examples/monorepo/packages/frontend-infra/cdk.json +7 -0
  173. package/examples/monorepo/packages/frontend-infra/lib/frontend-stack.ts +60 -0
  174. package/examples/monorepo/packages/frontend-infra/package.json +30 -0
  175. package/examples/monorepo/packages/frontend-infra/tsconfig.json +11 -0
  176. package/examples/monorepo/tsconfig.json +35 -0
  177. package/examples/multi-stack/.cdk-cost-analyzer.yml +72 -0
  178. package/examples/multi-stack/.gitlab-ci.yml +184 -0
  179. package/examples/multi-stack/README.md +279 -0
  180. package/examples/multi-stack/bin/app.ts +36 -0
  181. package/examples/multi-stack/cdk.json +72 -0
  182. package/examples/multi-stack/lib/compute-stack.ts +128 -0
  183. package/examples/multi-stack/lib/networking-stack.ts +69 -0
  184. package/examples/multi-stack/lib/storage-stack.ts +141 -0
  185. package/examples/multi-stack/package-lock.json +4437 -0
  186. package/examples/multi-stack/package.json +42 -0
  187. package/examples/multi-stack/tsconfig.json +34 -0
  188. package/examples/simple/base.json +8 -0
  189. package/examples/simple/target.json +14 -0
  190. package/examples/single-stack/.NVP +0 -0
  191. package/examples/single-stack/.cdk-cost-analyzer.yml +52 -0
  192. package/examples/single-stack/.gitlab-ci.yml +126 -0
  193. package/examples/single-stack/README.md +184 -0
  194. package/examples/single-stack/UeK +0 -0
  195. package/examples/single-stack/bin/app.ts +16 -0
  196. package/examples/single-stack/cdk.json +72 -0
  197. package/examples/single-stack/lib/infrastructure-stack.ts +119 -0
  198. package/examples/single-stack/package-lock.json +4443 -0
  199. package/examples/single-stack/package.json +38 -0
  200. package/examples/single-stack/tsconfig.json +34 -0
  201. package/package.json +139 -0
  202. package/test-cdk-project/README-COMPUTE.md +141 -0
  203. package/test-cdk-project/README.md +95 -0
  204. package/test-cdk-project/app-with-compute.js +102 -0
  205. package/test-cdk-project/app.js +81 -0
  206. package/test-cdk-project/cdk-compute.json +3 -0
  207. package/test-cdk-project/cdk.context.json +7 -0
  208. package/test-cdk-project/cdk.json +3 -0
  209. package/test-cdk-project/cdk.out/TestStack.assets.json +21 -0
  210. package/test-cdk-project/cdk.out/TestStack.template.json +115 -0
  211. package/test-cdk-project/cdk.out/cdk.out +1 -0
  212. package/test-cdk-project/cdk.out/manifest.json +503 -0
  213. package/test-cdk-project/cdk.out/tree.json +1 -0
  214. package/test-cdk-project/cdk.out.base/TestStack.assets.json +21 -0
  215. package/test-cdk-project/cdk.out.base/TestStack.template.json +115 -0
  216. package/test-cdk-project/cdk.out.base/cdk.out +1 -0
  217. package/test-cdk-project/cdk.out.base/manifest.json +503 -0
  218. package/test-cdk-project/cdk.out.base/tree.json +1 -0
  219. package/test-cdk-project/cdk.out.target/TestStack.assets.json +21 -0
  220. package/test-cdk-project/cdk.out.target/TestStack.template.json +183 -0
  221. package/test-cdk-project/cdk.out.target/cdk.out +1 -0
  222. package/test-cdk-project/cdk.out.target/manifest.json +521 -0
  223. package/test-cdk-project/cdk.out.target/tree.json +1 -0
  224. package/test-cdk-project/package-lock.json +422 -0
  225. package/test-cdk-project/package.json +17 -0
  226. package/tools/workflows/README.md +102 -0
  227. package/tools/workflows/validate-workflows.js +109 -0
  228. package/tools/workflows/workflow-utils.ts +181 -0
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "cdk-cost-analyzer-single-stack-example",
3
+ "version": "1.0.0",
4
+ "description": "Single-stack CDK application example with cost analysis",
5
+ "bin": {
6
+ "single-stack": "bin/app.js"
7
+ },
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "watch": "tsc -w",
11
+ "test": "jest",
12
+ "cdk": "cdk",
13
+ "synth": "cdk synth",
14
+ "deploy": "cdk deploy",
15
+ "diff": "cdk diff"
16
+ },
17
+ "keywords": [
18
+ "aws",
19
+ "cdk",
20
+ "cost-analysis",
21
+ "example"
22
+ ],
23
+ "author": "ANWB",
24
+ "license": "MIT",
25
+ "devDependencies": {
26
+ "@types/jest": "^29.5.14",
27
+ "@types/node": "^22.10.2",
28
+ "aws-cdk": "^2.1100.2",
29
+ "jest": "^29.7.0",
30
+ "ts-jest": "^29.2.5",
31
+ "ts-node": "^10.9.2",
32
+ "typescript": "^5.7.2"
33
+ },
34
+ "dependencies": {
35
+ "aws-cdk-lib": "^2.233.0",
36
+ "constructs": "^10.4.2"
37
+ }
38
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": [
6
+ "es2020"
7
+ ],
8
+ "declaration": true,
9
+ "strict": true,
10
+ "noImplicitAny": true,
11
+ "strictNullChecks": true,
12
+ "noImplicitThis": true,
13
+ "alwaysStrict": true,
14
+ "noUnusedLocals": false,
15
+ "noUnusedParameters": false,
16
+ "noImplicitReturns": true,
17
+ "noFallthroughCasesInSwitch": false,
18
+ "inlineSourceMap": true,
19
+ "inlineSources": true,
20
+ "experimentalDecorators": true,
21
+ "strictPropertyInitialization": false,
22
+ "typeRoots": [
23
+ "./node_modules/@types"
24
+ ],
25
+ "esModuleInterop": true,
26
+ "skipLibCheck": true,
27
+ "forceConsistentCasingInFileNames": true,
28
+ "resolveJsonModule": true
29
+ },
30
+ "exclude": [
31
+ "node_modules",
32
+ "cdk.out"
33
+ ]
34
+ }
package/package.json ADDED
@@ -0,0 +1,139 @@
1
+ {
2
+ "name": "cdk-cost-analyzer",
3
+ "description": "Analyze AWS CDK infrastructure changes and provide cost impact summaries",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/buildinginthecloud/cdk-cost-analyzer.git"
7
+ },
8
+ "bin": {
9
+ "cdk-cost-analyzer": "dist/cli/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "npx projen build",
13
+ "bump": "npx projen bump",
14
+ "ci:local": "npx projen ci:local",
15
+ "clobber": "npx projen clobber",
16
+ "compile": "npx projen compile",
17
+ "default": "npx projen default",
18
+ "eject": "npx projen eject",
19
+ "eslint": "npx projen eslint",
20
+ "install:act": "npx projen install:act",
21
+ "lint": "npx projen lint",
22
+ "package": "npx projen package",
23
+ "post-compile": "npx projen post-compile",
24
+ "post-upgrade": "npx projen post-upgrade",
25
+ "pre-compile": "npx projen pre-compile",
26
+ "prepare": "npx projen prepare",
27
+ "release": "npx projen release",
28
+ "test": "npx projen test",
29
+ "test:silent": "npx projen test:silent",
30
+ "test:watch": "npx projen test:watch",
31
+ "unbump": "npx projen unbump",
32
+ "upgrade": "npx projen upgrade",
33
+ "validate:workflows": "npx projen validate:workflows",
34
+ "watch": "npx projen watch",
35
+ "projen": "npx projen"
36
+ },
37
+ "author": {
38
+ "name": "Yvo van Zee",
39
+ "email": "yvo@buildinginthecloud.com",
40
+ "organization": false
41
+ },
42
+ "devDependencies": {
43
+ "@stylistic/eslint-plugin": "^2",
44
+ "@types/jest": "^30.0.0",
45
+ "@types/js-yaml": "^4.0.9",
46
+ "@types/node": "^22.10.1",
47
+ "@typescript-eslint/eslint-plugin": "^8",
48
+ "@typescript-eslint/parser": "^8",
49
+ "commit-and-tag-version": "^12",
50
+ "constructs": "^10.0.0",
51
+ "eslint": "^9",
52
+ "eslint-import-resolver-typescript": "^4.4.4",
53
+ "eslint-plugin-import": "^2.32.0",
54
+ "fast-check": "^3.23.1",
55
+ "husky": "^9.0.0",
56
+ "jest": "^30.2.0",
57
+ "jest-junit": "^16",
58
+ "lint-staged": "^15.0.0",
59
+ "projen": "^0.98.28",
60
+ "ts-jest": "^29.4.6",
61
+ "ts-node": "^10.9.2",
62
+ "typescript": "^5.7.2"
63
+ },
64
+ "dependencies": {
65
+ "@aws-sdk/client-pricing": "^3.705.0",
66
+ "commander": "^12.1.0",
67
+ "js-yaml": "^4.1.0"
68
+ },
69
+ "keywords": [
70
+ "analysis",
71
+ "aws",
72
+ "cdk",
73
+ "cloudformation",
74
+ "cost"
75
+ ],
76
+ "engines": {
77
+ "node": ">= 20.0.0"
78
+ },
79
+ "main": "dist/api/index.js",
80
+ "license": "MIT",
81
+ "homepage": "https://github.com/buildinginthecloud/cdk-cost-analyzer",
82
+ "publishConfig": {
83
+ "access": "public"
84
+ },
85
+ "version": "0.1.1",
86
+ "bugs": {
87
+ "url": "https://github.com/buildinginthecloud/cdk-cost-analyzer/issues"
88
+ },
89
+ "jest": {
90
+ "coverageProvider": "v8",
91
+ "testTimeout": 30000,
92
+ "forceExit": true,
93
+ "detectOpenHandles": true,
94
+ "testMatch": [
95
+ "<rootDir>/@(src|test)/**/*(*.)@(spec|test).ts?(x)",
96
+ "<rootDir>/@(src|test)/**/__tests__/**/*.ts?(x)",
97
+ "<rootDir>/@(projenrc)/**/*(*.)@(spec|test).ts?(x)",
98
+ "<rootDir>/@(projenrc)/**/__tests__/**/*.ts?(x)"
99
+ ],
100
+ "clearMocks": true,
101
+ "collectCoverage": true,
102
+ "coverageReporters": [
103
+ "json",
104
+ "lcov",
105
+ "clover",
106
+ "cobertura",
107
+ "text"
108
+ ],
109
+ "coverageDirectory": "coverage",
110
+ "coveragePathIgnorePatterns": [
111
+ "/node_modules/"
112
+ ],
113
+ "testPathIgnorePatterns": [
114
+ "/node_modules/"
115
+ ],
116
+ "watchPathIgnorePatterns": [
117
+ "/node_modules/"
118
+ ],
119
+ "reporters": [
120
+ "default",
121
+ [
122
+ "jest-junit",
123
+ {
124
+ "outputDirectory": "test-reports"
125
+ }
126
+ ]
127
+ ],
128
+ "transform": {
129
+ "^.+\\.[t]sx?$": [
130
+ "ts-jest",
131
+ {
132
+ "tsconfig": "tsconfig.dev.json"
133
+ }
134
+ ]
135
+ }
136
+ },
137
+ "types": "dist/api/index.d.ts",
138
+ "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
139
+ }
@@ -0,0 +1,141 @@
1
+ # CDK Cost Analyzer - EC2 & RDS Test
2
+
3
+ This test demonstrates the CDK Cost Analyzer with compute resources (EC2 and RDS).
4
+
5
+ ## Test Scenario
6
+
7
+ ### Base Stack (Current)
8
+ - S3 Bucket
9
+ - Lambda Function (128MB)
10
+
11
+ ### Target Stack (Proposed)
12
+ - S3 Bucket (unchanged)
13
+ - Lambda Function (512MB) - **MODIFIED**
14
+ - VPC with public and isolated subnets - **NEW**
15
+ - EC2 Instance (t3.medium) - **NEW**
16
+ - RDS PostgreSQL Database (db.t3.micro) - **NEW**
17
+
18
+ ## Cost Analysis Results
19
+
20
+ ```
21
+ Total Cost Delta: +$69.62/month
22
+
23
+ Key Resources:
24
+ - EC2 t3.medium: $36.43/month
25
+ - RDS db.t3.micro (PostgreSQL): $26.94/month
26
+ - Lambda upgrade (128MB → 512MB): +$6.25/month
27
+
28
+ Supporting Infrastructure (no direct cost):
29
+ - VPC, Subnets, Route Tables, Internet Gateway
30
+ - Security Groups, IAM Roles
31
+ - RDS Subnet Group, Secrets Manager
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### Synthesize Templates
37
+
38
+ ```bash
39
+ # Base stack
40
+ AWS_PROFILE=dev npx cdk synth \
41
+ -a "node app-with-compute.js" \
42
+ -c stack=base \
43
+ -o cdk.out.compute.base
44
+
45
+ # Target stack
46
+ AWS_PROFILE=dev npx cdk synth \
47
+ -a "node app-with-compute.js" \
48
+ -c stack=target \
49
+ -o cdk.out.compute.target
50
+ ```
51
+
52
+ ### Analyze Costs
53
+
54
+ ```bash
55
+ # Text format
56
+ AWS_PROFILE=dev node ../dist/cli/index.js \
57
+ cdk.out.compute.base/ComputeStack.template.json \
58
+ cdk.out.compute.target/ComputeStack.template.json \
59
+ --region eu-central-1
60
+
61
+ # Markdown format (for GitLab MR)
62
+ AWS_PROFILE=dev node ../dist/cli/index.js \
63
+ cdk.out.compute.base/ComputeStack.template.json \
64
+ cdk.out.compute.target/ComputeStack.template.json \
65
+ --region eu-central-1 \
66
+ --format markdown
67
+ ```
68
+
69
+ ## Key Insights
70
+
71
+ ### Costs Calculated
72
+ ✅ **EC2 Instance**: Accurate monthly cost based on instance type and region
73
+ ✅ **RDS Database**: Accurate monthly cost including instance and storage
74
+ ✅ **Lambda Functions**: Cost based on memory allocation and default assumptions
75
+
76
+ ### Resources Identified (No Direct Cost)
77
+ - VPC and networking components (subnets, route tables, IGW)
78
+ - Security groups and IAM roles
79
+ - RDS subnet groups
80
+ - Secrets Manager secrets
81
+
82
+ ### Cost Assumptions
83
+ - **EC2**: 730 hours/month (24/7), on-demand pricing, Linux OS
84
+ - **RDS**: 730 hours/month, 20GB storage, single-AZ, PostgreSQL 15
85
+ - **Lambda**: 1M invocations/month, 1s average duration
86
+
87
+ ## Real-World Application
88
+
89
+ This demonstrates how the tool would work in a typical infrastructure change:
90
+
91
+ 1. **Developer proposes changes** in a merge request
92
+ 2. **CI/CD pipeline synthesizes** both base and target CDK stacks
93
+ 3. **Cost analyzer runs** and generates a report
94
+ 4. **Report is posted** as a comment on the GitLab MR
95
+ 5. **Team reviews** the cost impact before approving
96
+
97
+ ## Example GitLab CI/CD Integration
98
+
99
+ ```yaml
100
+ cost-analysis:
101
+ stage: validate
102
+ image: node:18
103
+ before_script:
104
+ - npm install -g aws-cdk cdk-cost-analyzer
105
+ script:
106
+ # Synthesize current main branch
107
+ - git fetch origin main
108
+ - git checkout origin/main
109
+ - cdk synth -o cdk.out.base
110
+
111
+ # Synthesize MR branch
112
+ - git checkout $CI_COMMIT_SHA
113
+ - cdk synth -o cdk.out.target
114
+
115
+ # Analyze cost difference
116
+ - |
117
+ cdk-cost-analyzer \
118
+ cdk.out.base/YourStack.template.json \
119
+ cdk.out.target/YourStack.template.json \
120
+ --region eu-central-1 \
121
+ --format markdown > cost-report.md
122
+
123
+ # Post to MR (using GitLab API)
124
+ - |
125
+ curl --request POST \
126
+ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
127
+ --data-urlencode "body@cost-report.md" \
128
+ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"
129
+ only:
130
+ - merge_requests
131
+ variables:
132
+ AWS_REGION: eu-central-1
133
+ ```
134
+
135
+ ## Benefits
136
+
137
+ 1. **Early Cost Visibility**: See cost impact before deployment
138
+ 2. **Informed Decisions**: Team can discuss expensive changes
139
+ 3. **Cost Optimization**: Identify opportunities to reduce costs
140
+ 4. **Compliance**: Ensure changes stay within budget constraints
141
+ 5. **Documentation**: Automatic cost documentation in MR history
@@ -0,0 +1,95 @@
1
+ # CDK Cost Analyzer - Test Project
2
+
3
+ This is a test CDK project to demonstrate the CDK Cost Analyzer functionality.
4
+
5
+ ## Project Structure
6
+
7
+ - `app.js` - CDK application with two stacks (base and target)
8
+ - `cdk.out.base/` - Synthesized CloudFormation template for base stack
9
+ - `cdk.out.target/` - Synthesized CloudFormation template for target stack
10
+
11
+ ## Stacks
12
+
13
+ ### Base Stack (Current Infrastructure)
14
+ - S3 Bucket
15
+ - Lambda Function (128MB memory)
16
+
17
+ ### Target Stack (Proposed Changes)
18
+ - S3 Bucket (unchanged)
19
+ - Lambda Function (upgraded to 512MB) - **MODIFIED**
20
+ - New Lambda Function (256MB) - **NEW**
21
+ - New S3 Bucket - **NEW**
22
+
23
+ ## Usage
24
+
25
+ ### 1. Synthesize CDK Templates
26
+
27
+ ```bash
28
+ # Synthesize base stack
29
+ AWS_PROFILE=dev npx cdk synth -c stack=base -o cdk.out.base --quiet
30
+
31
+ # Synthesize target stack
32
+ AWS_PROFILE=dev npx cdk synth -c stack=target -o cdk.out.target --quiet
33
+ ```
34
+
35
+ ### 2. Analyze Cost Impact
36
+
37
+ ```bash
38
+ # From the parent directory
39
+ AWS_PROFILE=dev node dist/cli/index.js \
40
+ test-cdk-project/cdk.out.base/TestStack.template.json \
41
+ test-cdk-project/cdk.out.target/TestStack.template.json \
42
+ --region eu-central-1
43
+ ```
44
+
45
+ ### 3. Get Markdown Output (for GitLab MR)
46
+
47
+ ```bash
48
+ AWS_PROFILE=dev node dist/cli/index.js \
49
+ test-cdk-project/cdk.out.base/TestStack.template.json \
50
+ test-cdk-project/cdk.out.target/TestStack.template.json \
51
+ --region eu-central-1 \
52
+ --format markdown
53
+ ```
54
+
55
+ ## Expected Results
56
+
57
+ ```
58
+ Total Cost Delta: +$12.82/month
59
+
60
+ Added Resources:
61
+ - MyNewFunction: $4.17/month (Lambda 256MB)
62
+ - MyNewBucket: $2.40/month (S3 bucket)
63
+
64
+ Modified Resources:
65
+ - MyFunction: $2.08 → $8.33 (+$6.25) (Lambda 128MB → 512MB)
66
+ ```
67
+
68
+ ## Integration with GitLab CI/CD
69
+
70
+ You can integrate this into your GitLab pipeline:
71
+
72
+ ```yaml
73
+ cost-analysis:
74
+ stage: validate
75
+ script:
76
+ - npm install -g cdk-cost-analyzer
77
+ - cdk synth -c stack=base -o cdk.out.base
78
+ - cdk synth -c stack=target -o cdk.out.target
79
+ - |
80
+ cdk-cost-analyzer \
81
+ cdk.out.base/TestStack.template.json \
82
+ cdk.out.target/TestStack.template.json \
83
+ --region eu-central-1 \
84
+ --format markdown > cost-report.md
85
+ - cat cost-report.md
86
+ artifacts:
87
+ reports:
88
+ markdown: cost-report.md
89
+ ```
90
+
91
+ ## Notes
92
+
93
+ - Uses AWS account `585008061383` (dev) in `eu-central-1`
94
+ - Requires AWS credentials configured via `AWS_PROFILE=dev`
95
+ - IAM roles show as $0.00 (no direct cost, but included in report)
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ const cdk = require('aws-cdk-lib');
3
+ const { Stack } = require('aws-cdk-lib');
4
+ const ec2 = require('aws-cdk-lib/aws-ec2');
5
+ const s3 = require('aws-cdk-lib/aws-s3');
6
+ const lambda = require('aws-cdk-lib/aws-lambda');
7
+ const rds = require('aws-cdk-lib/aws-rds');
8
+
9
+ // Base Stack - Current infrastructure
10
+ class BaseStack extends Stack {
11
+ constructor(scope, id, props) {
12
+ super(scope, id, props);
13
+
14
+ // Simple S3 bucket
15
+ new s3.Bucket(this, 'MyBucket', {
16
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
17
+ });
18
+
19
+ // Lambda function with 128MB
20
+ new lambda.Function(this, 'MyFunction', {
21
+ runtime: lambda.Runtime.NODEJS_18_X,
22
+ handler: 'index.handler',
23
+ code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
24
+ memorySize: 128,
25
+ });
26
+ }
27
+ }
28
+
29
+ // Target Stack - Proposed changes with EC2 and RDS
30
+ class TargetStack extends Stack {
31
+ constructor(scope, id, props) {
32
+ super(scope, id, props);
33
+
34
+ // Keep the S3 bucket
35
+ new s3.Bucket(this, 'MyBucket', {
36
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
37
+ });
38
+
39
+ // Upgrade Lambda to 512MB (MODIFIED)
40
+ new lambda.Function(this, 'MyFunction', {
41
+ runtime: lambda.Runtime.NODEJS_18_X,
42
+ handler: 'index.handler',
43
+ code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
44
+ memorySize: 512,
45
+ });
46
+
47
+ // Create VPC for EC2 and RDS
48
+ const vpc = new ec2.Vpc(this, 'MyVPC', {
49
+ maxAzs: 2,
50
+ natGateways: 0,
51
+ subnetConfiguration: [
52
+ {
53
+ name: 'Public',
54
+ subnetType: ec2.SubnetType.PUBLIC,
55
+ },
56
+ {
57
+ name: 'Isolated',
58
+ subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
59
+ },
60
+ ],
61
+ });
62
+
63
+ // Add EC2 instance (NEW)
64
+ new ec2.Instance(this, 'MyInstance', {
65
+ vpc,
66
+ vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
67
+ instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM),
68
+ machineImage: ec2.MachineImage.latestAmazonLinux2023(),
69
+ });
70
+
71
+ // Add RDS database (NEW)
72
+ new rds.DatabaseInstance(this, 'MyDatabase', {
73
+ engine: rds.DatabaseInstanceEngine.postgres({
74
+ version: rds.PostgresEngineVersion.VER_15,
75
+ }),
76
+ instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
77
+ vpc,
78
+ vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
79
+ allocatedStorage: 20,
80
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
81
+ deletionProtection: false,
82
+ });
83
+ }
84
+ }
85
+
86
+ const app = new cdk.App();
87
+
88
+ // Synthesize based on context
89
+ const stackType = app.node.tryGetContext('stack') || 'base';
90
+
91
+ const env = {
92
+ account: '585008061383',
93
+ region: 'eu-central-1',
94
+ };
95
+
96
+ if (stackType === 'base') {
97
+ new BaseStack(app, 'ComputeStack', { env });
98
+ } else {
99
+ new TargetStack(app, 'ComputeStack', { env });
100
+ }
101
+
102
+ app.synth();
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ const cdk = require('aws-cdk-lib');
3
+ const { Stack } = require('aws-cdk-lib');
4
+ const ec2 = require('aws-cdk-lib/aws-ec2');
5
+ const s3 = require('aws-cdk-lib/aws-s3');
6
+ const lambda = require('aws-cdk-lib/aws-lambda');
7
+ const rds = require('aws-cdk-lib/aws-rds');
8
+
9
+ // Base Stack - Current infrastructure
10
+ class BaseStack extends Stack {
11
+ constructor(scope, id, props) {
12
+ super(scope, id, props);
13
+
14
+ // Simple S3 bucket
15
+ new s3.Bucket(this, 'MyBucket', {
16
+ bucketName: 'my-test-bucket-base',
17
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
18
+ });
19
+
20
+ // Lambda function with 128MB
21
+ new lambda.Function(this, 'MyFunction', {
22
+ runtime: lambda.Runtime.NODEJS_18_X,
23
+ handler: 'index.handler',
24
+ code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
25
+ memorySize: 128,
26
+ });
27
+ }
28
+ }
29
+
30
+ // Target Stack - Proposed changes
31
+ class TargetStack extends Stack {
32
+ constructor(scope, id, props) {
33
+ super(scope, id, props);
34
+
35
+ // Keep the S3 bucket
36
+ new s3.Bucket(this, 'MyBucket', {
37
+ bucketName: 'my-test-bucket-base',
38
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
39
+ });
40
+
41
+ // Upgrade Lambda to 512MB (MODIFIED)
42
+ new lambda.Function(this, 'MyFunction', {
43
+ runtime: lambda.Runtime.NODEJS_18_X,
44
+ handler: 'index.handler',
45
+ code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
46
+ memorySize: 1024,
47
+ });
48
+
49
+ // Add another Lambda function (NEW)
50
+ new lambda.Function(this, 'MyNewFunction', {
51
+ runtime: lambda.Runtime.NODEJS_18_X,
52
+ handler: 'index.handler',
53
+ code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
54
+ memorySize: 2560,
55
+ });
56
+
57
+ // Add another S3 bucket (NEW)
58
+ new s3.Bucket(this, 'MyNewBucket', {
59
+ bucketName: 'my-test-bucket-new',
60
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
61
+ });
62
+ }
63
+ }
64
+
65
+ const app = new cdk.App();
66
+
67
+ // Synthesize based on context
68
+ const stackType = app.node.tryGetContext('stack') || 'base';
69
+
70
+ const env = {
71
+ account: '585008061383',
72
+ region: 'eu-central-1'
73
+ };
74
+
75
+ if (stackType === 'base') {
76
+ new BaseStack(app, 'TestStack', { env });
77
+ } else {
78
+ new TargetStack(app, 'TestStack', { env });
79
+ }
80
+
81
+ app.synth();
@@ -0,0 +1,3 @@
1
+ {
2
+ "app": "node app-with-compute.js"
3
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "availability-zones:account=585008061383:region=eu-central-1": [
3
+ "eu-central-1a",
4
+ "eu-central-1b",
5
+ "eu-central-1c"
6
+ ]
7
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "app": "node app.js"
3
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "48.0.0",
3
+ "files": {
4
+ "fef4e5534aeeda5c83d0ba81f82463fe8d00a64e197ca90e146f1a90694b23e2": {
5
+ "displayName": "TestStack Template",
6
+ "source": {
7
+ "path": "TestStack.template.json",
8
+ "packaging": "file"
9
+ },
10
+ "destinations": {
11
+ "585008061383-eu-central-1-c1c9545d": {
12
+ "bucketName": "cdk-hnb659fds-assets-585008061383-eu-central-1",
13
+ "objectKey": "fef4e5534aeeda5c83d0ba81f82463fe8d00a64e197ca90e146f1a90694b23e2.json",
14
+ "region": "eu-central-1",
15
+ "assumeRoleArn": "arn:${AWS::Partition}:iam::585008061383:role/cdk-hnb659fds-file-publishing-role-585008061383-eu-central-1"
16
+ }
17
+ }
18
+ }
19
+ },
20
+ "dockerImages": {}
21
+ }