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,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cdk-cost-analyzer-single-stack-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Single-stack CDK application example with cost analysis",
|
|
5
|
+
"bin": {
|
|
6
|
+
"single-stack": "bin/app.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"watch": "tsc -w",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"cdk": "cdk",
|
|
13
|
+
"synth": "cdk synth",
|
|
14
|
+
"deploy": "cdk deploy",
|
|
15
|
+
"diff": "cdk diff"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"aws",
|
|
19
|
+
"cdk",
|
|
20
|
+
"cost-analysis",
|
|
21
|
+
"example"
|
|
22
|
+
],
|
|
23
|
+
"author": "ANWB",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/jest": "^29.5.14",
|
|
27
|
+
"@types/node": "^22.10.2",
|
|
28
|
+
"aws-cdk": "^2.1100.2",
|
|
29
|
+
"jest": "^29.7.0",
|
|
30
|
+
"ts-jest": "^29.2.5",
|
|
31
|
+
"ts-node": "^10.9.2",
|
|
32
|
+
"typescript": "^5.7.2"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"aws-cdk-lib": "^2.233.0",
|
|
36
|
+
"constructs": "^10.4.2"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": [
|
|
6
|
+
"es2020"
|
|
7
|
+
],
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"strictNullChecks": true,
|
|
12
|
+
"noImplicitThis": true,
|
|
13
|
+
"alwaysStrict": true,
|
|
14
|
+
"noUnusedLocals": false,
|
|
15
|
+
"noUnusedParameters": false,
|
|
16
|
+
"noImplicitReturns": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": false,
|
|
18
|
+
"inlineSourceMap": true,
|
|
19
|
+
"inlineSources": true,
|
|
20
|
+
"experimentalDecorators": true,
|
|
21
|
+
"strictPropertyInitialization": false,
|
|
22
|
+
"typeRoots": [
|
|
23
|
+
"./node_modules/@types"
|
|
24
|
+
],
|
|
25
|
+
"esModuleInterop": true,
|
|
26
|
+
"skipLibCheck": true,
|
|
27
|
+
"forceConsistentCasingInFileNames": true,
|
|
28
|
+
"resolveJsonModule": true
|
|
29
|
+
},
|
|
30
|
+
"exclude": [
|
|
31
|
+
"node_modules",
|
|
32
|
+
"cdk.out"
|
|
33
|
+
]
|
|
34
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cdk-cost-analyzer",
|
|
3
|
+
"description": "Analyze AWS CDK infrastructure changes and provide cost impact summaries",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/buildinginthecloud/cdk-cost-analyzer.git"
|
|
7
|
+
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"cdk-cost-analyzer": "dist/cli/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "npx projen build",
|
|
13
|
+
"bump": "npx projen bump",
|
|
14
|
+
"ci:local": "npx projen ci:local",
|
|
15
|
+
"clobber": "npx projen clobber",
|
|
16
|
+
"compile": "npx projen compile",
|
|
17
|
+
"default": "npx projen default",
|
|
18
|
+
"eject": "npx projen eject",
|
|
19
|
+
"eslint": "npx projen eslint",
|
|
20
|
+
"install:act": "npx projen install:act",
|
|
21
|
+
"lint": "npx projen lint",
|
|
22
|
+
"package": "npx projen package",
|
|
23
|
+
"post-compile": "npx projen post-compile",
|
|
24
|
+
"post-upgrade": "npx projen post-upgrade",
|
|
25
|
+
"pre-compile": "npx projen pre-compile",
|
|
26
|
+
"prepare": "npx projen prepare",
|
|
27
|
+
"release": "npx projen release",
|
|
28
|
+
"test": "npx projen test",
|
|
29
|
+
"test:silent": "npx projen test:silent",
|
|
30
|
+
"test:watch": "npx projen test:watch",
|
|
31
|
+
"unbump": "npx projen unbump",
|
|
32
|
+
"upgrade": "npx projen upgrade",
|
|
33
|
+
"validate:workflows": "npx projen validate:workflows",
|
|
34
|
+
"watch": "npx projen watch",
|
|
35
|
+
"projen": "npx projen"
|
|
36
|
+
},
|
|
37
|
+
"author": {
|
|
38
|
+
"name": "Yvo van Zee",
|
|
39
|
+
"email": "yvo@buildinginthecloud.com",
|
|
40
|
+
"organization": false
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@stylistic/eslint-plugin": "^2",
|
|
44
|
+
"@types/jest": "^30.0.0",
|
|
45
|
+
"@types/js-yaml": "^4.0.9",
|
|
46
|
+
"@types/node": "^22.10.1",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^8",
|
|
48
|
+
"@typescript-eslint/parser": "^8",
|
|
49
|
+
"commit-and-tag-version": "^12",
|
|
50
|
+
"constructs": "^10.0.0",
|
|
51
|
+
"eslint": "^9",
|
|
52
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
53
|
+
"eslint-plugin-import": "^2.32.0",
|
|
54
|
+
"fast-check": "^3.23.1",
|
|
55
|
+
"husky": "^9.0.0",
|
|
56
|
+
"jest": "^30.2.0",
|
|
57
|
+
"jest-junit": "^16",
|
|
58
|
+
"lint-staged": "^15.0.0",
|
|
59
|
+
"projen": "^0.98.28",
|
|
60
|
+
"ts-jest": "^29.4.6",
|
|
61
|
+
"ts-node": "^10.9.2",
|
|
62
|
+
"typescript": "^5.7.2"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@aws-sdk/client-pricing": "^3.705.0",
|
|
66
|
+
"commander": "^12.1.0",
|
|
67
|
+
"js-yaml": "^4.1.0"
|
|
68
|
+
},
|
|
69
|
+
"keywords": [
|
|
70
|
+
"analysis",
|
|
71
|
+
"aws",
|
|
72
|
+
"cdk",
|
|
73
|
+
"cloudformation",
|
|
74
|
+
"cost"
|
|
75
|
+
],
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">= 20.0.0"
|
|
78
|
+
},
|
|
79
|
+
"main": "dist/api/index.js",
|
|
80
|
+
"license": "MIT",
|
|
81
|
+
"homepage": "https://github.com/buildinginthecloud/cdk-cost-analyzer",
|
|
82
|
+
"publishConfig": {
|
|
83
|
+
"access": "public"
|
|
84
|
+
},
|
|
85
|
+
"version": "0.1.1",
|
|
86
|
+
"bugs": {
|
|
87
|
+
"url": "https://github.com/buildinginthecloud/cdk-cost-analyzer/issues"
|
|
88
|
+
},
|
|
89
|
+
"jest": {
|
|
90
|
+
"coverageProvider": "v8",
|
|
91
|
+
"testTimeout": 30000,
|
|
92
|
+
"forceExit": true,
|
|
93
|
+
"detectOpenHandles": true,
|
|
94
|
+
"testMatch": [
|
|
95
|
+
"<rootDir>/@(src|test)/**/*(*.)@(spec|test).ts?(x)",
|
|
96
|
+
"<rootDir>/@(src|test)/**/__tests__/**/*.ts?(x)",
|
|
97
|
+
"<rootDir>/@(projenrc)/**/*(*.)@(spec|test).ts?(x)",
|
|
98
|
+
"<rootDir>/@(projenrc)/**/__tests__/**/*.ts?(x)"
|
|
99
|
+
],
|
|
100
|
+
"clearMocks": true,
|
|
101
|
+
"collectCoverage": true,
|
|
102
|
+
"coverageReporters": [
|
|
103
|
+
"json",
|
|
104
|
+
"lcov",
|
|
105
|
+
"clover",
|
|
106
|
+
"cobertura",
|
|
107
|
+
"text"
|
|
108
|
+
],
|
|
109
|
+
"coverageDirectory": "coverage",
|
|
110
|
+
"coveragePathIgnorePatterns": [
|
|
111
|
+
"/node_modules/"
|
|
112
|
+
],
|
|
113
|
+
"testPathIgnorePatterns": [
|
|
114
|
+
"/node_modules/"
|
|
115
|
+
],
|
|
116
|
+
"watchPathIgnorePatterns": [
|
|
117
|
+
"/node_modules/"
|
|
118
|
+
],
|
|
119
|
+
"reporters": [
|
|
120
|
+
"default",
|
|
121
|
+
[
|
|
122
|
+
"jest-junit",
|
|
123
|
+
{
|
|
124
|
+
"outputDirectory": "test-reports"
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
],
|
|
128
|
+
"transform": {
|
|
129
|
+
"^.+\\.[t]sx?$": [
|
|
130
|
+
"ts-jest",
|
|
131
|
+
{
|
|
132
|
+
"tsconfig": "tsconfig.dev.json"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"types": "dist/api/index.d.ts",
|
|
138
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
|
|
139
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# CDK Cost Analyzer - EC2 & RDS Test
|
|
2
|
+
|
|
3
|
+
This test demonstrates the CDK Cost Analyzer with compute resources (EC2 and RDS).
|
|
4
|
+
|
|
5
|
+
## Test Scenario
|
|
6
|
+
|
|
7
|
+
### Base Stack (Current)
|
|
8
|
+
- S3 Bucket
|
|
9
|
+
- Lambda Function (128MB)
|
|
10
|
+
|
|
11
|
+
### Target Stack (Proposed)
|
|
12
|
+
- S3 Bucket (unchanged)
|
|
13
|
+
- Lambda Function (512MB) - **MODIFIED**
|
|
14
|
+
- VPC with public and isolated subnets - **NEW**
|
|
15
|
+
- EC2 Instance (t3.medium) - **NEW**
|
|
16
|
+
- RDS PostgreSQL Database (db.t3.micro) - **NEW**
|
|
17
|
+
|
|
18
|
+
## Cost Analysis Results
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Total Cost Delta: +$69.62/month
|
|
22
|
+
|
|
23
|
+
Key Resources:
|
|
24
|
+
- EC2 t3.medium: $36.43/month
|
|
25
|
+
- RDS db.t3.micro (PostgreSQL): $26.94/month
|
|
26
|
+
- Lambda upgrade (128MB → 512MB): +$6.25/month
|
|
27
|
+
|
|
28
|
+
Supporting Infrastructure (no direct cost):
|
|
29
|
+
- VPC, Subnets, Route Tables, Internet Gateway
|
|
30
|
+
- Security Groups, IAM Roles
|
|
31
|
+
- RDS Subnet Group, Secrets Manager
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Synthesize Templates
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Base stack
|
|
40
|
+
AWS_PROFILE=dev npx cdk synth \
|
|
41
|
+
-a "node app-with-compute.js" \
|
|
42
|
+
-c stack=base \
|
|
43
|
+
-o cdk.out.compute.base
|
|
44
|
+
|
|
45
|
+
# Target stack
|
|
46
|
+
AWS_PROFILE=dev npx cdk synth \
|
|
47
|
+
-a "node app-with-compute.js" \
|
|
48
|
+
-c stack=target \
|
|
49
|
+
-o cdk.out.compute.target
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Analyze Costs
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Text format
|
|
56
|
+
AWS_PROFILE=dev node ../dist/cli/index.js \
|
|
57
|
+
cdk.out.compute.base/ComputeStack.template.json \
|
|
58
|
+
cdk.out.compute.target/ComputeStack.template.json \
|
|
59
|
+
--region eu-central-1
|
|
60
|
+
|
|
61
|
+
# Markdown format (for GitLab MR)
|
|
62
|
+
AWS_PROFILE=dev node ../dist/cli/index.js \
|
|
63
|
+
cdk.out.compute.base/ComputeStack.template.json \
|
|
64
|
+
cdk.out.compute.target/ComputeStack.template.json \
|
|
65
|
+
--region eu-central-1 \
|
|
66
|
+
--format markdown
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Key Insights
|
|
70
|
+
|
|
71
|
+
### Costs Calculated
|
|
72
|
+
✅ **EC2 Instance**: Accurate monthly cost based on instance type and region
|
|
73
|
+
✅ **RDS Database**: Accurate monthly cost including instance and storage
|
|
74
|
+
✅ **Lambda Functions**: Cost based on memory allocation and default assumptions
|
|
75
|
+
|
|
76
|
+
### Resources Identified (No Direct Cost)
|
|
77
|
+
- VPC and networking components (subnets, route tables, IGW)
|
|
78
|
+
- Security groups and IAM roles
|
|
79
|
+
- RDS subnet groups
|
|
80
|
+
- Secrets Manager secrets
|
|
81
|
+
|
|
82
|
+
### Cost Assumptions
|
|
83
|
+
- **EC2**: 730 hours/month (24/7), on-demand pricing, Linux OS
|
|
84
|
+
- **RDS**: 730 hours/month, 20GB storage, single-AZ, PostgreSQL 15
|
|
85
|
+
- **Lambda**: 1M invocations/month, 1s average duration
|
|
86
|
+
|
|
87
|
+
## Real-World Application
|
|
88
|
+
|
|
89
|
+
This demonstrates how the tool would work in a typical infrastructure change:
|
|
90
|
+
|
|
91
|
+
1. **Developer proposes changes** in a merge request
|
|
92
|
+
2. **CI/CD pipeline synthesizes** both base and target CDK stacks
|
|
93
|
+
3. **Cost analyzer runs** and generates a report
|
|
94
|
+
4. **Report is posted** as a comment on the GitLab MR
|
|
95
|
+
5. **Team reviews** the cost impact before approving
|
|
96
|
+
|
|
97
|
+
## Example GitLab CI/CD Integration
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
cost-analysis:
|
|
101
|
+
stage: validate
|
|
102
|
+
image: node:18
|
|
103
|
+
before_script:
|
|
104
|
+
- npm install -g aws-cdk cdk-cost-analyzer
|
|
105
|
+
script:
|
|
106
|
+
# Synthesize current main branch
|
|
107
|
+
- git fetch origin main
|
|
108
|
+
- git checkout origin/main
|
|
109
|
+
- cdk synth -o cdk.out.base
|
|
110
|
+
|
|
111
|
+
# Synthesize MR branch
|
|
112
|
+
- git checkout $CI_COMMIT_SHA
|
|
113
|
+
- cdk synth -o cdk.out.target
|
|
114
|
+
|
|
115
|
+
# Analyze cost difference
|
|
116
|
+
- |
|
|
117
|
+
cdk-cost-analyzer \
|
|
118
|
+
cdk.out.base/YourStack.template.json \
|
|
119
|
+
cdk.out.target/YourStack.template.json \
|
|
120
|
+
--region eu-central-1 \
|
|
121
|
+
--format markdown > cost-report.md
|
|
122
|
+
|
|
123
|
+
# Post to MR (using GitLab API)
|
|
124
|
+
- |
|
|
125
|
+
curl --request POST \
|
|
126
|
+
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
|
|
127
|
+
--data-urlencode "body@cost-report.md" \
|
|
128
|
+
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"
|
|
129
|
+
only:
|
|
130
|
+
- merge_requests
|
|
131
|
+
variables:
|
|
132
|
+
AWS_REGION: eu-central-1
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Benefits
|
|
136
|
+
|
|
137
|
+
1. **Early Cost Visibility**: See cost impact before deployment
|
|
138
|
+
2. **Informed Decisions**: Team can discuss expensive changes
|
|
139
|
+
3. **Cost Optimization**: Identify opportunities to reduce costs
|
|
140
|
+
4. **Compliance**: Ensure changes stay within budget constraints
|
|
141
|
+
5. **Documentation**: Automatic cost documentation in MR history
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# CDK Cost Analyzer - Test Project
|
|
2
|
+
|
|
3
|
+
This is a test CDK project to demonstrate the CDK Cost Analyzer functionality.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
- `app.js` - CDK application with two stacks (base and target)
|
|
8
|
+
- `cdk.out.base/` - Synthesized CloudFormation template for base stack
|
|
9
|
+
- `cdk.out.target/` - Synthesized CloudFormation template for target stack
|
|
10
|
+
|
|
11
|
+
## Stacks
|
|
12
|
+
|
|
13
|
+
### Base Stack (Current Infrastructure)
|
|
14
|
+
- S3 Bucket
|
|
15
|
+
- Lambda Function (128MB memory)
|
|
16
|
+
|
|
17
|
+
### Target Stack (Proposed Changes)
|
|
18
|
+
- S3 Bucket (unchanged)
|
|
19
|
+
- Lambda Function (upgraded to 512MB) - **MODIFIED**
|
|
20
|
+
- New Lambda Function (256MB) - **NEW**
|
|
21
|
+
- New S3 Bucket - **NEW**
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### 1. Synthesize CDK Templates
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Synthesize base stack
|
|
29
|
+
AWS_PROFILE=dev npx cdk synth -c stack=base -o cdk.out.base --quiet
|
|
30
|
+
|
|
31
|
+
# Synthesize target stack
|
|
32
|
+
AWS_PROFILE=dev npx cdk synth -c stack=target -o cdk.out.target --quiet
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Analyze Cost Impact
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# From the parent directory
|
|
39
|
+
AWS_PROFILE=dev node dist/cli/index.js \
|
|
40
|
+
test-cdk-project/cdk.out.base/TestStack.template.json \
|
|
41
|
+
test-cdk-project/cdk.out.target/TestStack.template.json \
|
|
42
|
+
--region eu-central-1
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Get Markdown Output (for GitLab MR)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
AWS_PROFILE=dev node dist/cli/index.js \
|
|
49
|
+
test-cdk-project/cdk.out.base/TestStack.template.json \
|
|
50
|
+
test-cdk-project/cdk.out.target/TestStack.template.json \
|
|
51
|
+
--region eu-central-1 \
|
|
52
|
+
--format markdown
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Expected Results
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Total Cost Delta: +$12.82/month
|
|
59
|
+
|
|
60
|
+
Added Resources:
|
|
61
|
+
- MyNewFunction: $4.17/month (Lambda 256MB)
|
|
62
|
+
- MyNewBucket: $2.40/month (S3 bucket)
|
|
63
|
+
|
|
64
|
+
Modified Resources:
|
|
65
|
+
- MyFunction: $2.08 → $8.33 (+$6.25) (Lambda 128MB → 512MB)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Integration with GitLab CI/CD
|
|
69
|
+
|
|
70
|
+
You can integrate this into your GitLab pipeline:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
cost-analysis:
|
|
74
|
+
stage: validate
|
|
75
|
+
script:
|
|
76
|
+
- npm install -g cdk-cost-analyzer
|
|
77
|
+
- cdk synth -c stack=base -o cdk.out.base
|
|
78
|
+
- cdk synth -c stack=target -o cdk.out.target
|
|
79
|
+
- |
|
|
80
|
+
cdk-cost-analyzer \
|
|
81
|
+
cdk.out.base/TestStack.template.json \
|
|
82
|
+
cdk.out.target/TestStack.template.json \
|
|
83
|
+
--region eu-central-1 \
|
|
84
|
+
--format markdown > cost-report.md
|
|
85
|
+
- cat cost-report.md
|
|
86
|
+
artifacts:
|
|
87
|
+
reports:
|
|
88
|
+
markdown: cost-report.md
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Notes
|
|
92
|
+
|
|
93
|
+
- Uses AWS account `585008061383` (dev) in `eu-central-1`
|
|
94
|
+
- Requires AWS credentials configured via `AWS_PROFILE=dev`
|
|
95
|
+
- IAM roles show as $0.00 (no direct cost, but included in report)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const cdk = require('aws-cdk-lib');
|
|
3
|
+
const { Stack } = require('aws-cdk-lib');
|
|
4
|
+
const ec2 = require('aws-cdk-lib/aws-ec2');
|
|
5
|
+
const s3 = require('aws-cdk-lib/aws-s3');
|
|
6
|
+
const lambda = require('aws-cdk-lib/aws-lambda');
|
|
7
|
+
const rds = require('aws-cdk-lib/aws-rds');
|
|
8
|
+
|
|
9
|
+
// Base Stack - Current infrastructure
|
|
10
|
+
class BaseStack extends Stack {
|
|
11
|
+
constructor(scope, id, props) {
|
|
12
|
+
super(scope, id, props);
|
|
13
|
+
|
|
14
|
+
// Simple S3 bucket
|
|
15
|
+
new s3.Bucket(this, 'MyBucket', {
|
|
16
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Lambda function with 128MB
|
|
20
|
+
new lambda.Function(this, 'MyFunction', {
|
|
21
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
22
|
+
handler: 'index.handler',
|
|
23
|
+
code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
|
|
24
|
+
memorySize: 128,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Target Stack - Proposed changes with EC2 and RDS
|
|
30
|
+
class TargetStack extends Stack {
|
|
31
|
+
constructor(scope, id, props) {
|
|
32
|
+
super(scope, id, props);
|
|
33
|
+
|
|
34
|
+
// Keep the S3 bucket
|
|
35
|
+
new s3.Bucket(this, 'MyBucket', {
|
|
36
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Upgrade Lambda to 512MB (MODIFIED)
|
|
40
|
+
new lambda.Function(this, 'MyFunction', {
|
|
41
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
42
|
+
handler: 'index.handler',
|
|
43
|
+
code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
|
|
44
|
+
memorySize: 512,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Create VPC for EC2 and RDS
|
|
48
|
+
const vpc = new ec2.Vpc(this, 'MyVPC', {
|
|
49
|
+
maxAzs: 2,
|
|
50
|
+
natGateways: 0,
|
|
51
|
+
subnetConfiguration: [
|
|
52
|
+
{
|
|
53
|
+
name: 'Public',
|
|
54
|
+
subnetType: ec2.SubnetType.PUBLIC,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Isolated',
|
|
58
|
+
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Add EC2 instance (NEW)
|
|
64
|
+
new ec2.Instance(this, 'MyInstance', {
|
|
65
|
+
vpc,
|
|
66
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
|
|
67
|
+
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM),
|
|
68
|
+
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Add RDS database (NEW)
|
|
72
|
+
new rds.DatabaseInstance(this, 'MyDatabase', {
|
|
73
|
+
engine: rds.DatabaseInstanceEngine.postgres({
|
|
74
|
+
version: rds.PostgresEngineVersion.VER_15,
|
|
75
|
+
}),
|
|
76
|
+
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
|
|
77
|
+
vpc,
|
|
78
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
|
|
79
|
+
allocatedStorage: 20,
|
|
80
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
81
|
+
deletionProtection: false,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const app = new cdk.App();
|
|
87
|
+
|
|
88
|
+
// Synthesize based on context
|
|
89
|
+
const stackType = app.node.tryGetContext('stack') || 'base';
|
|
90
|
+
|
|
91
|
+
const env = {
|
|
92
|
+
account: '585008061383',
|
|
93
|
+
region: 'eu-central-1',
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (stackType === 'base') {
|
|
97
|
+
new BaseStack(app, 'ComputeStack', { env });
|
|
98
|
+
} else {
|
|
99
|
+
new TargetStack(app, 'ComputeStack', { env });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
app.synth();
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const cdk = require('aws-cdk-lib');
|
|
3
|
+
const { Stack } = require('aws-cdk-lib');
|
|
4
|
+
const ec2 = require('aws-cdk-lib/aws-ec2');
|
|
5
|
+
const s3 = require('aws-cdk-lib/aws-s3');
|
|
6
|
+
const lambda = require('aws-cdk-lib/aws-lambda');
|
|
7
|
+
const rds = require('aws-cdk-lib/aws-rds');
|
|
8
|
+
|
|
9
|
+
// Base Stack - Current infrastructure
|
|
10
|
+
class BaseStack extends Stack {
|
|
11
|
+
constructor(scope, id, props) {
|
|
12
|
+
super(scope, id, props);
|
|
13
|
+
|
|
14
|
+
// Simple S3 bucket
|
|
15
|
+
new s3.Bucket(this, 'MyBucket', {
|
|
16
|
+
bucketName: 'my-test-bucket-base',
|
|
17
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Lambda function with 128MB
|
|
21
|
+
new lambda.Function(this, 'MyFunction', {
|
|
22
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
23
|
+
handler: 'index.handler',
|
|
24
|
+
code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
|
|
25
|
+
memorySize: 128,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Target Stack - Proposed changes
|
|
31
|
+
class TargetStack extends Stack {
|
|
32
|
+
constructor(scope, id, props) {
|
|
33
|
+
super(scope, id, props);
|
|
34
|
+
|
|
35
|
+
// Keep the S3 bucket
|
|
36
|
+
new s3.Bucket(this, 'MyBucket', {
|
|
37
|
+
bucketName: 'my-test-bucket-base',
|
|
38
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Upgrade Lambda to 512MB (MODIFIED)
|
|
42
|
+
new lambda.Function(this, 'MyFunction', {
|
|
43
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
44
|
+
handler: 'index.handler',
|
|
45
|
+
code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
|
|
46
|
+
memorySize: 1024,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Add another Lambda function (NEW)
|
|
50
|
+
new lambda.Function(this, 'MyNewFunction', {
|
|
51
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
52
|
+
handler: 'index.handler',
|
|
53
|
+
code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
|
|
54
|
+
memorySize: 2560,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Add another S3 bucket (NEW)
|
|
58
|
+
new s3.Bucket(this, 'MyNewBucket', {
|
|
59
|
+
bucketName: 'my-test-bucket-new',
|
|
60
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const app = new cdk.App();
|
|
66
|
+
|
|
67
|
+
// Synthesize based on context
|
|
68
|
+
const stackType = app.node.tryGetContext('stack') || 'base';
|
|
69
|
+
|
|
70
|
+
const env = {
|
|
71
|
+
account: '585008061383',
|
|
72
|
+
region: 'eu-central-1'
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
if (stackType === 'base') {
|
|
76
|
+
new BaseStack(app, 'TestStack', { env });
|
|
77
|
+
} else {
|
|
78
|
+
new TargetStack(app, 'TestStack', { env });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
app.synth();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "48.0.0",
|
|
3
|
+
"files": {
|
|
4
|
+
"fef4e5534aeeda5c83d0ba81f82463fe8d00a64e197ca90e146f1a90694b23e2": {
|
|
5
|
+
"displayName": "TestStack Template",
|
|
6
|
+
"source": {
|
|
7
|
+
"path": "TestStack.template.json",
|
|
8
|
+
"packaging": "file"
|
|
9
|
+
},
|
|
10
|
+
"destinations": {
|
|
11
|
+
"585008061383-eu-central-1-c1c9545d": {
|
|
12
|
+
"bucketName": "cdk-hnb659fds-assets-585008061383-eu-central-1",
|
|
13
|
+
"objectKey": "fef4e5534aeeda5c83d0ba81f82463fe8d00a64e197ca90e146f1a90694b23e2.json",
|
|
14
|
+
"region": "eu-central-1",
|
|
15
|
+
"assumeRoleArn": "arn:${AWS::Partition}:iam::585008061383:role/cdk-hnb659fds-file-publishing-role-585008061383-eu-central-1"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"dockerImages": {}
|
|
21
|
+
}
|