terruvim-core-test 0.0.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 (199) hide show
  1. package/dist/src/core/config.js +2 -0
  2. package/dist/src/core/configMerge.js +266 -0
  3. package/dist/src/core/configUtils.js +72 -0
  4. package/dist/src/core/dependencyResolver.js +17 -0
  5. package/dist/src/core/deployUtils.js +73 -0
  6. package/dist/src/core/dynamicResourceManager.js +709 -0
  7. package/dist/src/core/entrypoint.js +56 -0
  8. package/dist/src/core/generateFinalConfig.js +45 -0
  9. package/dist/src/core/index.js +24 -0
  10. package/dist/src/core/resourceMap.js +99 -0
  11. package/dist/src/factories/accountPermissions.js +134 -0
  12. package/dist/src/factories/acmFactory.js +30 -0
  13. package/dist/src/factories/albFactory.js +331 -0
  14. package/dist/src/factories/attachSecretAccessPolicy.js +56 -0
  15. package/dist/src/factories/auroraFactory.js +619 -0
  16. package/dist/src/factories/backupPolicy.js +152 -0
  17. package/dist/src/factories/bastionFactory.js +91 -0
  18. package/dist/src/factories/bedrockFactory.js +334 -0
  19. package/dist/src/factories/budgetFactory.js +64 -0
  20. package/dist/src/factories/buildAlbCloudWatchAlarmsHelper.js +79 -0
  21. package/dist/src/factories/buildAlbCloudWatchDashboardHelper.js +106 -0
  22. package/dist/src/factories/buildAlbListenerRulesHelper.js +45 -0
  23. package/dist/src/factories/buildAlbListenersHelper.js +64 -0
  24. package/dist/src/factories/buildAlbResourceHelper.js +54 -0
  25. package/dist/src/factories/buildAlbRoute53RecordHelper.js +49 -0
  26. package/dist/src/factories/buildAlbTargetGroupsHelper.js +47 -0
  27. package/dist/src/factories/buildAlbWafAssociationHelper.js +43 -0
  28. package/dist/src/factories/buildAndPushDockerImage.js +57 -0
  29. package/dist/src/factories/buildAwsCloudWatchAlarmsHelper.js +118 -0
  30. package/dist/src/factories/buildCloudFrontRoute53RecordHelper.js +49 -0
  31. package/dist/src/factories/buildEcsClusterArgs.js +32 -0
  32. package/dist/src/factories/buildEcsSecrets.js +48 -0
  33. package/dist/src/factories/buildForceRedeployEnv.js +8 -0
  34. package/dist/src/factories/buildResourceOptions.js +11 -0
  35. package/dist/src/factories/buildS3StaticHostingCicdHelper.js +142 -0
  36. package/dist/src/factories/buildS3StaticHostingCloudWatchDashboardHelper.js +122 -0
  37. package/dist/src/factories/cloudTrailFactory.js +22 -0
  38. package/dist/src/factories/cloudWatchCompositeAlarmFactory.js +91 -0
  39. package/dist/src/factories/cloudWatchInsightsQueryFactory.js +83 -0
  40. package/dist/src/factories/cloudWatchLogGroupFactory.js +84 -0
  41. package/dist/src/factories/cloudfrontCodePipelineFactory.js +357 -0
  42. package/dist/src/factories/cloudwatchAlarmsFactory.js +121 -0
  43. package/dist/src/factories/codePipelineNotificationFactory.js +193 -0
  44. package/dist/src/factories/codePipelineNotificationRulesFactory.js +117 -0
  45. package/dist/src/factories/codeStarConnectionFactory.js +56 -0
  46. package/dist/src/factories/collectSecretKeys.js +18 -0
  47. package/dist/src/factories/comprehensiveNotificationFactory.js +250 -0
  48. package/dist/src/factories/costAndUsageReportFactory.js +32 -0
  49. package/dist/src/factories/createAwsAcmCertificate.js +40 -0
  50. package/dist/src/factories/createAwsBudget.js +40 -0
  51. package/dist/src/factories/createAwsCloudTrail.js +59 -0
  52. package/dist/src/factories/createAwsCloudwatchDashboard.js +59 -0
  53. package/dist/src/factories/createAwsEc2Instance.js +40 -0
  54. package/dist/src/factories/createAwsEventBridgeEventBus.js +40 -0
  55. package/dist/src/factories/createAwsGuardDutyDetector.js +40 -0
  56. package/dist/src/factories/createAwsGuardDutyDetectorFeature.js +45 -0
  57. package/dist/src/factories/createAwsGuardDutyFilter.js +46 -0
  58. package/dist/src/factories/createAwsGuardDutyPublishingDestination.js +50 -0
  59. package/dist/src/factories/createAwsHostedZone.js +40 -0
  60. package/dist/src/factories/createAwsIamRole.js +49 -0
  61. package/dist/src/factories/createAwsIamRoleInlinePolicies.js +48 -0
  62. package/dist/src/factories/createAwsIdentitystoreGroup.js +44 -0
  63. package/dist/src/factories/createAwsIdentitystoreGroupMembership.js +56 -0
  64. package/dist/src/factories/createAwsIdentitystoreUser.js +47 -0
  65. package/dist/src/factories/createAwsInspectorAssessmentTarget.js +47 -0
  66. package/dist/src/factories/createAwsInspectorDelegatedAdminAccount.js +47 -0
  67. package/dist/src/factories/createAwsInspectorEnabler.js +49 -0
  68. package/dist/src/factories/createAwsInspectorOrganizationConfiguration.js +55 -0
  69. package/dist/src/factories/createAwsKmsAliases.js +47 -0
  70. package/dist/src/factories/createAwsKmsKey.js +51 -0
  71. package/dist/src/factories/createAwsMacieAccount.js +45 -0
  72. package/dist/src/factories/createAwsMacieClassificationJob.js +53 -0
  73. package/dist/src/factories/createAwsMacieMember.js +49 -0
  74. package/dist/src/factories/createAwsMacieOrganizationConfiguration.js +44 -0
  75. package/dist/src/factories/createAwsRdsCluster.js +40 -0
  76. package/dist/src/factories/createAwsRdsClusterInstance.js +40 -0
  77. package/dist/src/factories/createAwsRdsInstance.js +40 -0
  78. package/dist/src/factories/createAwsRdsSubnetGroup.js +40 -0
  79. package/dist/src/factories/createAwsRoute53Record.js +40 -0
  80. package/dist/src/factories/createAwsSecret.js +40 -0
  81. package/dist/src/factories/createAwsSecretRotation.js +40 -0
  82. package/dist/src/factories/createAwsSecretVersion.js +40 -0
  83. package/dist/src/factories/createAwsSecurityGroup.js +40 -0
  84. package/dist/src/factories/createAwsSecurityGroupRule.js +40 -0
  85. package/dist/src/factories/createAwsSecurityHubAccount.js +40 -0
  86. package/dist/src/factories/createAwsSecurityHubAutomationRule.js +48 -0
  87. package/dist/src/factories/createAwsSecurityHubStandardsControl.js +44 -0
  88. package/dist/src/factories/createAwsSecurityHubStandardsSubscription.js +42 -0
  89. package/dist/src/factories/createAwsSesDomainDkim.js +40 -0
  90. package/dist/src/factories/createAwsSesDomainIdentity.js +40 -0
  91. package/dist/src/factories/createAwsSesEmailIdentity.js +40 -0
  92. package/dist/src/factories/createAwsSnsSubscription.js +62 -0
  93. package/dist/src/factories/createAwsSnsTopic.js +41 -0
  94. package/dist/src/factories/createAwsSqsQueue.js +40 -0
  95. package/dist/src/factories/createAwsSsmParameters.js +66 -0
  96. package/dist/src/factories/createAwsSsoAccountAssignment.js +66 -0
  97. package/dist/src/factories/createAwsSsoPermissionSet.js +64 -0
  98. package/dist/src/factories/createAwsStepFunctionsStateMachine.js +40 -0
  99. package/dist/src/factories/createBudget.js +56 -0
  100. package/dist/src/factories/createBudgetWithSnsAlert.js +79 -0
  101. package/dist/src/factories/createCostAndUsageReport.js +40 -0
  102. package/dist/src/factories/createEcrRepo.js +69 -0
  103. package/dist/src/factories/createEcsRolesAndPolicies.js +84 -0
  104. package/dist/src/factories/createEcsService.js +71 -0
  105. package/dist/src/factories/createEnvSecret.js +60 -0
  106. package/dist/src/factories/createGithubCodeStarConnection.js +44 -0
  107. package/dist/src/factories/createIamUserWithAccessKey.js +44 -0
  108. package/dist/src/factories/createLambdaFunction.js +89 -0
  109. package/dist/src/factories/createLambdaPermission.js +57 -0
  110. package/dist/src/factories/createListenerRule.js +68 -0
  111. package/dist/src/factories/createLogGroup.js +44 -0
  112. package/dist/src/factories/createSlackChannelConfiguration.js +49 -0
  113. package/dist/src/factories/createTargetGroup.js +50 -0
  114. package/dist/src/factories/createTaskDefinition.js +49 -0
  115. package/dist/src/factories/createVpcEndpoint.js +49 -0
  116. package/dist/src/factories/dashboardFactory.js +94 -0
  117. package/dist/src/factories/dataProtectionPolicyBuilder.js +103 -0
  118. package/dist/src/factories/ec2Factory.js +67 -0
  119. package/dist/src/factories/ecsClusterFactory.js +90 -0
  120. package/dist/src/factories/ecsCodePipelineFactory.js +308 -0
  121. package/dist/src/factories/ecsServiceFactory.js +350 -0
  122. package/dist/src/factories/enhancedCloudFrontCodePipelineFactory.js +205 -0
  123. package/dist/src/factories/enhancedEcsCodePipelineFactory.js +189 -0
  124. package/dist/src/factories/eventBridgeBusFactory.js +84 -0
  125. package/dist/src/factories/eventBridgeFactory.js +26 -0
  126. package/dist/src/factories/eventBridgeRuleFactory.js +114 -0
  127. package/dist/src/factories/fetchAllSecrets.js +51 -0
  128. package/dist/src/factories/getDeterministicPriority.js +13 -0
  129. package/dist/src/factories/getOrCreateSshKeyPair.js +57 -0
  130. package/dist/src/factories/guardDutyFactory.js +151 -0
  131. package/dist/src/factories/hostedZoneFactory.js +30 -0
  132. package/dist/src/factories/iamRoleFactory.js +29 -0
  133. package/dist/src/factories/inspectorFactory.js +109 -0
  134. package/dist/src/factories/kmsKeyFactory.js +32 -0
  135. package/dist/src/factories/lambdaFactory.js +133 -0
  136. package/dist/src/factories/lambdaPermissionFactory.js +32 -0
  137. package/dist/src/factories/logDataProtectionPolicyFactory.js +81 -0
  138. package/dist/src/factories/macieFactory.js +85 -0
  139. package/dist/src/factories/networkingFactory.js +429 -0
  140. package/dist/src/factories/opensearchCollectionFactory.js +109 -0
  141. package/dist/src/factories/organizationFactory.js +221 -0
  142. package/dist/src/factories/processReservedInstances.js +6 -0
  143. package/dist/src/factories/processSavingsPlans.js +43 -0
  144. package/dist/src/factories/rdsFactory.js +40 -0
  145. package/dist/src/factories/recordFactory.js +36 -0
  146. package/dist/src/factories/resolveEnvSecrets.js +14 -0
  147. package/dist/src/factories/resourceFactory.js +12 -0
  148. package/dist/src/factories/s3Factory.js +262 -0
  149. package/dist/src/factories/s3StaticHostingFactory.backup.js +424 -0
  150. package/dist/src/factories/s3StaticHostingFactory.js +348 -0
  151. package/dist/src/factories/s3StaticHostingFactory.refactored.js +334 -0
  152. package/dist/src/factories/savingsPlanFactory.js +26 -0
  153. package/dist/src/factories/secretsManagerFactory.js +107 -0
  154. package/dist/src/factories/securityGroupFactory.js +28 -0
  155. package/dist/src/factories/securityGroupRuleFactory.js +43 -0
  156. package/dist/src/factories/securityHubFactory.js +96 -0
  157. package/dist/src/factories/sesDomainDkimFactory.js +25 -0
  158. package/dist/src/factories/sesFactory.js +25 -0
  159. package/dist/src/factories/sesIdentitiesFactory.js +134 -0
  160. package/dist/src/factories/simpleNotificationFactory.js +112 -0
  161. package/dist/src/factories/smtpUserFactory.js +108 -0
  162. package/dist/src/factories/snsFactory.js +87 -0
  163. package/dist/src/factories/sqsFactory.js +41 -0
  164. package/dist/src/factories/ssmParameterFactory.js +67 -0
  165. package/dist/src/factories/ssoFactory.js +32 -0
  166. package/dist/src/factories/ssoGroupFactory.js +41 -0
  167. package/dist/src/factories/ssoPermissionSetFactory.js +29 -0
  168. package/dist/src/factories/ssoUserFactory.js +30 -0
  169. package/dist/src/factories/stepFunctionsFactory.js +32 -0
  170. package/dist/src/factories/tagPolicies.js +99 -0
  171. package/dist/src/factories/transformBudgetCostFilters.js +8 -0
  172. package/dist/src/factories/transformBudgetNotifications.js +12 -0
  173. package/dist/src/factories/transformBudgetPlannedLimits.js +8 -0
  174. package/dist/src/factories/types.js +2 -0
  175. package/dist/src/factories/validateAcmConfig.js +26 -0
  176. package/dist/src/factories/validateAuroraConfig.js +8 -0
  177. package/dist/src/factories/validateBedrockConfig.js +124 -0
  178. package/dist/src/factories/validateDashboardConfig.js +28 -0
  179. package/dist/src/factories/validateEventBridgeConfig.js +14 -0
  180. package/dist/src/factories/validateHostedZoneConfig.js +26 -0
  181. package/dist/src/factories/validateIamRoleConfig.js +8 -0
  182. package/dist/src/factories/validateKmsKeyConfig.js +8 -0
  183. package/dist/src/factories/validateRdsConfig.js +17 -0
  184. package/dist/src/factories/validateRoute53RecordConfig.js +41 -0
  185. package/dist/src/factories/validateS3Config.js +8 -0
  186. package/dist/src/factories/validateSecretsManagerConfig.js +8 -0
  187. package/dist/src/factories/validateSecurityGroupConfig.js +8 -0
  188. package/dist/src/factories/validateSecurityGroupRuleConfig.js +8 -0
  189. package/dist/src/factories/validateSesDomainDkimConfig.js +8 -0
  190. package/dist/src/factories/validateSesDomainIdentityConfig.js +8 -0
  191. package/dist/src/factories/validateSesIdentitiesConfig.js +40 -0
  192. package/dist/src/factories/validateSnsConfig.js +11 -0
  193. package/dist/src/factories/validateSqsConfig.js +11 -0
  194. package/dist/src/factories/validateSsmParameterFactoryConfig.js +9 -0
  195. package/dist/src/factories/validateStepFunctionsConfig.js +8 -0
  196. package/dist/src/factories/vpcEndpointFactory.js +98 -0
  197. package/dist/src/factories/wafFactory.js +499 -0
  198. package/package.json +71 -0
  199. package/scripts/copy-assets.js +136 -0
@@ -0,0 +1,499 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.WafFactory = void 0;
37
+ const aws = __importStar(require("@pulumi/aws"));
38
+ const pulumi = __importStar(require("@pulumi/pulumi"));
39
+ class WafFactory {
40
+ static createWaf(config, provider) {
41
+ const resourceName = config.name;
42
+ const providerOptions = provider ? { provider } : undefined;
43
+ const ipSets = WafFactory.createIpSets(config, provider);
44
+ const rules = WafFactory.buildWafRules(config, ipSets);
45
+ const webAcl = new aws.wafv2.WebAcl(resourceName, {
46
+ scope: config.scope,
47
+ description: config.description || `WAF for ${config.name}`,
48
+ defaultAction: config.defaultAction === "allow" ? { allow: {} } : { block: {} },
49
+ rules,
50
+ visibilityConfig: {
51
+ cloudwatchMetricsEnabled: config.visibilityConfig?.cloudwatchMetricsEnabled ?? true,
52
+ sampledRequestsEnabled: config.visibilityConfig?.sampledRequestsEnabled ?? true,
53
+ metricName: config.visibilityConfig?.metricName || `${config.name}-waf`,
54
+ },
55
+ tags: config.tags,
56
+ }, providerOptions);
57
+ if (config.logging?.enabled) {
58
+ WafFactory.setupWafLogging(config, webAcl, provider);
59
+ }
60
+ return webAcl;
61
+ }
62
+ static createIpSets(config, provider) {
63
+ const providerOptions = provider ? { provider } : undefined;
64
+ const ipSets = {};
65
+ if (config.ipRestrictions?.blockedIps?.length) {
66
+ ipSets.blockedIps = new aws.wafv2.IpSet(`${config.name}-blocked-ips`, {
67
+ scope: config.scope,
68
+ ipAddressVersion: "IPV4",
69
+ addresses: config.ipRestrictions.blockedIps,
70
+ description: "Blocked IP addresses",
71
+ tags: config.tags,
72
+ }, providerOptions);
73
+ }
74
+ if (config.ipRestrictions?.allowedIps?.length) {
75
+ ipSets.allowedIps = new aws.wafv2.IpSet(`${config.name}-allowed-ips`, {
76
+ scope: config.scope,
77
+ ipAddressVersion: "IPV4",
78
+ addresses: config.ipRestrictions.allowedIps,
79
+ description: "Allowed IP addresses",
80
+ tags: config.tags,
81
+ }, providerOptions);
82
+ }
83
+ return ipSets;
84
+ }
85
+ static buildWafRules(config, ipSets) {
86
+ const rules = [];
87
+ let priority = 1;
88
+ if (ipSets.allowedIps) {
89
+ rules.push({
90
+ name: "AllowedIPs",
91
+ priority: priority++,
92
+ action: { allow: {} },
93
+ statement: {
94
+ ipSetReferenceStatement: {
95
+ arn: ipSets.allowedIps.arn,
96
+ },
97
+ },
98
+ visibilityConfig: {
99
+ cloudwatchMetricsEnabled: true,
100
+ sampledRequestsEnabled: true,
101
+ metricName: `${config.name}-allowed-ips`,
102
+ },
103
+ });
104
+ }
105
+ if (ipSets.blockedIps) {
106
+ rules.push({
107
+ name: "BlockedIPs",
108
+ priority: priority++,
109
+ action: { block: {} },
110
+ statement: {
111
+ ipSetReferenceStatement: {
112
+ arn: ipSets.blockedIps.arn,
113
+ },
114
+ },
115
+ visibilityConfig: {
116
+ cloudwatchMetricsEnabled: true,
117
+ sampledRequestsEnabled: true,
118
+ metricName: `${config.name}-blocked-ips`,
119
+ },
120
+ });
121
+ }
122
+ if (config.geoRestrictions?.blockedCountries?.length) {
123
+ rules.push({
124
+ name: "GeoBlocking",
125
+ priority: priority++,
126
+ action: { block: {} },
127
+ statement: {
128
+ geoMatchStatement: {
129
+ countryCodes: config.geoRestrictions.blockedCountries,
130
+ },
131
+ },
132
+ visibilityConfig: {
133
+ cloudwatchMetricsEnabled: true,
134
+ sampledRequestsEnabled: true,
135
+ metricName: `${config.name}-geo-blocking`,
136
+ },
137
+ });
138
+ }
139
+ if (config.rateLimiting?.enabled) {
140
+ rules.push({
141
+ name: "RateLimiting",
142
+ priority: priority++,
143
+ action: config.rateLimiting.action === "block" ? { block: {} } : { count: {} },
144
+ statement: {
145
+ rateBasedStatement: {
146
+ limit: config.rateLimiting.limit,
147
+ aggregateKeyType: "IP",
148
+ },
149
+ },
150
+ visibilityConfig: {
151
+ cloudwatchMetricsEnabled: true,
152
+ sampledRequestsEnabled: true,
153
+ metricName: `${config.name}-rate-limiting`,
154
+ },
155
+ });
156
+ }
157
+ if (config.managedRuleGroups?.length) {
158
+ for (const ruleGroup of config.managedRuleGroups) {
159
+ const excludedRules = ruleGroup.excludedRules?.map(rule => ({
160
+ name: rule,
161
+ })) || [];
162
+ rules.push({
163
+ name: `ManagedRuleGroup-${ruleGroup.name}`,
164
+ priority: priority++,
165
+ overrideAction: ruleGroup.overrideAction === "count" ? { count: {} } : undefined,
166
+ statement: {
167
+ managedRuleGroupStatement: {
168
+ vendorName: ruleGroup.vendorName,
169
+ name: ruleGroup.name,
170
+ version: ruleGroup.version,
171
+ },
172
+ },
173
+ visibilityConfig: {
174
+ cloudwatchMetricsEnabled: true,
175
+ sampledRequestsEnabled: true,
176
+ metricName: `${config.name}-${ruleGroup.name.toLowerCase()}`,
177
+ },
178
+ });
179
+ }
180
+ }
181
+ if (config.sqlInjectionProtection?.enabled) {
182
+ const fieldToMatch = config.sqlInjectionProtection.fieldToMatch || [
183
+ { type: "uri" },
184
+ { type: "query-string" },
185
+ { type: "body" },
186
+ ];
187
+ for (const field of fieldToMatch) {
188
+ rules.push({
189
+ name: `SQLInjectionProtection-${field.type}`,
190
+ priority: priority++,
191
+ action: config.sqlInjectionProtection.action === "block" ? { block: {} } : { count: {} },
192
+ statement: {
193
+ sqliMatchStatement: {
194
+ fieldToMatch: WafFactory.buildFieldToMatch(field),
195
+ textTransformations: [
196
+ { type: "URL_DECODE", priority: 1 },
197
+ { type: "HTML_ENTITY_DECODE", priority: 2 },
198
+ ],
199
+ },
200
+ },
201
+ visibilityConfig: {
202
+ cloudwatchMetricsEnabled: true,
203
+ sampledRequestsEnabled: true,
204
+ metricName: `${config.name}-sqli-${field.type}`,
205
+ },
206
+ });
207
+ }
208
+ }
209
+ if (config.xssProtection?.enabled) {
210
+ const fieldToMatch = config.xssProtection.fieldToMatch || [
211
+ { type: "uri" },
212
+ { type: "query-string" },
213
+ { type: "body" },
214
+ ];
215
+ for (const field of fieldToMatch) {
216
+ rules.push({
217
+ name: `XSSProtection-${field.type}`,
218
+ priority: priority++,
219
+ action: config.xssProtection.action === "block" ? { block: {} } : { count: {} },
220
+ statement: {
221
+ xssMatchStatement: {
222
+ fieldToMatch: WafFactory.buildFieldToMatch(field),
223
+ textTransformations: [
224
+ { type: "URL_DECODE", priority: 1 },
225
+ { type: "HTML_ENTITY_DECODE", priority: 2 },
226
+ ],
227
+ },
228
+ },
229
+ visibilityConfig: {
230
+ cloudwatchMetricsEnabled: true,
231
+ sampledRequestsEnabled: true,
232
+ metricName: `${config.name}-xss-${field.type}`,
233
+ },
234
+ });
235
+ }
236
+ }
237
+ if (config.sizeRestrictions?.enabled) {
238
+ if (config.sizeRestrictions.maxBodySize) {
239
+ rules.push({
240
+ name: "BodySizeRestriction",
241
+ priority: priority++,
242
+ action: config.sizeRestrictions.action === "block" ? { block: {} } : { count: {} },
243
+ statement: {
244
+ sizeConstraintStatement: {
245
+ fieldToMatch: { body: {} },
246
+ comparisonOperator: "GT",
247
+ size: config.sizeRestrictions.maxBodySize,
248
+ textTransformations: [{ type: "NONE", priority: 0 }],
249
+ },
250
+ },
251
+ visibilityConfig: {
252
+ cloudwatchMetricsEnabled: true,
253
+ sampledRequestsEnabled: true,
254
+ metricName: `${config.name}-body-size`,
255
+ },
256
+ });
257
+ }
258
+ if (config.sizeRestrictions.maxUriSize) {
259
+ rules.push({
260
+ name: "URISizeRestriction",
261
+ priority: priority++,
262
+ action: config.sizeRestrictions.action === "block" ? { block: {} } : { count: {} },
263
+ statement: {
264
+ sizeConstraintStatement: {
265
+ fieldToMatch: { uriPath: {} },
266
+ comparisonOperator: "GT",
267
+ size: config.sizeRestrictions.maxUriSize,
268
+ textTransformations: [{ type: "NONE", priority: 0 }],
269
+ },
270
+ },
271
+ visibilityConfig: {
272
+ cloudwatchMetricsEnabled: true,
273
+ sampledRequestsEnabled: true,
274
+ metricName: `${config.name}-uri-size`,
275
+ },
276
+ });
277
+ }
278
+ }
279
+ if (config.customRegexRules?.length) {
280
+ for (const regexRule of config.customRegexRules) {
281
+ rules.push({
282
+ name: regexRule.name,
283
+ priority: priority++,
284
+ action: regexRule.action === "block" ? { block: {} } : { count: {} },
285
+ statement: {
286
+ regexMatchStatement: {
287
+ regexString: regexRule.regex,
288
+ fieldToMatch: WafFactory.buildFieldToMatch(regexRule.fieldToMatch),
289
+ textTransformations: [
290
+ { type: "URL_DECODE", priority: 1 },
291
+ { type: "LOWERCASE", priority: 2 },
292
+ ],
293
+ },
294
+ },
295
+ visibilityConfig: {
296
+ cloudwatchMetricsEnabled: true,
297
+ sampledRequestsEnabled: true,
298
+ metricName: `${config.name}-${regexRule.name.toLowerCase()}`,
299
+ },
300
+ });
301
+ }
302
+ }
303
+ if (config.rules?.length) {
304
+ for (const rule of config.rules) {
305
+ rules.push(WafFactory.buildCustomRule(config.name, rule));
306
+ }
307
+ }
308
+ return rules;
309
+ }
310
+ static buildFieldToMatch(field) {
311
+ switch (field.type) {
312
+ case "uri":
313
+ return { uriPath: {} };
314
+ case "query-string":
315
+ return { queryString: {} };
316
+ case "header":
317
+ return { singleHeader: { name: field.name.toLowerCase() } };
318
+ case "body":
319
+ return { body: {} };
320
+ case "method":
321
+ return { method: {} };
322
+ case "all-query-arguments":
323
+ return { allQueryArguments: {} };
324
+ default:
325
+ return { uriPath: {} };
326
+ }
327
+ }
328
+ static buildCustomRule(wafName, rule) {
329
+ const ruleConfig = {
330
+ name: rule.name,
331
+ priority: rule.priority,
332
+ statement: {},
333
+ visibilityConfig: {
334
+ cloudwatchMetricsEnabled: true,
335
+ sampledRequestsEnabled: true,
336
+ metricName: `${wafName}-${rule.name.toLowerCase()}`,
337
+ },
338
+ };
339
+ if (rule.overrideAction && rule.overrideAction === "count") {
340
+ ruleConfig.overrideAction = { count: {} };
341
+ }
342
+ else {
343
+ ruleConfig.action =
344
+ rule.action === "allow" ? { allow: {} } :
345
+ rule.action === "block" ? { block: {} } : { count: {} };
346
+ }
347
+ switch (rule.statement.type) {
348
+ case "rate-limit":
349
+ ruleConfig.statement = {
350
+ rateBasedStatement: {
351
+ limit: rule.statement.limit || 2000,
352
+ aggregateKeyType: "IP",
353
+ },
354
+ };
355
+ break;
356
+ case "sql-injection":
357
+ ruleConfig.statement = {
358
+ sqliMatchStatement: {
359
+ fieldToMatch: rule.statement.fieldToMatch ?
360
+ WafFactory.buildFieldToMatch(rule.statement.fieldToMatch) : { uriPath: {} },
361
+ textTransformations: rule.statement.textTransformations?.map(t => ({
362
+ type: t.type.toUpperCase().replace(/-/g, "_"),
363
+ priority: t.priority,
364
+ })) || [{ type: "URL_DECODE", priority: 1 }],
365
+ },
366
+ };
367
+ break;
368
+ case "xss":
369
+ ruleConfig.statement = {
370
+ xssMatchStatement: {
371
+ fieldToMatch: rule.statement.fieldToMatch ?
372
+ WafFactory.buildFieldToMatch(rule.statement.fieldToMatch) : { uriPath: {} },
373
+ textTransformations: rule.statement.textTransformations?.map(t => ({
374
+ type: t.type.toUpperCase().replace(/-/g, "_"),
375
+ priority: t.priority,
376
+ })) || [{ type: "URL_DECODE", priority: 1 }],
377
+ },
378
+ };
379
+ break;
380
+ case "managed-rule-group":
381
+ if (rule.statement.managedRuleGroup) {
382
+ ruleConfig.statement = {
383
+ managedRuleGroupStatement: {
384
+ vendorName: rule.statement.managedRuleGroup.vendorName,
385
+ name: rule.statement.managedRuleGroup.name,
386
+ version: rule.statement.managedRuleGroup.version,
387
+ },
388
+ };
389
+ }
390
+ break;
391
+ }
392
+ return ruleConfig;
393
+ }
394
+ static setupWafLogging(config, webAcl, provider) {
395
+ const providerOptions = provider ? { provider } : undefined;
396
+ const logGroup = new aws.cloudwatch.LogGroup(`${config.name}-waf-logs`, {
397
+ name: config.logging.logGroupName || `aws-waf-logs-${config.name}`,
398
+ retentionInDays: config.logging.retentionDays || 365,
399
+ tags: config.tags,
400
+ }, providerOptions);
401
+ const loggingConfig = new aws.wafv2.WebAclLoggingConfiguration(`${config.name}-waf-logging`, {
402
+ resourceArn: webAcl.arn,
403
+ logDestinationConfigs: [pulumi.interpolate `${logGroup.arn}:*`],
404
+ }, providerOptions);
405
+ }
406
+ static createSecureWafConfig(name, scope) {
407
+ return {
408
+ name,
409
+ scope,
410
+ description: `Enterprise-grade WAF security for ${name}`,
411
+ defaultAction: "allow",
412
+ rateLimiting: {
413
+ enabled: true,
414
+ limit: 2000,
415
+ action: "block",
416
+ },
417
+ sqlInjectionProtection: {
418
+ enabled: true,
419
+ action: "block",
420
+ fieldToMatch: [
421
+ { type: "uri" },
422
+ { type: "query-string" },
423
+ { type: "body" },
424
+ { type: "header", name: "authorization" },
425
+ ],
426
+ },
427
+ xssProtection: {
428
+ enabled: true,
429
+ action: "block",
430
+ fieldToMatch: [
431
+ { type: "uri" },
432
+ { type: "query-string" },
433
+ { type: "body" },
434
+ ],
435
+ },
436
+ sizeRestrictions: {
437
+ enabled: true,
438
+ maxBodySize: 8192000,
439
+ maxUriSize: 8192,
440
+ action: "block",
441
+ },
442
+ managedRuleGroups: [
443
+ {
444
+ name: "AWSManagedRulesCommonRuleSet",
445
+ vendorName: "AWS",
446
+ overrideAction: "count",
447
+ },
448
+ {
449
+ name: "AWSManagedRulesKnownBadInputsRuleSet",
450
+ vendorName: "AWS",
451
+ overrideAction: "count",
452
+ },
453
+ {
454
+ name: "AWSManagedRulesSQLiRuleSet",
455
+ vendorName: "AWS",
456
+ overrideAction: "count",
457
+ },
458
+ {
459
+ name: "AWSManagedRulesLinuxRuleSet",
460
+ vendorName: "AWS",
461
+ overrideAction: "count",
462
+ },
463
+ {
464
+ name: "AWSManagedRulesAmazonIpReputationList",
465
+ vendorName: "AWS",
466
+ overrideAction: "count",
467
+ },
468
+ {
469
+ name: "AWSManagedRulesAnonymousIpList",
470
+ vendorName: "AWS",
471
+ overrideAction: "count",
472
+ },
473
+ ],
474
+ customRegexRules: [
475
+ {
476
+ name: "BlockScanningTools",
477
+ regex: "(nikto|nmap|sqlmap|burp|acunetix|nessus|openvas|w3af|skipfish|sqlninja)",
478
+ action: "block",
479
+ fieldToMatch: { type: "header", name: "user-agent" },
480
+ },
481
+ {
482
+ name: "BlockSuspiciousPatterns",
483
+ regex: "(union.select|script.alert|javascript:|vbscript:|onload=|onerror=)",
484
+ action: "block",
485
+ fieldToMatch: { type: "uri" },
486
+ },
487
+ ],
488
+ logging: {
489
+ enabled: true,
490
+ retentionDays: 365,
491
+ },
492
+ visibilityConfig: {
493
+ cloudwatchMetricsEnabled: true,
494
+ sampledRequestsEnabled: true,
495
+ },
496
+ };
497
+ }
498
+ }
499
+ exports.WafFactory = WafFactory;
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "terruvim-core-test",
3
+ "version": "0.0.1",
4
+ "description": "Core logic for Terruvim framework TEST",
5
+ "private": false,
6
+ "main": "dist/src/core/entrypoint.js",
7
+ "types": "dist/src/core/entrypoint.d.ts",
8
+ "bin": {
9
+ "terruvim": "./scripts/copy-assets.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "up": "pulumi up",
14
+ "preview": "pulumi preview",
15
+ "destroy": "pulumi destroy"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "terruvim",
22
+ "core"
23
+ ],
24
+ "author": [
25
+ "Vlad Vorobei",
26
+ "Anton Kolvakh"
27
+ ],
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@aws-sdk/client-dynamodb": "^3.835.0",
31
+ "@aws-sdk/client-s3": "^3.837.0",
32
+ "@aws-sdk/client-sns": "^3.835.0",
33
+ "@aws-sdk/lib-dynamodb": "^3.835.0",
34
+ "@pulumi/aws": "^6.83.0",
35
+ "@pulumi/aws-apigateway": "^2.6.2",
36
+ "@pulumi/awsx": "^2.22.0",
37
+ "@pulumi/cloud-aws": "^0.40.2",
38
+ "@pulumi/command": "^1.1.0",
39
+ "@pulumi/digitalocean": "^4.48.0",
40
+ "@pulumi/docker": "^4.7.0",
41
+ "@pulumi/eks": "^3.9.1",
42
+ "@pulumi/kubernetes": "^4.23.0",
43
+ "@pulumi/pagerduty": "^4.26.2",
44
+ "@pulumi/postgresql": "^3.15.2",
45
+ "@pulumi/pulumi": "^3.0.0",
46
+ "@pulumi/pulumiservice": "^0.29.3",
47
+ "@pulumi/random": "^4.18.2",
48
+ "@pulumi/tls": "^5.2.0",
49
+ "@pulumiverse/time": "^0.1.1",
50
+ "@slack/webhook": "^7.0.5",
51
+ "@types/jsonwebtoken": "^9.0.10",
52
+ "@types/node-forge": "^1.3.11",
53
+ "@types/superagent": "^8.1.9",
54
+ "athena-client": "^2.5.1",
55
+ "js-yaml": "^4.1.0",
56
+ "jsonwebtoken": "^9.0.2",
57
+ "jwks-rsa": "^3.2.0",
58
+ "moment-timezone": "^0.6.0",
59
+ "node-forge": "^1.3.1",
60
+ "pcloudinit": "^0.1.0",
61
+ "superagent": "^10.2.1"
62
+ },
63
+ "devDependencies": {
64
+ "@types/aws-lambda": "^8.10.150",
65
+ "@types/jest": "^30.0.0",
66
+ "@types/js-yaml": "^4.0.9",
67
+ "@types/mime-types": "^3.0.1",
68
+ "@types/mustache": "^4.2.6",
69
+ "typescript": "^5.3.0"
70
+ }
71
+ }