cdk-cost-analyzer 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cdk-cost-analyzer-cache/metadata.json +12 -0
- package/.gitlab-ci.yml +214 -0
- package/.husky/pre-commit +12 -0
- package/.kiro/hooks/accessibility-audit.kiro.hook +18 -0
- package/.kiro/hooks/api-schema-validation.kiro.hook +21 -0
- package/.kiro/hooks/auto-test-on-save.kiro.hook +19 -0
- package/.kiro/hooks/cdk-synth-on-change.kiro.hook +20 -0
- package/.kiro/hooks/code-coverage-check.kiro.hook +14 -0
- package/.kiro/hooks/commit-message-helper.kiro.hook +14 -0
- package/.kiro/hooks/dependency-update-check.kiro.hook +14 -0
- package/.kiro/hooks/env-file-validation.kiro.hook +18 -0
- package/.kiro/hooks/lint-and-format-on-save.kiro.hook +21 -0
- package/.kiro/hooks/mcp-config-validation.kiro.hook +17 -0
- package/.kiro/hooks/mcp-server-test.kiro.hook +14 -0
- package/.kiro/hooks/performance-analysis.kiro.hook +14 -0
- package/.kiro/hooks/readme-spell-check.kiro.hook +14 -0
- package/.kiro/hooks/security-scan-on-dependency-change.kiro.hook +21 -0
- package/.kiro/hooks/translation-update.kiro.hook +18 -0
- package/.kiro/hooks/update-documentation.kiro.hook +18 -0
- package/.kiro/settings/mcp.json +20 -0
- package/.kiro/specs/cdk-cost-analyzer/design.md +620 -0
- package/.kiro/specs/cdk-cost-analyzer/requirements.md +183 -0
- package/.kiro/specs/cdk-cost-analyzer/tasks.md +357 -0
- package/.kiro/specs/github-actions-ci/design.md +281 -0
- package/.kiro/specs/github-actions-ci/requirements.md +86 -0
- package/.kiro/specs/github-actions-ci/tasks.md +115 -0
- package/.kiro/specs/nlb-calculator-test-coverage/design.md +190 -0
- package/.kiro/specs/nlb-calculator-test-coverage/requirements.md +84 -0
- package/.kiro/specs/nlb-calculator-test-coverage/tasks.md +150 -0
- package/.kiro/specs/production-readiness/design.md +1213 -0
- package/.kiro/specs/production-readiness/requirements.md +312 -0
- package/.kiro/specs/production-readiness/tasks.md +269 -0
- package/.kiro/specs/repository-cleanup/design.md +283 -0
- package/.kiro/specs/repository-cleanup/requirements.md +74 -0
- package/.kiro/specs/repository-cleanup/tasks.md +64 -0
- package/.kiro/steering/aws-cli-best-practices.md +41 -0
- package/.kiro/steering/cdk-best-practices.md +49 -0
- package/.kiro/steering/development-standards.md +54 -0
- package/.kiro/steering/docker-best-practices.md +34 -0
- package/.kiro/steering/documentation-style.md +151 -0
- package/.kiro/steering/git-best-practices.md +37 -0
- package/.kiro/steering/mcp-best-practices.md +95 -0
- package/.kiro/steering/python-best-practices.md +48 -0
- package/.kiro/steering/react-best-practices.md +44 -0
- package/.kiro/steering/security-best-practices.md +41 -0
- package/.kiro/steering/testing-best-practices.md +59 -0
- package/.kiro/steering/typescript-best-practices.md +40 -0
- package/CHANGELOG.md +49 -0
- package/CONTRIBUTING.md +258 -0
- package/LICENSE +19 -0
- package/README.md +480 -0
- package/SECURITY.md +117 -0
- package/dist/api/index.d.ts +11 -0
- package/dist/api/index.js +65 -0
- package/dist/api/types.d.ts +15 -0
- package/dist/api/types.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +262 -0
- package/dist/config/ConfigManager.d.ts +40 -0
- package/dist/config/ConfigManager.js +238 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +19 -0
- package/dist/config/types.d.ts +72 -0
- package/dist/config/types.js +15 -0
- package/dist/diff/DiffEngine.d.ts +7 -0
- package/dist/diff/DiffEngine.js +73 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +21 -0
- package/dist/diff/types.d.ts +20 -0
- package/dist/diff/types.js +3 -0
- package/dist/integrations/GitLabIntegration.d.ts +7 -0
- package/dist/integrations/GitLabIntegration.js +45 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +21 -0
- package/dist/integrations/types.d.ts +11 -0
- package/dist/integrations/types.js +13 -0
- package/dist/parser/TemplateParser.d.ts +8 -0
- package/dist/parser/TemplateParser.js +75 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.js +22 -0
- package/dist/parser/types.d.ts +30 -0
- package/dist/parser/types.js +3 -0
- package/dist/pipeline/PipelineOrchestrator.d.ts +23 -0
- package/dist/pipeline/PipelineOrchestrator.js +191 -0
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +19 -0
- package/dist/pipeline/types.d.ts +41 -0
- package/dist/pipeline/types.js +13 -0
- package/dist/pricing/CacheManager.d.ts +75 -0
- package/dist/pricing/CacheManager.js +195 -0
- package/dist/pricing/PricingClient.d.ts +17 -0
- package/dist/pricing/PricingClient.js +122 -0
- package/dist/pricing/PricingService.d.ts +16 -0
- package/dist/pricing/PricingService.js +149 -0
- package/dist/pricing/calculators/ALBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/ALBCalculator.js +163 -0
- package/dist/pricing/calculators/APIGatewayCalculator.d.ts +10 -0
- package/dist/pricing/calculators/APIGatewayCalculator.js +177 -0
- package/dist/pricing/calculators/CloudFrontCalculator.d.ts +59 -0
- package/dist/pricing/calculators/CloudFrontCalculator.js +151 -0
- package/dist/pricing/calculators/DynamoDBCalculator.d.ts +9 -0
- package/dist/pricing/calculators/DynamoDBCalculator.js +146 -0
- package/dist/pricing/calculators/EC2Calculator.d.ts +7 -0
- package/dist/pricing/calculators/EC2Calculator.js +80 -0
- package/dist/pricing/calculators/ECSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/ECSCalculator.js +116 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.d.ts +8 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.js +106 -0
- package/dist/pricing/calculators/LambdaCalculator.d.ts +13 -0
- package/dist/pricing/calculators/LambdaCalculator.js +111 -0
- package/dist/pricing/calculators/NLBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/NLBCalculator.js +138 -0
- package/dist/pricing/calculators/NatGatewayCalculator.d.ts +12 -0
- package/dist/pricing/calculators/NatGatewayCalculator.js +116 -0
- package/dist/pricing/calculators/RDSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/RDSCalculator.js +103 -0
- package/dist/pricing/calculators/S3Calculator.d.ts +8 -0
- package/dist/pricing/calculators/S3Calculator.js +68 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.d.ts +12 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.js +129 -0
- package/dist/pricing/index.d.ts +10 -0
- package/dist/pricing/index.js +37 -0
- package/dist/pricing/types.d.ts +53 -0
- package/dist/pricing/types.js +22 -0
- package/dist/releasetag.txt +1 -0
- package/dist/reporter/Reporter.d.ts +18 -0
- package/dist/reporter/Reporter.js +412 -0
- package/dist/reporter/index.d.ts +2 -0
- package/dist/reporter/index.js +21 -0
- package/dist/reporter/types.d.ts +72 -0
- package/dist/reporter/types.js +3 -0
- package/dist/synthesis/SynthesisOrchestrator.d.ts +26 -0
- package/dist/synthesis/SynthesisOrchestrator.js +243 -0
- package/dist/synthesis/index.d.ts +2 -0
- package/dist/synthesis/index.js +19 -0
- package/dist/synthesis/types.d.ts +17 -0
- package/dist/synthesis/types.js +13 -0
- package/dist/threshold/ThresholdEnforcer.d.ts +29 -0
- package/dist/threshold/ThresholdEnforcer.js +143 -0
- package/dist/threshold/index.d.ts +2 -0
- package/dist/threshold/index.js +19 -0
- package/dist/threshold/types.d.ts +15 -0
- package/dist/threshold/types.js +17 -0
- package/docs/CALCULATORS.md +820 -0
- package/docs/CI_CD.md +608 -0
- package/docs/CONFIGURATION.md +407 -0
- package/docs/DEVELOPMENT.md +387 -0
- package/docs/RELEASE.md +223 -0
- package/docs/TROUBLESHOOTING.md +847 -0
- package/examples/.cdk-cost-analyzer.yml +85 -0
- package/examples/.gitlab-ci.yml +125 -0
- package/examples/api-usage.js +26 -0
- package/examples/complex/base.json +16 -0
- package/examples/complex/target.json +29 -0
- package/examples/monorepo/.gitlab-ci.yml +251 -0
- package/examples/monorepo/README.md +341 -0
- package/examples/monorepo/package.json +27 -0
- package/examples/monorepo/packages/backend-infra/.cdk-cost-analyzer.yml +34 -0
- package/examples/monorepo/packages/backend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/backend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/backend-infra/lib/backend-stack.ts +128 -0
- package/examples/monorepo/packages/backend-infra/package.json +30 -0
- package/examples/monorepo/packages/backend-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/data-infra/.cdk-cost-analyzer.yml +38 -0
- package/examples/monorepo/packages/data-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/data-infra/cdk.json +7 -0
- package/examples/monorepo/packages/data-infra/lib/data-stack.ts +121 -0
- package/examples/monorepo/packages/data-infra/package.json +30 -0
- package/examples/monorepo/packages/data-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/frontend-infra/.cdk-cost-analyzer.yml +31 -0
- package/examples/monorepo/packages/frontend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/frontend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/frontend-infra/lib/frontend-stack.ts +60 -0
- package/examples/monorepo/packages/frontend-infra/package.json +30 -0
- package/examples/monorepo/packages/frontend-infra/tsconfig.json +11 -0
- package/examples/monorepo/tsconfig.json +35 -0
- package/examples/multi-stack/.cdk-cost-analyzer.yml +72 -0
- package/examples/multi-stack/.gitlab-ci.yml +184 -0
- package/examples/multi-stack/README.md +279 -0
- package/examples/multi-stack/bin/app.ts +36 -0
- package/examples/multi-stack/cdk.json +72 -0
- package/examples/multi-stack/lib/compute-stack.ts +128 -0
- package/examples/multi-stack/lib/networking-stack.ts +69 -0
- package/examples/multi-stack/lib/storage-stack.ts +141 -0
- package/examples/multi-stack/package-lock.json +4437 -0
- package/examples/multi-stack/package.json +42 -0
- package/examples/multi-stack/tsconfig.json +34 -0
- package/examples/simple/base.json +8 -0
- package/examples/simple/target.json +14 -0
- package/examples/single-stack/.NVP +0 -0
- package/examples/single-stack/.cdk-cost-analyzer.yml +52 -0
- package/examples/single-stack/.gitlab-ci.yml +126 -0
- package/examples/single-stack/README.md +184 -0
- package/examples/single-stack/UeK +0 -0
- package/examples/single-stack/bin/app.ts +16 -0
- package/examples/single-stack/cdk.json +72 -0
- package/examples/single-stack/lib/infrastructure-stack.ts +119 -0
- package/examples/single-stack/package-lock.json +4443 -0
- package/examples/single-stack/package.json +38 -0
- package/examples/single-stack/tsconfig.json +34 -0
- package/package.json +139 -0
- package/test-cdk-project/README-COMPUTE.md +141 -0
- package/test-cdk-project/README.md +95 -0
- package/test-cdk-project/app-with-compute.js +102 -0
- package/test-cdk-project/app.js +81 -0
- package/test-cdk-project/cdk-compute.json +3 -0
- package/test-cdk-project/cdk.context.json +7 -0
- package/test-cdk-project/cdk.json +3 -0
- package/test-cdk-project/cdk.out/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out/cdk.out +1 -0
- package/test-cdk-project/cdk.out/manifest.json +503 -0
- package/test-cdk-project/cdk.out/tree.json +1 -0
- package/test-cdk-project/cdk.out.base/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.base/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out.base/cdk.out +1 -0
- package/test-cdk-project/cdk.out.base/manifest.json +503 -0
- package/test-cdk-project/cdk.out.base/tree.json +1 -0
- package/test-cdk-project/cdk.out.target/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.target/TestStack.template.json +183 -0
- package/test-cdk-project/cdk.out.target/cdk.out +1 -0
- package/test-cdk-project/cdk.out.target/manifest.json +521 -0
- package/test-cdk-project/cdk.out.target/tree.json +1 -0
- package/test-cdk-project/package-lock.json +422 -0
- package/test-cdk-project/package.json +17 -0
- package/tools/workflows/README.md +102 -0
- package/tools/workflows/validate-workflows.js +109 -0
- package/tools/workflows/workflow-utils.ts +181 -0
|
@@ -0,0 +1,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
|
+
}
|
|
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
|
+
}
|