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,42 @@
1
+ {
2
+ "name": "cdk-cost-analyzer-multi-stack-example",
3
+ "version": "1.0.0",
4
+ "description": "Multi-stack CDK application example with cost analysis",
5
+ "bin": {
6
+ "multi-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 --all",
15
+ "deploy:networking": "cdk deploy NetworkingStack",
16
+ "deploy:compute": "cdk deploy ComputeStack",
17
+ "deploy:storage": "cdk deploy StorageStack",
18
+ "diff": "cdk diff"
19
+ },
20
+ "keywords": [
21
+ "aws",
22
+ "cdk",
23
+ "multi-stack",
24
+ "cost-analysis",
25
+ "example"
26
+ ],
27
+ "author": "ANWB",
28
+ "license": "MIT",
29
+ "devDependencies": {
30
+ "@types/jest": "^29.5.14",
31
+ "@types/node": "^22.10.2",
32
+ "aws-cdk": "^2.233.0",
33
+ "jest": "^29.7.0",
34
+ "ts-jest": "^29.2.5",
35
+ "ts-node": "^10.9.2",
36
+ "typescript": "^5.7.2"
37
+ },
38
+ "dependencies": {
39
+ "aws-cdk-lib": "^2.233.0",
40
+ "constructs": "^10.4.2"
41
+ }
42
+ }
@@ -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
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "Resources": {
3
+ "MyBucket": {
4
+ "Type": "AWS::S3::Bucket",
5
+ "Properties": {}
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "Resources": {
3
+ "MyBucket": {
4
+ "Type": "AWS::S3::Bucket",
5
+ "Properties": {}
6
+ },
7
+ "MyInstance": {
8
+ "Type": "AWS::EC2::Instance",
9
+ "Properties": {
10
+ "InstanceType": "t3.micro"
11
+ }
12
+ }
13
+ }
14
+ }
File without changes
@@ -0,0 +1,52 @@
1
+ # CDK Cost Analyzer Configuration
2
+ # This file configures cost thresholds and usage assumptions for cost analysis
3
+
4
+ # Cost thresholds for pipeline enforcement
5
+ thresholds:
6
+ default:
7
+ warning: 50 # USD per month - displays warning but passes pipeline
8
+ error: 200 # USD per month - fails pipeline, requires review
9
+
10
+ # Custom usage assumptions for cost estimation
11
+ # Adjust these values to match your expected application usage
12
+ usageAssumptions:
13
+ # Amazon S3 usage patterns
14
+ s3:
15
+ storageGB: 100 # Expected storage size in GB
16
+ getRequests: 50000 # Monthly GET requests
17
+ putRequests: 5000 # Monthly PUT requests
18
+ dataTransferGB: 50 # Monthly data transfer out in GB
19
+
20
+ # AWS Lambda usage patterns
21
+ lambda:
22
+ invocationsPerMonth: 1000000 # Monthly function invocations
23
+ averageDurationMs: 200 # Average execution duration in milliseconds
24
+ memoryMB: 512 # Allocated memory in MB
25
+
26
+ # Amazon DynamoDB usage patterns
27
+ dynamodb:
28
+ readCapacityUnits: 5 # Provisioned read capacity units
29
+ writeCapacityUnits: 5 # Provisioned write capacity units
30
+ storageGB: 10 # Expected data storage in GB
31
+
32
+ # Amazon API Gateway usage patterns
33
+ apiGateway:
34
+ requestsPerMonth: 1000000 # Monthly API requests
35
+
36
+ # CDK synthesis configuration (optional)
37
+ synthesis:
38
+ appPath: . # Path to CDK application
39
+ outputPath: cdk.out # CDK synthesis output directory
40
+
41
+ # Resource exclusions (optional)
42
+ # Exclude specific resource types from cost analysis
43
+ exclusions:
44
+ resourceTypes:
45
+ - AWS::IAM::Role # IAM roles have no direct cost
46
+ - AWS::IAM::Policy # IAM policies have no direct cost
47
+ - AWS::Logs::LogGroup # CloudWatch Logs analyzed separately
48
+
49
+ # Cache configuration
50
+ cache:
51
+ enabled: true # Enable pricing data caching
52
+ durationHours: 24 # Cache duration in hours
@@ -0,0 +1,126 @@
1
+ # GitLab CI/CD Pipeline with CDK Cost Analysis
2
+ # This pipeline runs cost analysis on merge requests to prevent unexpected infrastructure costs
3
+
4
+ stages:
5
+ - build
6
+ - test
7
+ - cost-analysis
8
+ - deploy
9
+
10
+ variables:
11
+ AWS_REGION: us-east-1
12
+ CDK_APP_PATH: examples/single-stack
13
+ NODE_VERSION: "18"
14
+
15
+ # Install dependencies for the application
16
+ build:
17
+ stage: build
18
+ image: node:${NODE_VERSION}
19
+ script:
20
+ - echo "Installing dependencies..."
21
+ - npm ci
22
+ - cd ${CDK_APP_PATH}
23
+ - npm ci
24
+ cache:
25
+ key: ${CI_COMMIT_REF_SLUG}
26
+ paths:
27
+ - node_modules/
28
+ - ${CDK_APP_PATH}/node_modules/
29
+ artifacts:
30
+ paths:
31
+ - node_modules/
32
+ - ${CDK_APP_PATH}/node_modules/
33
+ expire_in: 1 hour
34
+
35
+ # Run application tests
36
+ test:
37
+ stage: test
38
+ image: node:${NODE_VERSION}
39
+ dependencies:
40
+ - build
41
+ script:
42
+ - cd ${CDK_APP_PATH}
43
+ - npm test
44
+ only:
45
+ - merge_requests
46
+ - main
47
+
48
+ # Analyze infrastructure cost changes for merge requests
49
+ cost-analysis:
50
+ stage: cost-analysis
51
+ image: node:${NODE_VERSION}
52
+ dependencies:
53
+ - build
54
+ before_script:
55
+ # Install CDK Cost Analyzer globally
56
+ - npm install -g cdk-cost-analyzer
57
+ # Verify AWS credentials are configured
58
+ - |
59
+ if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
60
+ echo "ERROR: AWS credentials not configured"
61
+ echo "Please configure AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as CI/CD variables"
62
+ exit 1
63
+ fi
64
+ script:
65
+ - echo "Analyzing infrastructure cost changes..."
66
+ - cd ${CDK_APP_PATH}
67
+ # Run cost analysis with automatic CDK synthesis
68
+ - |
69
+ cdk-cost-analyzer pipeline \
70
+ --base-branch ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} \
71
+ --target-branch ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} \
72
+ --cdk-app-path . \
73
+ --region ${AWS_REGION} \
74
+ --format markdown \
75
+ --post-to-gitlab
76
+ cache:
77
+ key: pricing-cache
78
+ paths:
79
+ - .cdk-cost-analyzer-cache/
80
+ artifacts:
81
+ reports:
82
+ # Store cost analysis report as artifact
83
+ dotenv: cost-analysis.env
84
+ paths:
85
+ - cost-report.md
86
+ expire_in: 30 days
87
+ only:
88
+ - merge_requests
89
+ allow_failure: false # Fail pipeline if cost threshold exceeded
90
+
91
+ # Deploy to AWS (requires manual approval if cost threshold exceeded)
92
+ deploy:
93
+ stage: deploy
94
+ image: node:${NODE_VERSION}
95
+ dependencies:
96
+ - build
97
+ before_script:
98
+ - npm install -g aws-cdk
99
+ script:
100
+ - cd ${CDK_APP_PATH}
101
+ - echo "Deploying infrastructure to AWS..."
102
+ - cdk deploy --require-approval never
103
+ only:
104
+ - main
105
+ when: manual
106
+ environment:
107
+ name: production
108
+ action: start
109
+
110
+ # Optional: Deploy to development environment automatically
111
+ deploy:dev:
112
+ stage: deploy
113
+ image: node:${NODE_VERSION}
114
+ dependencies:
115
+ - build
116
+ before_script:
117
+ - npm install -g aws-cdk
118
+ script:
119
+ - cd ${CDK_APP_PATH}
120
+ - echo "Deploying to development environment..."
121
+ - cdk deploy --require-approval never
122
+ only:
123
+ - develop
124
+ environment:
125
+ name: development
126
+ action: start
@@ -0,0 +1,184 @@
1
+ # Single-Stack CDK Cost Analyzer Example
2
+
3
+ This example demonstrates how to integrate CDK Cost Analyzer into a basic single-stack CDK application with GitLab CI/CD pipeline integration.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ single-stack/
9
+ ├── bin/
10
+ │ └── app.ts # CDK application entry point
11
+ ├── lib/
12
+ │ └── infrastructure-stack.ts # Infrastructure stack definition
13
+ ├── .cdk-cost-analyzer.yml # Cost analyzer configuration
14
+ ├── .gitlab-ci.yml # GitLab CI pipeline
15
+ ├── cdk.json # CDK configuration
16
+ ├── package.json # Node.js dependencies
17
+ ├── tsconfig.json # TypeScript configuration
18
+ └── README.md # This file
19
+ ```
20
+
21
+ ## Infrastructure Overview
22
+
23
+ This example creates a simple web application infrastructure:
24
+
25
+ - **Amazon S3**: Static website hosting bucket
26
+ - **AWS Lambda**: API backend function
27
+ - **Amazon DynamoDB**: Data storage table
28
+ - **Amazon API Gateway**: REST API endpoint
29
+
30
+ ## Prerequisites
31
+
32
+ - Node.js 18 or later
33
+ - AWS CDK CLI: `npm install -g aws-cdk`
34
+ - AWS account with appropriate credentials
35
+ - GitLab repository with CI/CD enabled
36
+
37
+ ## Setup Instructions
38
+
39
+ ### 1. Install Dependencies
40
+
41
+ ```bash
42
+ cd examples/single-stack
43
+ npm install
44
+ ```
45
+
46
+ ### 2. Configure AWS Credentials
47
+
48
+ For local development:
49
+
50
+ ```bash
51
+ export AWS_ACCESS_KEY_ID=your-access-key
52
+ export AWS_SECRET_ACCESS_KEY=your-secret-key
53
+ export AWS_REGION=us-east-1
54
+ ```
55
+
56
+ For GitLab CI, configure these as CI/CD variables in your GitLab project settings.
57
+
58
+ ### 3. Bootstrap CDK (First Time Only)
59
+
60
+ ```bash
61
+ cdk bootstrap aws://ACCOUNT-ID/REGION
62
+ ```
63
+
64
+ ### 4. Review Configuration
65
+
66
+ Edit `.cdk-cost-analyzer.yml` to adjust cost thresholds and usage assumptions for your needs.
67
+
68
+ ## Local Development
69
+
70
+ ### Synthesize CloudFormation Template
71
+
72
+ ```bash
73
+ cdk synth
74
+ ```
75
+
76
+ ### Deploy Infrastructure
77
+
78
+ ```bash
79
+ cdk deploy
80
+ ```
81
+
82
+ ### Run Cost Analysis Locally
83
+
84
+ ```bash
85
+ # Install cost analyzer
86
+ npm install -g cdk-cost-analyzer
87
+
88
+ # Analyze cost impact
89
+ cdk-cost-analyzer pipeline \
90
+ --base-branch main \
91
+ --target-branch feature/my-changes \
92
+ --region us-east-1
93
+ ```
94
+
95
+ ## GitLab CI/CD Integration
96
+
97
+ The `.gitlab-ci.yml` file configures automatic cost analysis for merge requests.
98
+
99
+ ### Pipeline Stages
100
+
101
+ 1. **Build**: Install dependencies
102
+ 2. **Test**: Run application tests
103
+ 3. **Cost Analysis**: Analyze infrastructure cost changes
104
+ 4. **Deploy**: Deploy to AWS (manual approval required if cost threshold exceeded)
105
+
106
+ ### Cost Thresholds
107
+
108
+ The pipeline enforces cost thresholds defined in `.cdk-cost-analyzer.yml`:
109
+
110
+ - **Warning**: $50/month - Pipeline passes but displays warning
111
+ - **Error**: $200/month - Pipeline fails, requires manual review
112
+
113
+ ### Viewing Cost Reports
114
+
115
+ Cost analysis results appear as comments on merge requests, showing:
116
+
117
+ - Total monthly cost change
118
+ - Per-resource cost breakdown
119
+ - Threshold status
120
+ - Configuration summary
121
+
122
+ ## Customizing Usage Assumptions
123
+
124
+ Edit `.cdk-cost-analyzer.yml` to reflect your actual usage patterns:
125
+
126
+ ```yaml
127
+ usageAssumptions:
128
+ s3:
129
+ storageGB: 100 # Expected storage size
130
+ getRequests: 50000 # Monthly GET requests
131
+ putRequests: 5000 # Monthly PUT requests
132
+ lambda:
133
+ invocationsPerMonth: 1000000 # Monthly invocations
134
+ averageDurationMs: 200 # Average execution time
135
+ dynamodb:
136
+ readCapacityUnits: 5 # Provisioned read capacity
137
+ writeCapacityUnits: 5 # Provisioned write capacity
138
+ ```
139
+
140
+ ## Troubleshooting
141
+
142
+ ### Synthesis Fails in Pipeline
143
+
144
+ **Issue**: CDK synthesis fails with dependency errors
145
+
146
+ **Solution**: Ensure all dependencies are installed in the build stage:
147
+
148
+ ```yaml
149
+ build:
150
+ script:
151
+ - npm ci
152
+ - cd examples/single-stack && npm ci
153
+ ```
154
+
155
+ ### Missing AWS Credentials
156
+
157
+ **Issue**: Pipeline fails with "Unable to locate credentials"
158
+
159
+ **Solution**: Configure AWS credentials as GitLab CI/CD variables:
160
+ - `AWS_ACCESS_KEY_ID`
161
+ - `AWS_SECRET_ACCESS_KEY`
162
+ - `AWS_REGION`
163
+
164
+ ### Cost Threshold Exceeded
165
+
166
+ **Issue**: Pipeline fails due to cost threshold violation
167
+
168
+ **Solution**: Review the cost report in the merge request comment:
169
+ 1. Identify resources contributing to cost increase
170
+ 2. Optimize resource configuration if possible
171
+ 3. Request threshold override approval if increase is justified
172
+ 4. Update thresholds in `.cdk-cost-analyzer.yml` if appropriate
173
+
174
+ ## Next Steps
175
+
176
+ - Review [Configuration Documentation](../../docs/CONFIGURATION.md) for advanced options
177
+ - Explore [Multi-Stack Example](../multi-stack/) for complex applications
178
+ - Check [Troubleshooting Guide](../../docs/TROUBLESHOOTING.md) for common issues
179
+
180
+ ## Additional Resources
181
+
182
+ - [AWS CDK Documentation](https://docs.aws.amazon.com/cdk/)
183
+ - [CDK Cost Analyzer Documentation](../../README.md)
184
+ - [GitLab CI/CD Documentation](https://docs.gitlab.com/ee/ci/)
File without changes
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import 'source-map-support/register';
3
+ import * as cdk from 'aws-cdk-lib';
4
+ import { InfrastructureStack } from '../lib/infrastructure-stack';
5
+
6
+ const app = new cdk.App();
7
+
8
+ new InfrastructureStack(app, 'SingleStackExample', {
9
+ env: {
10
+ account: process.env.CDK_DEFAULT_ACCOUNT,
11
+ region: process.env.CDK_DEFAULT_REGION || 'us-east-1',
12
+ },
13
+ description: 'Single-stack CDK Cost Analyzer example - Basic web application infrastructure',
14
+ });
15
+
16
+ app.synth();
@@ -0,0 +1,72 @@
1
+ {
2
+ "app": "npx ts-node --prefer-ts-exts bin/app.ts",
3
+ "watch": {
4
+ "include": [
5
+ "**"
6
+ ],
7
+ "exclude": [
8
+ "README.md",
9
+ "cdk*.json",
10
+ "**/*.d.ts",
11
+ "**/*.js",
12
+ "tsconfig.json",
13
+ "package*.json",
14
+ "yarn.lock",
15
+ "node_modules",
16
+ "test"
17
+ ]
18
+ },
19
+ "context": {
20
+ "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21
+ "@aws-cdk/core:checkSecretUsage": true,
22
+ "@aws-cdk/core:target-partitions": [
23
+ "aws",
24
+ "aws-cn"
25
+ ],
26
+ "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27
+ "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28
+ "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29
+ "@aws-cdk/aws-iam:minimizePolicies": true,
30
+ "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31
+ "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32
+ "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33
+ "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34
+ "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35
+ "@aws-cdk/core:enablePartitionLiterals": true,
36
+ "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37
+ "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
38
+ "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
39
+ "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
40
+ "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
41
+ "@aws-cdk/aws-route53-patters:useCertificate": true,
42
+ "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
43
+ "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
44
+ "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
45
+ "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
46
+ "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
47
+ "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
48
+ "@aws-cdk/aws-redshift:columnId": true,
49
+ "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
50
+ "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
51
+ "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
52
+ "@aws-cdk/aws-kms:aliasNameRef": true,
53
+ "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
54
+ "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
55
+ "@aws-cdk/aws-efs:denyAnonymousAccess": true,
56
+ "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
57
+ "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
58
+ "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
59
+ "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
60
+ "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
61
+ "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
62
+ "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
63
+ "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
64
+ "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
65
+ "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
66
+ "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
67
+ "@aws-cdk/aws-eks:nodegroupNameAttribute": true,
68
+ "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
69
+ "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
70
+ "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false
71
+ }
72
+ }
@@ -0,0 +1,119 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as s3 from 'aws-cdk-lib/aws-s3';
3
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
4
+ import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
5
+ import * as apigateway from 'aws-cdk-lib/aws-apigateway';
6
+ import { Construct } from 'constructs';
7
+
8
+ /**
9
+ * Single-stack infrastructure for a basic web application
10
+ *
11
+ * This stack demonstrates common AWS resources that CDK Cost Analyzer can estimate:
12
+ * - S3 bucket for static website hosting
13
+ * - Lambda function for API backend
14
+ * - DynamoDB table for data storage
15
+ * - API Gateway for REST API endpoint
16
+ */
17
+ export class InfrastructureStack extends cdk.Stack {
18
+ constructor(scope: Construct, id: string, props?: cdk.StackProps) {
19
+ super(scope, id, props);
20
+
21
+ // S3 bucket for static website hosting
22
+ const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
23
+ bucketName: `${cdk.Stack.of(this).account}-website-${cdk.Stack.of(this).region}`,
24
+ websiteIndexDocument: 'index.html',
25
+ websiteErrorDocument: 'error.html',
26
+ publicReadAccess: true,
27
+ blockPublicAccess: {
28
+ blockPublicAcls: false,
29
+ blockPublicPolicy: false,
30
+ ignorePublicAcls: false,
31
+ restrictPublicBuckets: false,
32
+ },
33
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
34
+ autoDeleteObjects: true,
35
+ });
36
+
37
+ // DynamoDB table for application data
38
+ const dataTable = new dynamodb.Table(this, 'DataTable', {
39
+ tableName: 'application-data',
40
+ partitionKey: {
41
+ name: 'id',
42
+ type: dynamodb.AttributeType.STRING,
43
+ },
44
+ billingMode: dynamodb.BillingMode.PROVISIONED,
45
+ readCapacity: 5,
46
+ writeCapacity: 5,
47
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
48
+ });
49
+
50
+ // Lambda function for API backend
51
+ const apiFunction = new lambda.Function(this, 'ApiFunction', {
52
+ functionName: 'api-handler',
53
+ runtime: lambda.Runtime.NODEJS_18_X,
54
+ handler: 'index.handler',
55
+ code: lambda.Code.fromInline(`
56
+ exports.handler = async (event) => {
57
+ return {
58
+ statusCode: 200,
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ 'Access-Control-Allow-Origin': '*',
62
+ },
63
+ body: JSON.stringify({
64
+ message: 'Hello from Lambda!',
65
+ timestamp: new Date().toISOString(),
66
+ }),
67
+ };
68
+ };
69
+ `),
70
+ memorySize: 512,
71
+ timeout: cdk.Duration.seconds(30),
72
+ environment: {
73
+ TABLE_NAME: dataTable.tableName,
74
+ },
75
+ });
76
+
77
+ // Grant Lambda function permissions to access DynamoDB
78
+ dataTable.grantReadWriteData(apiFunction);
79
+
80
+ // API Gateway REST API
81
+ const api = new apigateway.RestApi(this, 'Api', {
82
+ restApiName: 'Application API',
83
+ description: 'REST API for the application',
84
+ deployOptions: {
85
+ stageName: 'prod',
86
+ throttlingRateLimit: 100,
87
+ throttlingBurstLimit: 200,
88
+ },
89
+ defaultCorsPreflightOptions: {
90
+ allowOrigins: apigateway.Cors.ALL_ORIGINS,
91
+ allowMethods: apigateway.Cors.ALL_METHODS,
92
+ },
93
+ });
94
+
95
+ // API Gateway integration with Lambda
96
+ const lambdaIntegration = new apigateway.LambdaIntegration(apiFunction);
97
+ api.root.addMethod('GET', lambdaIntegration);
98
+
99
+ const itemsResource = api.root.addResource('items');
100
+ itemsResource.addMethod('GET', lambdaIntegration);
101
+ itemsResource.addMethod('POST', lambdaIntegration);
102
+
103
+ // Stack outputs
104
+ new cdk.CfnOutput(this, 'WebsiteUrl', {
105
+ value: websiteBucket.bucketWebsiteUrl,
106
+ description: 'Static website URL',
107
+ });
108
+
109
+ new cdk.CfnOutput(this, 'ApiUrl', {
110
+ value: api.url,
111
+ description: 'API Gateway endpoint URL',
112
+ });
113
+
114
+ new cdk.CfnOutput(this, 'TableName', {
115
+ value: dataTable.tableName,
116
+ description: 'DynamoDB table name',
117
+ });
118
+ }
119
+ }