@dga-itc/aws-cdk-constructs 1.0.0

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 (82) hide show
  1. package/README.md +219 -0
  2. package/dist/aws-cdk/constructs/acm.d.ts +28 -0
  3. package/dist/aws-cdk/constructs/acm.js +239 -0
  4. package/dist/aws-cdk/constructs/alb.d.ts +28 -0
  5. package/dist/aws-cdk/constructs/alb.js +304 -0
  6. package/dist/aws-cdk/constructs/bastion.d.ts +46 -0
  7. package/dist/aws-cdk/constructs/bastion.js +332 -0
  8. package/dist/aws-cdk/constructs/cloudfront.d.ts +45 -0
  9. package/dist/aws-cdk/constructs/cloudfront.js +261 -0
  10. package/dist/aws-cdk/constructs/ecr.d.ts +17 -0
  11. package/dist/aws-cdk/constructs/ecr.js +143 -0
  12. package/dist/aws-cdk/constructs/ecs-cluster.d.ts +21 -0
  13. package/dist/aws-cdk/constructs/ecs-cluster.js +124 -0
  14. package/dist/aws-cdk/constructs/ecs-service.d.ts +72 -0
  15. package/dist/aws-cdk/constructs/ecs-service.js +682 -0
  16. package/dist/aws-cdk/constructs/efs.d.ts +31 -0
  17. package/dist/aws-cdk/constructs/efs.js +241 -0
  18. package/dist/aws-cdk/constructs/elasticache.d.ts +35 -0
  19. package/dist/aws-cdk/constructs/elasticache.js +210 -0
  20. package/dist/aws-cdk/constructs/nacl.d.ts +37 -0
  21. package/dist/aws-cdk/constructs/nacl.js +88 -0
  22. package/dist/aws-cdk/constructs/nlb.d.ts +39 -0
  23. package/dist/aws-cdk/constructs/nlb.js +276 -0
  24. package/dist/aws-cdk/constructs/rds.d.ts +40 -0
  25. package/dist/aws-cdk/constructs/rds.js +320 -0
  26. package/dist/aws-cdk/constructs/self-signed-cert.d.ts +83 -0
  27. package/dist/aws-cdk/constructs/self-signed-cert.js +215 -0
  28. package/dist/aws-cdk/constructs/sqs.d.ts +30 -0
  29. package/dist/aws-cdk/constructs/sqs.js +268 -0
  30. package/dist/aws-cdk/constructs/vpc.d.ts +30 -0
  31. package/dist/aws-cdk/constructs/vpc.js +423 -0
  32. package/dist/aws-cdk/constructs/waf.d.ts +37 -0
  33. package/dist/aws-cdk/constructs/waf.js +350 -0
  34. package/dist/aws-cdk/interfaces/account-config.d.ts +18 -0
  35. package/dist/aws-cdk/interfaces/account-config.js +2 -0
  36. package/dist/aws-cdk/interfaces/acm-config.d.ts +94 -0
  37. package/dist/aws-cdk/interfaces/acm-config.js +14 -0
  38. package/dist/aws-cdk/interfaces/alb-config.d.ts +72 -0
  39. package/dist/aws-cdk/interfaces/alb-config.js +2 -0
  40. package/dist/aws-cdk/interfaces/bastion-config.d.ts +77 -0
  41. package/dist/aws-cdk/interfaces/bastion-config.js +10 -0
  42. package/dist/aws-cdk/interfaces/cloudfront-config.d.ts +154 -0
  43. package/dist/aws-cdk/interfaces/cloudfront-config.js +15 -0
  44. package/dist/aws-cdk/interfaces/ecr-config.d.ts +40 -0
  45. package/dist/aws-cdk/interfaces/ecr-config.js +2 -0
  46. package/dist/aws-cdk/interfaces/ecs-cluster-config.d.ts +30 -0
  47. package/dist/aws-cdk/interfaces/ecs-cluster-config.js +2 -0
  48. package/dist/aws-cdk/interfaces/ecs-service-config.d.ts +237 -0
  49. package/dist/aws-cdk/interfaces/ecs-service-config.js +2 -0
  50. package/dist/aws-cdk/interfaces/efs-config.d.ts +56 -0
  51. package/dist/aws-cdk/interfaces/efs-config.js +7 -0
  52. package/dist/aws-cdk/interfaces/elasticache-config.d.ts +56 -0
  53. package/dist/aws-cdk/interfaces/elasticache-config.js +7 -0
  54. package/dist/aws-cdk/interfaces/nacl-config.d.ts +1 -0
  55. package/dist/aws-cdk/interfaces/nacl-config.js +3 -0
  56. package/dist/aws-cdk/interfaces/nlb-config.d.ts +69 -0
  57. package/dist/aws-cdk/interfaces/nlb-config.js +2 -0
  58. package/dist/aws-cdk/interfaces/rds-config.d.ts +84 -0
  59. package/dist/aws-cdk/interfaces/rds-config.js +7 -0
  60. package/dist/aws-cdk/interfaces/sqs-config.d.ts +145 -0
  61. package/dist/aws-cdk/interfaces/sqs-config.js +12 -0
  62. package/dist/aws-cdk/interfaces/tag-config.d.ts +18 -0
  63. package/dist/aws-cdk/interfaces/tag-config.js +2 -0
  64. package/dist/aws-cdk/interfaces/vpc-config.d.ts +72 -0
  65. package/dist/aws-cdk/interfaces/vpc-config.js +2 -0
  66. package/dist/aws-cdk/interfaces/waf-config.d.ts +180 -0
  67. package/dist/aws-cdk/interfaces/waf-config.js +2 -0
  68. package/dist/aws-cdk/utils/priority-tracker.d.ts +60 -0
  69. package/dist/aws-cdk/utils/priority-tracker.js +131 -0
  70. package/dist/index.d.ts +33 -0
  71. package/dist/index.js +55 -0
  72. package/dist/terraform-cdk/constructs/alb-listener-rule.d.ts +33 -0
  73. package/dist/terraform-cdk/constructs/alb-listener-rule.js +81 -0
  74. package/dist/terraform-cdk/constructs/ecs-service.d.ts +29 -0
  75. package/dist/terraform-cdk/constructs/ecs-service.js +238 -0
  76. package/dist/terraform-cdk/interfaces/ecs-service-config.d.ts +53 -0
  77. package/dist/terraform-cdk/interfaces/ecs-service-config.js +25 -0
  78. package/dist/terraform-cdk/interfaces/infrastructure-refs.d.ts +16 -0
  79. package/dist/terraform-cdk/interfaces/infrastructure-refs.js +8 -0
  80. package/dist/terraform-cdk/utils/priority-tracker.d.ts +60 -0
  81. package/dist/terraform-cdk/utils/priority-tracker.js +131 -0
  82. package/package.json +46 -0
@@ -0,0 +1,350 @@
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.WafConstruct = void 0;
37
+ const constructs_1 = require("constructs");
38
+ const cdk = __importStar(require("aws-cdk-lib"));
39
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
40
+ const wafv2 = __importStar(require("aws-cdk-lib/aws-wafv2"));
41
+ const logs = __importStar(require("aws-cdk-lib/aws-logs"));
42
+ /**
43
+ * WAF v2 Construct — สร้าง WebACL พร้อม AWS Managed Rule Sets
44
+ *
45
+ * Features:
46
+ * - AWS Managed Rule Groups (Common, SQLi, KnownBadInputs, etc.)
47
+ * - Rate Limiting per IP
48
+ * - Geo Blocking
49
+ * - IP Allow/Block Lists
50
+ * - CloudWatch Logging (filtered)
51
+ *
52
+ * Scopes:
53
+ * - CLOUDFRONT → ต้อง deploy ใน us-east-1, ใช้กับ CloudFront
54
+ * - REGIONAL → ใช้กับ ALB, API Gateway, AppSync
55
+ */
56
+ class WafConstruct extends constructs_1.Construct {
57
+ constructor(scope, id, props) {
58
+ super(scope, id);
59
+ const { config } = props;
60
+ this.removalPolicy = config.removalPolicy === 'retain'
61
+ ? aws_cdk_lib_1.RemovalPolicy.RETAIN
62
+ : aws_cdk_lib_1.RemovalPolicy.DESTROY;
63
+ // A. Create IP Sets (if configured)
64
+ const ipSets = this.createIpSets(config);
65
+ // B. Build all rules
66
+ const rules = this.buildRules(config, ipSets);
67
+ // C. Create WebACL
68
+ this.webAcl = this.createWebAcl(config, rules);
69
+ this.webAclArn = this.webAcl.attrArn;
70
+ // D. Create Logging (optional)
71
+ if (config.logging) {
72
+ this.logGroup = this.createLogging(config);
73
+ }
74
+ // E. (Optional) Associate with resources (REGIONAL scope only)
75
+ if (config.scope === 'REGIONAL' && config.associatedResourceArns) {
76
+ this.createAssociations(config.associatedResourceArns);
77
+ }
78
+ // F. Apply Removal Policy
79
+ this.webAcl.applyRemovalPolicy(this.removalPolicy);
80
+ // G. Outputs
81
+ this.createOutputs(config);
82
+ }
83
+ // ==========================================
84
+ // IP Sets
85
+ // ==========================================
86
+ createIpSets(config) {
87
+ const ipSets = new Map();
88
+ if (config.ipAllowList) {
89
+ const allowSet = this.createIpSet('AllowList', config.ipAllowList, config.scope);
90
+ ipSets.set('allow', allowSet);
91
+ }
92
+ if (config.ipBlockList) {
93
+ const blockSet = this.createIpSet('BlockList', config.ipBlockList, config.scope);
94
+ ipSets.set('block', blockSet);
95
+ }
96
+ return ipSets;
97
+ }
98
+ createIpSet(logicalId, ipSetConfig, scope) {
99
+ const ipSet = new wafv2.CfnIPSet(this, logicalId, {
100
+ name: ipSetConfig.name,
101
+ scope,
102
+ ipAddressVersion: ipSetConfig.ipAddressVersion ?? 'IPV4',
103
+ addresses: ipSetConfig.addresses,
104
+ description: `${ipSetConfig.action} list — ${ipSetConfig.name}`,
105
+ });
106
+ ipSet.applyRemovalPolicy(this.removalPolicy);
107
+ return ipSet;
108
+ }
109
+ // ==========================================
110
+ // Build Rules
111
+ // ==========================================
112
+ buildRules(config, ipSets) {
113
+ const rules = [];
114
+ const metricsEnabled = config.enableCloudWatchMetrics !== false;
115
+ const sampledEnabled = config.enableSampledRequests !== false;
116
+ // ── IP Allow List ──
117
+ if (config.ipAllowList && ipSets.has('allow')) {
118
+ rules.push({
119
+ name: config.ipAllowList.name,
120
+ priority: config.ipAllowList.priority,
121
+ statement: {
122
+ ipSetReferenceStatement: {
123
+ arn: ipSets.get('allow').attrArn,
124
+ },
125
+ },
126
+ action: this.resolveAction(config.ipAllowList.action),
127
+ visibilityConfig: {
128
+ cloudWatchMetricsEnabled: metricsEnabled,
129
+ sampledRequestsEnabled: sampledEnabled,
130
+ metricName: config.ipAllowList.name.replace(/[^a-zA-Z0-9]/g, ''),
131
+ },
132
+ });
133
+ }
134
+ // ── IP Block List ──
135
+ if (config.ipBlockList && ipSets.has('block')) {
136
+ rules.push({
137
+ name: config.ipBlockList.name,
138
+ priority: config.ipBlockList.priority,
139
+ statement: {
140
+ ipSetReferenceStatement: {
141
+ arn: ipSets.get('block').attrArn,
142
+ },
143
+ },
144
+ action: this.resolveAction(config.ipBlockList.action),
145
+ visibilityConfig: {
146
+ cloudWatchMetricsEnabled: metricsEnabled,
147
+ sampledRequestsEnabled: sampledEnabled,
148
+ metricName: config.ipBlockList.name.replace(/[^a-zA-Z0-9]/g, ''),
149
+ },
150
+ });
151
+ }
152
+ // ── Geo Blocking ──
153
+ if (config.geoBlock) {
154
+ const geoAction = config.geoBlock.action === 'count'
155
+ ? { count: {} }
156
+ : { block: {} };
157
+ rules.push({
158
+ name: 'GeoBlocking',
159
+ priority: config.geoBlock.priority,
160
+ statement: {
161
+ geoMatchStatement: {
162
+ countryCodes: config.geoBlock.countryCodes,
163
+ },
164
+ },
165
+ action: geoAction,
166
+ visibilityConfig: {
167
+ cloudWatchMetricsEnabled: metricsEnabled,
168
+ sampledRequestsEnabled: sampledEnabled,
169
+ metricName: 'GeoBlocking',
170
+ },
171
+ });
172
+ }
173
+ // ── Rate Limiting ──
174
+ if (config.rateLimit) {
175
+ const rlAction = config.rateLimit.action === 'count'
176
+ ? { count: {} }
177
+ : { block: {} };
178
+ rules.push({
179
+ name: 'RateLimitPerIP',
180
+ priority: config.rateLimit.priority,
181
+ statement: {
182
+ rateBasedStatement: {
183
+ limit: config.rateLimit.limit,
184
+ aggregateKeyType: 'IP',
185
+ },
186
+ },
187
+ action: rlAction,
188
+ visibilityConfig: {
189
+ cloudWatchMetricsEnabled: metricsEnabled,
190
+ sampledRequestsEnabled: sampledEnabled,
191
+ metricName: 'RateLimitPerIP',
192
+ },
193
+ });
194
+ }
195
+ // ── AWS Managed Rule Groups ──
196
+ if (config.managedRuleGroups) {
197
+ config.managedRuleGroups.forEach((rg) => {
198
+ rules.push(this.buildManagedRuleGroup(rg, metricsEnabled, sampledEnabled));
199
+ });
200
+ }
201
+ return rules;
202
+ }
203
+ buildManagedRuleGroup(rg, metricsEnabled, sampledEnabled) {
204
+ // Build excluded rules list
205
+ const excludedRules = rg.excludedRules?.map((ruleName) => ({
206
+ name: ruleName,
207
+ }));
208
+ // Build rule action overrides
209
+ const ruleActionOverrides = rg.ruleOverrides
210
+ ? Object.entries(rg.ruleOverrides).map(([ruleName, action]) => ({
211
+ name: ruleName,
212
+ actionToUse: this.resolveAction(action),
213
+ }))
214
+ : undefined;
215
+ // Override action: 'none' = enforce rules, 'count' = count only
216
+ const overrideAction = rg.overrideAction === 'count'
217
+ ? { count: {} }
218
+ : { none: {} };
219
+ return {
220
+ name: rg.name,
221
+ priority: rg.priority,
222
+ overrideAction,
223
+ statement: {
224
+ managedRuleGroupStatement: {
225
+ vendorName: rg.vendorName ?? 'AWS',
226
+ name: rg.name,
227
+ excludedRules,
228
+ ruleActionOverrides,
229
+ },
230
+ },
231
+ visibilityConfig: {
232
+ cloudWatchMetricsEnabled: metricsEnabled,
233
+ sampledRequestsEnabled: sampledEnabled,
234
+ metricName: rg.name.replace(/[^a-zA-Z0-9]/g, ''),
235
+ },
236
+ };
237
+ }
238
+ resolveAction(action) {
239
+ switch (action) {
240
+ case 'allow':
241
+ return { allow: {} };
242
+ case 'block':
243
+ return { block: {} };
244
+ case 'count':
245
+ default:
246
+ return { count: {} };
247
+ }
248
+ }
249
+ // ==========================================
250
+ // WebACL
251
+ // ==========================================
252
+ createWebAcl(config, rules) {
253
+ const defaultAction = config.defaultAction === 'block'
254
+ ? { block: {} }
255
+ : { allow: {} };
256
+ const metricsEnabled = config.enableCloudWatchMetrics !== false;
257
+ const sampledEnabled = config.enableSampledRequests !== false;
258
+ return new wafv2.CfnWebACL(this, 'WebACL', {
259
+ name: config.webAclName,
260
+ description: config.description ?? `WAF WebACL for ${config.stackName}`,
261
+ scope: config.scope,
262
+ defaultAction,
263
+ rules,
264
+ visibilityConfig: {
265
+ cloudWatchMetricsEnabled: metricsEnabled,
266
+ sampledRequestsEnabled: sampledEnabled,
267
+ metricName: config.webAclName.replace(/[^a-zA-Z0-9]/g, ''),
268
+ },
269
+ });
270
+ }
271
+ // ==========================================
272
+ // Logging
273
+ // ==========================================
274
+ createLogging(config) {
275
+ const logConfig = config.logging;
276
+ const logRemoval = logConfig.removalPolicy === 'retain'
277
+ ? aws_cdk_lib_1.RemovalPolicy.RETAIN
278
+ : aws_cdk_lib_1.RemovalPolicy.DESTROY;
279
+ // ⚠️ WAF log group name ต้องขึ้นต้นด้วย 'aws-waf-logs-'
280
+ const logGroup = new logs.LogGroup(this, 'LogGroup', {
281
+ logGroupName: `aws-waf-logs-${config.stackName}`,
282
+ retention: logConfig.retention ?? logs.RetentionDays.ONE_MONTH,
283
+ removalPolicy: logRemoval,
284
+ });
285
+ // Logging Configuration
286
+ const loggingConfig = new wafv2.CfnLoggingConfiguration(this, 'LoggingConfig', {
287
+ resourceArn: this.webAcl.attrArn,
288
+ logDestinationConfigs: [logGroup.logGroupArn],
289
+ });
290
+ // Log filter — default: log blocked requests only
291
+ if (logConfig.logFilter !== 'all') {
292
+ loggingConfig.addPropertyOverride('LoggingFilter', {
293
+ DefaultBehavior: 'DROP',
294
+ Filters: [{
295
+ Behavior: 'KEEP',
296
+ Conditions: [{
297
+ ActionCondition: { Action: 'BLOCK' },
298
+ }],
299
+ Requirement: 'MEETS_ANY',
300
+ }],
301
+ });
302
+ }
303
+ // Dependency: LoggingConfiguration ต้องสร้างหลัง WebACL
304
+ loggingConfig.addDependency(this.webAcl);
305
+ return logGroup;
306
+ }
307
+ // ==========================================
308
+ // Resource Associations (REGIONAL only)
309
+ // ==========================================
310
+ createAssociations(resourceArns) {
311
+ resourceArns.forEach((arn, index) => {
312
+ const assoc = new wafv2.CfnWebACLAssociation(this, `Association${index}`, {
313
+ webAclArn: this.webAcl.attrArn,
314
+ resourceArn: arn,
315
+ });
316
+ assoc.addDependency(this.webAcl);
317
+ });
318
+ }
319
+ // ==========================================
320
+ // Outputs
321
+ // ==========================================
322
+ createOutputs(config) {
323
+ const stack = cdk.Stack.of(this);
324
+ new cdk.CfnOutput(stack, 'WebACLArn', {
325
+ value: this.webAcl.attrArn,
326
+ description: 'WAF WebACL ARN',
327
+ exportName: `${config.stackName}-WebACL-Arn`,
328
+ });
329
+ new cdk.CfnOutput(stack, 'WebACLId', {
330
+ value: this.webAcl.ref,
331
+ description: 'WAF WebACL ID',
332
+ exportName: `${config.stackName}-WebACL-Id`,
333
+ });
334
+ new cdk.CfnOutput(stack, 'WebACLName', {
335
+ value: config.webAclName,
336
+ description: 'WAF WebACL Name',
337
+ });
338
+ new cdk.CfnOutput(stack, 'WAFScope', {
339
+ value: config.scope,
340
+ description: 'WAF Scope (CLOUDFRONT or REGIONAL)',
341
+ });
342
+ if (this.logGroup) {
343
+ new cdk.CfnOutput(stack, 'LogGroupName', {
344
+ value: this.logGroup.logGroupName,
345
+ description: 'WAF Log Group Name',
346
+ });
347
+ }
348
+ }
349
+ }
350
+ exports.WafConstruct = WafConstruct;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Account Configuration Interface
3
+ *
4
+ * ใช้เป็น "resource" กลางสำหรับกำหนด region ให้แต่ละ environment
5
+ *
6
+ * account ID มาจาก --profile ตอน deploy (CDK_DEFAULT_ACCOUNT) ไม่ต้องใส่ใน config
7
+ *
8
+ * วิธีใช้:
9
+ * 1. สร้าง AccountConfig ใน configs/accounts/ (เช่น myapp-prod.ts)
10
+ * 2. ทุก service config ใส่ accountConfigName เพื่ออ้างอิง
11
+ * 3. bin/main.ts จะ resolve region จาก accountConfigName, account จาก --profile
12
+ */
13
+ export interface AccountConfig {
14
+ /** ชื่อ account config (ใช้อ้างอิงจาก service configs) */
15
+ name: string;
16
+ /** AWS Region (e.g., 'us-east-1') — override region จาก profile */
17
+ region: string;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,94 @@
1
+ /**
2
+ * ACM Configuration Interface
3
+ *
4
+ * รองรับ 2 โหมด:
5
+ * - request: ขอ certificate ใหม่จาก ACM (DNS/Email validation)
6
+ * - import: นำเข้า certificate ที่มีอยู่แล้ว (PEM format)
7
+ *
8
+ * วิธีใช้:
9
+ * 1. สร้าง AcmConfig ใน configs/acm/ (เช่น demo-dev-acm-e1.ts)
10
+ * 2. ลงทะเบียนใน configs/acm/index.ts
11
+ * 3. bin/main.ts จะสร้าง AcmStack อัตโนมัติ
12
+ */
13
+ /** โหมดการสร้าง Certificate */
14
+ export type AcmMode = 'request' | 'import';
15
+ /** วิธี Validation สำหรับ request mode */
16
+ export type AcmValidationMethod = 'DNS' | 'EMAIL';
17
+ /**
18
+ * Request mode config — ขอ certificate ใหม่จาก ACM
19
+ */
20
+ export interface AcmRequestConfig {
21
+ /** Domain name หลัก (e.g., 'example.com') */
22
+ domainName: string;
23
+ /** Subject Alternative Names (e.g., ['*.example.com', 'api.example.com']) */
24
+ subjectAlternativeNames?: string[];
25
+ /** Validation method (default: 'DNS') */
26
+ validationMethod?: AcmValidationMethod;
27
+ /**
28
+ * Route53 Hosted Zone ID — ถ้าใส่จะสร้าง DNS validation record อัตโนมัติ
29
+ * (ใช้ได้เฉพาะ validationMethod = 'DNS')
30
+ */
31
+ hostedZoneId?: string;
32
+ /** Hosted Zone name (required if hostedZoneId is set) */
33
+ hostedZoneName?: string;
34
+ /** Key algorithm (default: 'RSA_2048') */
35
+ keyAlgorithm?: 'RSA_2048' | 'EC_prime256v1' | 'EC_secp384r1';
36
+ /**
37
+ * Enable transparency logging (default: true)
38
+ * Certificate Transparency Logging ช่วยตรวจสอบว่า cert ถูก issue อย่างถูกต้อง
39
+ */
40
+ transparencyLoggingEnabled?: boolean;
41
+ }
42
+ /**
43
+ * Import mode config — นำเข้า certificate ที่มีอยู่แล้ว
44
+ *
45
+ * ใช้ SSM Parameter Store หรือ Secrets Manager เก็บค่า PEM
46
+ * (ไม่ควร hardcode ค่า PEM ใน config โดยตรง)
47
+ */
48
+ export interface AcmImportConfig {
49
+ /** Certificate body (PEM format) — หรือ SSM parameter name ที่เก็บค่า */
50
+ certificateBodyParam: string;
51
+ /** Certificate private key (PEM format) — หรือ Secrets Manager ARN ที่เก็บค่า */
52
+ privateKeyParam: string;
53
+ /** Certificate chain (PEM format) — optional, หรือ SSM parameter name */
54
+ certificateChainParam?: string;
55
+ }
56
+ /**
57
+ * ACM Config — รวม request + import mode
58
+ */
59
+ export interface AcmConfig {
60
+ /** ชื่อ CloudFormation stack (ถ้าใช้ regions จะถูก suffix ด้วย region shorthand อัตโนมัติ) */
61
+ stackName: string;
62
+ /** AWS Region (ถ้าไม่กำหนดจะใช้ CDK_DEFAULT_REGION) */
63
+ region?: string;
64
+ /** AWS Account (ถ้าไม่กำหนดจะใช้ CDK_DEFAULT_ACCOUNT) */
65
+ account?: string;
66
+ /** อ้างอิง Account Config name (ดู configs/accounts/) */
67
+ accountConfigName?: string;
68
+ /**
69
+ * สร้าง certificate ในหลาย regions พร้อมกัน
70
+ * เช่น ['ap-southeast-7', 'us-east-1']
71
+ *
72
+ * ถ้าใส่ regions:
73
+ * - stackName จะถูก suffix ด้วย region shorthand (e.g., 'my-acm' → 'my-acm-apse7', 'my-acm-use1')
74
+ * - จะสร้าง 1 stack ต่อ 1 region
75
+ * - ไม่ต้องใส่ region / accountConfigName (จะถูก override)
76
+ *
77
+ * ถ้าไม่ใส่ regions → ใช้ region เดียวจาก accountConfigName / region / CDK_DEFAULT_REGION
78
+ */
79
+ regions?: string[];
80
+ /** โหมดการสร้าง certificate */
81
+ mode: AcmMode;
82
+ /** Config สำหรับ request mode (required if mode = 'request') */
83
+ request?: AcmRequestConfig;
84
+ /** Config สำหรับ import mode (required if mode = 'import') */
85
+ import?: AcmImportConfig;
86
+ /** Removal policy (default: 'destroy') */
87
+ removalPolicy?: 'destroy' | 'retain';
88
+ /** Export certificate ARN เป็น CfnOutput (default: true) */
89
+ enableExport?: boolean;
90
+ /** อ้างอิง Tag Config name (ดู configs/tags/) */
91
+ tagConfigName?: string;
92
+ /** Tags เสริม — merge กับ tagConfigName (override ถ้า key ซ้ำ) */
93
+ tags?: Record<string, string>;
94
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * ACM Configuration Interface
4
+ *
5
+ * รองรับ 2 โหมด:
6
+ * - request: ขอ certificate ใหม่จาก ACM (DNS/Email validation)
7
+ * - import: นำเข้า certificate ที่มีอยู่แล้ว (PEM format)
8
+ *
9
+ * วิธีใช้:
10
+ * 1. สร้าง AcmConfig ใน configs/acm/ (เช่น demo-dev-acm-e1.ts)
11
+ * 2. ลงทะเบียนใน configs/acm/index.ts
12
+ * 3. bin/main.ts จะสร้าง AcmStack อัตโนมัติ
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,72 @@
1
+ import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
2
+ export type AlbScheme = 'internet-facing' | 'internal';
3
+ export interface AlbListenerConfig {
4
+ /** Enable HTTP listener (default: true) */
5
+ httpEnabled?: boolean;
6
+ /** HTTP port (default: 80) */
7
+ httpPort?: number;
8
+ /** Redirect HTTP to HTTPS (default: true if HTTPS is enabled) */
9
+ httpRedirectToHttps?: boolean;
10
+ /** Enable HTTPS listener (default: true) */
11
+ httpsEnabled?: boolean;
12
+ /** HTTPS port (default: 443) */
13
+ httpsPort?: number;
14
+ /** ACM certificate ARN - required if httpsEnabled */
15
+ certificateArn?: string;
16
+ /** Additional certificates for same listener */
17
+ additionalCertificateArns?: string[];
18
+ /** SSL policy (default: RECOMMENDED_TLS) */
19
+ sslPolicy?: elbv2.SslPolicy;
20
+ }
21
+ export interface AlbSecurityConfig {
22
+ /** Allow HTTP from 0.0.0.0/0 (default: true for internet-facing) */
23
+ allowHttpFromAnywhere?: boolean;
24
+ /** Allow HTTPS from 0.0.0.0/0 (default: true for internet-facing) */
25
+ allowHttpsFromAnywhere?: boolean;
26
+ /** Additional CIDRs to allow */
27
+ allowFromCidrs?: string[];
28
+ /** Additional Security Group IDs to allow */
29
+ allowFromSecurityGroupIds?: string[];
30
+ /** Drop invalid HTTP headers (default: true) */
31
+ dropInvalidHeaderFields?: boolean;
32
+ /** Idle timeout in seconds (default: 60) */
33
+ idleTimeoutSeconds?: number;
34
+ }
35
+ /**
36
+ * VpcRef - อ้างอิง VPC stack ใน CDK app เดียวกัน
37
+ */
38
+ export interface AlbVpcRefSource {
39
+ vpcStackName: string;
40
+ /** ใช้ subnet ชื่ออะไร (default: 'public') */
41
+ subnetName?: string;
42
+ }
43
+ export interface AlbConfig {
44
+ stackName: string;
45
+ albName: string;
46
+ region?: string;
47
+ account?: string;
48
+ /** อ้างอิง Account Config name (ดู configs/accounts/) */
49
+ accountConfigName?: string;
50
+ /** Custom Security Group name (optional, removes CDK hash suffix) */
51
+ securityGroupName?: string;
52
+ /** ALB scheme */
53
+ scheme: AlbScheme;
54
+ /** VPC source - อ้างอิง VPC stack */
55
+ source: AlbVpcRefSource;
56
+ /** Listener configuration */
57
+ listener?: AlbListenerConfig;
58
+ /** Security configuration */
59
+ security?: AlbSecurityConfig;
60
+ /** Deletion protection (default: false) */
61
+ deletionProtection?: boolean;
62
+ /** Removal policy (default: 'destroy') */
63
+ removalPolicy?: 'destroy' | 'retain';
64
+ /** Access logs */
65
+ accessLogsEnabled?: boolean;
66
+ accessLogsBucket?: string;
67
+ accessLogsPrefix?: string;
68
+ /** อ้างอิง Tag Config name (ดู configs/tags/) */
69
+ tagConfigName?: string;
70
+ /** Tags เสริม — merge กับ tagConfigName (override ถ้า key ซ้ำ) */
71
+ tags?: Record<string, string>;
72
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Bastion Host Configuration Interface
3
+ *
4
+ * สำหรับสร้าง EC2 Bastion Host เพื่อ:
5
+ * - เข้าถึง RDS สำหรับ migrate ข้อมูล
6
+ * - Mount EFS สำหรับอัปโหลดไฟล์
7
+ * - ส่ง SSH key ให้ vendor ได้
8
+ */
9
+ export interface BastionVpcRefSource {
10
+ vpcStackName: string;
11
+ /** ใช้ subnet ชื่ออะไรสำหรับวาง Bastion (default: 'private') */
12
+ subnetName?: string;
13
+ }
14
+ export interface BastionEfsMount {
15
+ /** EFS stack name สำหรับ cross-stack reference */
16
+ efsStackName: string;
17
+ /** Mount path บน EC2 (default: '/mnt/efs') */
18
+ mountPath?: string;
19
+ /** Access Point name ที่จะใช้ (optional) */
20
+ accessPointName?: string;
21
+ }
22
+ export interface BastionRdsAccess {
23
+ /** RDS stack name สำหรับ cross-stack reference */
24
+ rdsStackName: string;
25
+ /** Port ของ database (default: 3306) */
26
+ port?: number;
27
+ }
28
+ export interface BastionRedisAccess {
29
+ /** ElastiCache stack name สำหรับ cross-stack reference */
30
+ elastiCacheStackName: string;
31
+ /** Port ของ Redis (default: 6379) */
32
+ port?: number;
33
+ }
34
+ export interface BastionConfig {
35
+ stackName: string;
36
+ instanceName: string;
37
+ region?: string;
38
+ account?: string;
39
+ /** อ้างอิง Account Config name (ดู configs/accounts/) */
40
+ accountConfigName?: string;
41
+ /** VPC source - อ้างอิง VPC stack */
42
+ source: BastionVpcRefSource;
43
+ /** Custom Security Group name (optional) */
44
+ securityGroupName?: string;
45
+ /** EC2 Instance Type (default: 't3.micro') */
46
+ instanceType?: string;
47
+ /** Key Pair name - ถ้าไม่ระบุจะสร้างใหม่ */
48
+ keyPairName?: string;
49
+ /** สร้าง Key Pair ใหม่หรือไม่ (default: true) */
50
+ createKeyPair?: boolean;
51
+ /** AMI ID (optional - ถ้าไม่ระบุจะใช้ Amazon Linux 2023) */
52
+ amiId?: string;
53
+ /** Allowed SSH CIDR blocks (default: ไม่เปิด SSH จากข้างนอก) */
54
+ allowedSshCidrs?: string[];
55
+ /** Associate public IP address (default: false) - ต้องวางใน public subnet */
56
+ associatePublicIpAddress?: boolean;
57
+ /** EBS volume size in GB (default: 20) */
58
+ volumeSize?: number;
59
+ /** EBS volume type (default: 'gp3') */
60
+ volumeType?: 'gp2' | 'gp3';
61
+ /** EFS mount configuration (optional) */
62
+ efsMount?: BastionEfsMount;
63
+ /** RDS access configuration (optional) */
64
+ rdsAccess?: BastionRdsAccess;
65
+ /** Redis access configuration (optional) */
66
+ redisAccess?: BastionRedisAccess;
67
+ /** Install MySQL/MariaDB client (default: true) */
68
+ installMysqlClient?: boolean;
69
+ /** Additional user data script (optional) */
70
+ additionalUserData?: string;
71
+ /** Removal policy (default: 'destroy' - bastion เป็น temporary) */
72
+ removalPolicy?: 'destroy' | 'retain';
73
+ /** อ้างอิง Tag Config name (ดู configs/tags/) */
74
+ tagConfigName?: string;
75
+ /** Tags เสริม — merge กับ tagConfigName (override ถ้า key ซ้ำ) */
76
+ tags?: Record<string, string>;
77
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Bastion Host Configuration Interface
4
+ *
5
+ * สำหรับสร้าง EC2 Bastion Host เพื่อ:
6
+ * - เข้าถึง RDS สำหรับ migrate ข้อมูล
7
+ * - Mount EFS สำหรับอัปโหลดไฟล์
8
+ * - ส่ง SSH key ให้ vendor ได้
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });