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,121 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
3
+ import * as rds from 'aws-cdk-lib/aws-rds';
4
+ import * as elasticache from 'aws-cdk-lib/aws-elasticache';
5
+ import * as s3 from 'aws-cdk-lib/aws-s3';
6
+ import { Construct } from 'constructs';
7
+
8
+ /**
9
+ * Data infrastructure stack
10
+ *
11
+ * Creates RDS database, ElastiCache cluster, and S3 bucket for data storage
12
+ */
13
+ export class DataStack extends cdk.Stack {
14
+ constructor(scope: Construct, id: string, props?: cdk.StackProps) {
15
+ super(scope, id, props);
16
+
17
+ // VPC for data resources
18
+ const vpc = new ec2.Vpc(this, 'DataVpc', {
19
+ vpcName: 'data-vpc',
20
+ maxAzs: 2,
21
+ natGateways: 1,
22
+ });
23
+
24
+ // Security group for database
25
+ const dbSecurityGroup = new ec2.SecurityGroup(this, 'DbSecurityGroup', {
26
+ vpc,
27
+ description: 'Security group for RDS database',
28
+ allowAllOutbound: false,
29
+ });
30
+
31
+ // RDS PostgreSQL Database
32
+ const database = new rds.DatabaseInstance(this, 'Database', {
33
+ engine: rds.DatabaseInstanceEngine.postgres({
34
+ version: rds.PostgresEngineVersion.VER_15_3,
35
+ }),
36
+ instanceType: ec2.InstanceType.of(
37
+ ec2.InstanceClass.T3,
38
+ ec2.InstanceSize.MEDIUM
39
+ ),
40
+ vpc,
41
+ vpcSubnets: {
42
+ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
43
+ },
44
+ securityGroups: [dbSecurityGroup],
45
+ allocatedStorage: 100,
46
+ storageType: rds.StorageType.GP3,
47
+ multiAz: false,
48
+ databaseName: 'datadb',
49
+ backupRetention: cdk.Duration.days(7),
50
+ deleteAutomatedBackups: true,
51
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
52
+ deletionProtection: false,
53
+ });
54
+
55
+ // Security group for cache
56
+ const cacheSecurityGroup = new ec2.SecurityGroup(this, 'CacheSecurityGroup', {
57
+ vpc,
58
+ description: 'Security group for ElastiCache',
59
+ allowAllOutbound: false,
60
+ });
61
+
62
+ // ElastiCache subnet group
63
+ const cacheSubnetGroup = new elasticache.CfnSubnetGroup(this, 'CacheSubnetGroup', {
64
+ description: 'Subnet group for ElastiCache',
65
+ subnetIds: vpc.selectSubnets({
66
+ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
67
+ }).subnetIds,
68
+ });
69
+
70
+ // ElastiCache Redis Cluster
71
+ const cacheCluster = new elasticache.CfnCacheCluster(this, 'CacheCluster', {
72
+ cacheNodeType: 'cache.t3.micro',
73
+ engine: 'redis',
74
+ numCacheNodes: 2,
75
+ vpcSecurityGroupIds: [cacheSecurityGroup.securityGroupId],
76
+ cacheSubnetGroupName: cacheSubnetGroup.ref,
77
+ engineVersion: '7.0',
78
+ });
79
+
80
+ // S3 bucket for data storage
81
+ const dataBucket = new s3.Bucket(this, 'DataBucket', {
82
+ bucketName: `${cdk.Stack.of(this).account}-data-storage-${cdk.Stack.of(this).region}`,
83
+ versioned: true,
84
+ encryption: s3.BucketEncryption.S3_MANAGED,
85
+ blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
86
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
87
+ autoDeleteObjects: true,
88
+ lifecycleRules: [
89
+ {
90
+ id: 'DeleteOldVersions',
91
+ noncurrentVersionExpiration: cdk.Duration.days(90),
92
+ },
93
+ {
94
+ id: 'TransitionToGlacier',
95
+ transitions: [
96
+ {
97
+ storageClass: s3.StorageClass.GLACIER,
98
+ transitionAfter: cdk.Duration.days(90),
99
+ },
100
+ ],
101
+ },
102
+ ],
103
+ });
104
+
105
+ // Stack outputs
106
+ new cdk.CfnOutput(this, 'DatabaseEndpoint', {
107
+ value: database.dbInstanceEndpointAddress,
108
+ description: 'RDS database endpoint',
109
+ });
110
+
111
+ new cdk.CfnOutput(this, 'CacheEndpoint', {
112
+ value: cacheCluster.attrRedisEndpointAddress,
113
+ description: 'ElastiCache Redis endpoint',
114
+ });
115
+
116
+ new cdk.CfnOutput(this, 'DataBucketName', {
117
+ value: dataBucket.bucketName,
118
+ description: 'S3 data bucket name',
119
+ });
120
+ }
121
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "data-infra",
3
+ "version": "1.0.0",
4
+ "description": "Data infrastructure CDK application",
5
+ "bin": {
6
+ "data-infra": "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
+ "clean": "rm -rf cdk.out node_modules"
16
+ },
17
+ "devDependencies": {
18
+ "@types/jest": "^29.5.14",
19
+ "@types/node": "^22.10.2",
20
+ "aws-cdk": "^2.232.1",
21
+ "jest": "^29.7.0",
22
+ "ts-jest": "^29.2.5",
23
+ "ts-node": "^10.9.2",
24
+ "typescript": "^5.7.2"
25
+ },
26
+ "dependencies": {
27
+ "aws-cdk-lib": "^2.232.1",
28
+ "constructs": "^10.4.2"
29
+ }
30
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "."
6
+ },
7
+ "exclude": [
8
+ "node_modules",
9
+ "cdk.out"
10
+ ]
11
+ }
@@ -0,0 +1,31 @@
1
+ # CDK Cost Analyzer Configuration for Frontend Infrastructure
2
+
3
+ thresholds:
4
+ default:
5
+ warning: 30 # USD per month
6
+ error: 100 # USD per month
7
+
8
+ usageAssumptions:
9
+ s3:
10
+ storageGB: 50
11
+ getRequests: 100000
12
+ putRequests: 5000
13
+ dataTransferGB: 100
14
+
15
+ cloudfront:
16
+ dataTransferGB: 200
17
+ requests: 5000000
18
+
19
+ synthesis:
20
+ appPath: .
21
+ outputPath: cdk.out
22
+
23
+ exclusions:
24
+ resourceTypes:
25
+ - AWS::IAM::Role
26
+ - AWS::IAM::Policy
27
+ - AWS::CertificateManager::Certificate
28
+
29
+ cache:
30
+ enabled: true
31
+ durationHours: 24
@@ -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 { FrontendStack } from '../lib/frontend-stack';
5
+
6
+ const app = new cdk.App();
7
+
8
+ new FrontendStack(app, 'FrontendStack', {
9
+ env: {
10
+ account: process.env.CDK_DEFAULT_ACCOUNT,
11
+ region: process.env.CDK_DEFAULT_REGION || 'us-east-1',
12
+ },
13
+ description: 'Monorepo example - Frontend infrastructure (S3, CloudFront)',
14
+ });
15
+
16
+ app.synth();
@@ -0,0 +1,7 @@
1
+ {
2
+ "app": "npx ts-node --prefer-ts-exts bin/app.ts",
3
+ "context": {
4
+ "@aws-cdk/core:enablePartitionLiterals": true,
5
+ "@aws-cdk/aws-lambda:recognizeLayerVersion": true
6
+ }
7
+ }
@@ -0,0 +1,60 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as s3 from 'aws-cdk-lib/aws-s3';
3
+ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
4
+ import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
5
+ import { Construct } from 'constructs';
6
+
7
+ /**
8
+ * Frontend infrastructure stack
9
+ *
10
+ * Creates S3 bucket for static website hosting and CloudFront distribution
11
+ */
12
+ export class FrontendStack extends cdk.Stack {
13
+ constructor(scope: Construct, id: string, props?: cdk.StackProps) {
14
+ super(scope, id, props);
15
+
16
+ // S3 bucket for static website
17
+ const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
18
+ bucketName: `${cdk.Stack.of(this).account}-frontend-${cdk.Stack.of(this).region}`,
19
+ websiteIndexDocument: 'index.html',
20
+ websiteErrorDocument: 'error.html',
21
+ publicReadAccess: false,
22
+ blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
23
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
24
+ autoDeleteObjects: true,
25
+ });
26
+
27
+ // CloudFront distribution
28
+ const distribution = new cloudfront.Distribution(this, 'Distribution', {
29
+ defaultBehavior: {
30
+ origin: new origins.S3Origin(websiteBucket),
31
+ viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
32
+ cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
33
+ },
34
+ defaultRootObject: 'index.html',
35
+ errorResponses: [
36
+ {
37
+ httpStatus: 404,
38
+ responseHttpStatus: 200,
39
+ responsePagePath: '/index.html',
40
+ },
41
+ ],
42
+ });
43
+
44
+ // Stack outputs
45
+ new cdk.CfnOutput(this, 'BucketName', {
46
+ value: websiteBucket.bucketName,
47
+ description: 'S3 bucket name',
48
+ });
49
+
50
+ new cdk.CfnOutput(this, 'DistributionDomain', {
51
+ value: distribution.distributionDomainName,
52
+ description: 'CloudFront distribution domain',
53
+ });
54
+
55
+ new cdk.CfnOutput(this, 'DistributionUrl', {
56
+ value: `https://${distribution.distributionDomainName}`,
57
+ description: 'CloudFront distribution URL',
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "frontend-infra",
3
+ "version": "1.0.0",
4
+ "description": "Frontend infrastructure CDK application",
5
+ "bin": {
6
+ "frontend-infra": "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
+ "clean": "rm -rf cdk.out node_modules"
16
+ },
17
+ "devDependencies": {
18
+ "@types/jest": "^29.5.14",
19
+ "@types/node": "^22.10.2",
20
+ "aws-cdk": "^2.232.1",
21
+ "jest": "^29.7.0",
22
+ "ts-jest": "^29.2.5",
23
+ "ts-node": "^10.9.2",
24
+ "typescript": "^5.7.2"
25
+ },
26
+ "dependencies": {
27
+ "aws-cdk-lib": "^2.232.1",
28
+ "constructs": "^10.4.2"
29
+ }
30
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "."
6
+ },
7
+ "exclude": [
8
+ "node_modules",
9
+ "cdk.out"
10
+ ]
11
+ }
@@ -0,0 +1,35 @@
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
+ "dist"
34
+ ]
35
+ }
@@ -0,0 +1,72 @@
1
+ # CDK Cost Analyzer Configuration for Multi-Stack Application
2
+ # This file configures cost thresholds and usage assumptions for cost analysis
3
+
4
+ # Cost thresholds for pipeline enforcement
5
+ # Note: Thresholds apply to total cost across all stacks
6
+ thresholds:
7
+ default:
8
+ warning: 100 # USD per month - displays warning but passes pipeline
9
+ error: 500 # USD per month - fails pipeline, requires review
10
+
11
+ # Custom usage assumptions for cost estimation
12
+ # Adjust these values to match your expected application usage
13
+ usageAssumptions:
14
+ # NAT Gateway usage (Networking Stack)
15
+ natGateway:
16
+ dataProcessedGB: 500 # Monthly data processed through NAT Gateway
17
+
18
+ # Application Load Balancer usage (Compute Stack)
19
+ alb:
20
+ newConnectionsPerSecond: 50
21
+ activeConnectionsPerMinute: 5000
22
+ processedBytesGB: 1000
23
+
24
+ # VPC Endpoint usage (Networking Stack)
25
+ vpcEndpoint:
26
+ dataProcessedGB: 100 # Monthly data processed through interface endpoints
27
+
28
+ # ECS usage (Compute Stack)
29
+ ecs:
30
+ taskCount: 2
31
+ cpuUnits: 512
32
+ memoryMB: 1024
33
+ hoursPerMonth: 730
34
+
35
+ # RDS usage (Storage Stack)
36
+ rds:
37
+ instanceClass: db.t3.medium
38
+ storageGB: 100
39
+ backupRetentionDays: 7
40
+ multiAZ: false
41
+
42
+ # ElastiCache usage (Storage Stack)
43
+ elasticache:
44
+ nodeType: cache.t3.micro
45
+ numNodes: 2
46
+ engineType: redis
47
+
48
+ # S3 usage (Storage Stack)
49
+ s3:
50
+ storageGB: 500
51
+ getRequests: 100000
52
+ putRequests: 10000
53
+ dataTransferGB: 100
54
+
55
+ # CDK synthesis configuration (optional)
56
+ synthesis:
57
+ appPath: . # Path to CDK application
58
+ outputPath: cdk.out # CDK synthesis output directory
59
+
60
+ # Resource exclusions (optional)
61
+ # Exclude specific resource types from cost analysis
62
+ exclusions:
63
+ resourceTypes:
64
+ - AWS::IAM::Role # IAM roles have no direct cost
65
+ - AWS::IAM::Policy # IAM policies have no direct cost
66
+ - AWS::EC2::SecurityGroup # Security groups have no direct cost
67
+ - AWS::Logs::LogGroup # CloudWatch Logs analyzed separately
68
+
69
+ # Cache configuration
70
+ cache:
71
+ enabled: true # Enable pricing data caching
72
+ durationHours: 24 # Cache duration in hours
@@ -0,0 +1,184 @@
1
+ # GitLab CI/CD Pipeline with Multi-Stack CDK Cost Analysis
2
+ # This pipeline runs cost analysis on merge requests for multi-stack applications
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/multi-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
+ # Handles multi-stack applications automatically
50
+ cost-analysis:
51
+ stage: cost-analysis
52
+ image: node:${NODE_VERSION}
53
+ dependencies:
54
+ - build
55
+ before_script:
56
+ # Install CDK Cost Analyzer globally
57
+ - npm install -g cdk-cost-analyzer
58
+ # Verify AWS credentials are configured
59
+ - |
60
+ if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
61
+ echo "ERROR: AWS credentials not configured"
62
+ echo "Please configure AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as CI/CD variables"
63
+ exit 1
64
+ fi
65
+ script:
66
+ - echo "Analyzing infrastructure cost changes across all stacks..."
67
+ - cd ${CDK_APP_PATH}
68
+ # Run cost analysis with automatic CDK synthesis
69
+ # The tool automatically detects and analyzes all stacks
70
+ - |
71
+ cdk-cost-analyzer pipeline \
72
+ --base-branch ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} \
73
+ --target-branch ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} \
74
+ --cdk-app-path . \
75
+ --region ${AWS_REGION} \
76
+ --format markdown \
77
+ --post-to-gitlab
78
+ cache:
79
+ key: pricing-cache
80
+ paths:
81
+ - .cdk-cost-analyzer-cache/
82
+ artifacts:
83
+ reports:
84
+ # Store cost analysis report as artifact
85
+ dotenv: cost-analysis.env
86
+ paths:
87
+ - cost-report.md
88
+ expire_in: 30 days
89
+ timeout: 15m # Multi-stack analysis may take longer
90
+ only:
91
+ - merge_requests
92
+ allow_failure: false # Fail pipeline if cost threshold exceeded
93
+
94
+ # Deploy all stacks to production (requires manual approval)
95
+ deploy:all:
96
+ stage: deploy
97
+ image: node:${NODE_VERSION}
98
+ dependencies:
99
+ - build
100
+ before_script:
101
+ - npm install -g aws-cdk
102
+ script:
103
+ - cd ${CDK_APP_PATH}
104
+ - echo "Deploying all stacks to production..."
105
+ - cdk deploy --all --require-approval never
106
+ only:
107
+ - main
108
+ when: manual
109
+ environment:
110
+ name: production
111
+ action: start
112
+
113
+ # Deploy individual stacks (useful for targeted updates)
114
+ deploy:networking:
115
+ stage: deploy
116
+ image: node:${NODE_VERSION}
117
+ dependencies:
118
+ - build
119
+ before_script:
120
+ - npm install -g aws-cdk
121
+ script:
122
+ - cd ${CDK_APP_PATH}
123
+ - echo "Deploying networking stack..."
124
+ - cdk deploy NetworkingStack --require-approval never
125
+ only:
126
+ - main
127
+ when: manual
128
+ environment:
129
+ name: production/networking
130
+ action: start
131
+
132
+ deploy:compute:
133
+ stage: deploy
134
+ image: node:${NODE_VERSION}
135
+ dependencies:
136
+ - build
137
+ before_script:
138
+ - npm install -g aws-cdk
139
+ script:
140
+ - cd ${CDK_APP_PATH}
141
+ - echo "Deploying compute stack..."
142
+ - cdk deploy ComputeStack --require-approval never
143
+ only:
144
+ - main
145
+ when: manual
146
+ environment:
147
+ name: production/compute
148
+ action: start
149
+
150
+ deploy:storage:
151
+ stage: deploy
152
+ image: node:${NODE_VERSION}
153
+ dependencies:
154
+ - build
155
+ before_script:
156
+ - npm install -g aws-cdk
157
+ script:
158
+ - cd ${CDK_APP_PATH}
159
+ - echo "Deploying storage stack..."
160
+ - cdk deploy StorageStack --require-approval never
161
+ only:
162
+ - main
163
+ when: manual
164
+ environment:
165
+ name: production/storage
166
+ action: start
167
+
168
+ # Deploy to development environment automatically
169
+ deploy:dev:
170
+ stage: deploy
171
+ image: node:${NODE_VERSION}
172
+ dependencies:
173
+ - build
174
+ before_script:
175
+ - npm install -g aws-cdk
176
+ script:
177
+ - cd ${CDK_APP_PATH}
178
+ - echo "Deploying all stacks to development environment..."
179
+ - cdk deploy --all --require-approval never
180
+ only:
181
+ - develop
182
+ environment:
183
+ name: development
184
+ action: start