@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.
- package/README.md +219 -0
- package/dist/aws-cdk/constructs/acm.d.ts +28 -0
- package/dist/aws-cdk/constructs/acm.js +239 -0
- package/dist/aws-cdk/constructs/alb.d.ts +28 -0
- package/dist/aws-cdk/constructs/alb.js +304 -0
- package/dist/aws-cdk/constructs/bastion.d.ts +46 -0
- package/dist/aws-cdk/constructs/bastion.js +332 -0
- package/dist/aws-cdk/constructs/cloudfront.d.ts +45 -0
- package/dist/aws-cdk/constructs/cloudfront.js +261 -0
- package/dist/aws-cdk/constructs/ecr.d.ts +17 -0
- package/dist/aws-cdk/constructs/ecr.js +143 -0
- package/dist/aws-cdk/constructs/ecs-cluster.d.ts +21 -0
- package/dist/aws-cdk/constructs/ecs-cluster.js +124 -0
- package/dist/aws-cdk/constructs/ecs-service.d.ts +72 -0
- package/dist/aws-cdk/constructs/ecs-service.js +682 -0
- package/dist/aws-cdk/constructs/efs.d.ts +31 -0
- package/dist/aws-cdk/constructs/efs.js +241 -0
- package/dist/aws-cdk/constructs/elasticache.d.ts +35 -0
- package/dist/aws-cdk/constructs/elasticache.js +210 -0
- package/dist/aws-cdk/constructs/nacl.d.ts +37 -0
- package/dist/aws-cdk/constructs/nacl.js +88 -0
- package/dist/aws-cdk/constructs/nlb.d.ts +39 -0
- package/dist/aws-cdk/constructs/nlb.js +276 -0
- package/dist/aws-cdk/constructs/rds.d.ts +40 -0
- package/dist/aws-cdk/constructs/rds.js +320 -0
- package/dist/aws-cdk/constructs/self-signed-cert.d.ts +83 -0
- package/dist/aws-cdk/constructs/self-signed-cert.js +215 -0
- package/dist/aws-cdk/constructs/sqs.d.ts +30 -0
- package/dist/aws-cdk/constructs/sqs.js +268 -0
- package/dist/aws-cdk/constructs/vpc.d.ts +30 -0
- package/dist/aws-cdk/constructs/vpc.js +423 -0
- package/dist/aws-cdk/constructs/waf.d.ts +37 -0
- package/dist/aws-cdk/constructs/waf.js +350 -0
- package/dist/aws-cdk/interfaces/account-config.d.ts +18 -0
- package/dist/aws-cdk/interfaces/account-config.js +2 -0
- package/dist/aws-cdk/interfaces/acm-config.d.ts +94 -0
- package/dist/aws-cdk/interfaces/acm-config.js +14 -0
- package/dist/aws-cdk/interfaces/alb-config.d.ts +72 -0
- package/dist/aws-cdk/interfaces/alb-config.js +2 -0
- package/dist/aws-cdk/interfaces/bastion-config.d.ts +77 -0
- package/dist/aws-cdk/interfaces/bastion-config.js +10 -0
- package/dist/aws-cdk/interfaces/cloudfront-config.d.ts +154 -0
- package/dist/aws-cdk/interfaces/cloudfront-config.js +15 -0
- package/dist/aws-cdk/interfaces/ecr-config.d.ts +40 -0
- package/dist/aws-cdk/interfaces/ecr-config.js +2 -0
- package/dist/aws-cdk/interfaces/ecs-cluster-config.d.ts +30 -0
- package/dist/aws-cdk/interfaces/ecs-cluster-config.js +2 -0
- package/dist/aws-cdk/interfaces/ecs-service-config.d.ts +237 -0
- package/dist/aws-cdk/interfaces/ecs-service-config.js +2 -0
- package/dist/aws-cdk/interfaces/efs-config.d.ts +56 -0
- package/dist/aws-cdk/interfaces/efs-config.js +7 -0
- package/dist/aws-cdk/interfaces/elasticache-config.d.ts +56 -0
- package/dist/aws-cdk/interfaces/elasticache-config.js +7 -0
- package/dist/aws-cdk/interfaces/nacl-config.d.ts +1 -0
- package/dist/aws-cdk/interfaces/nacl-config.js +3 -0
- package/dist/aws-cdk/interfaces/nlb-config.d.ts +69 -0
- package/dist/aws-cdk/interfaces/nlb-config.js +2 -0
- package/dist/aws-cdk/interfaces/rds-config.d.ts +84 -0
- package/dist/aws-cdk/interfaces/rds-config.js +7 -0
- package/dist/aws-cdk/interfaces/sqs-config.d.ts +145 -0
- package/dist/aws-cdk/interfaces/sqs-config.js +12 -0
- package/dist/aws-cdk/interfaces/tag-config.d.ts +18 -0
- package/dist/aws-cdk/interfaces/tag-config.js +2 -0
- package/dist/aws-cdk/interfaces/vpc-config.d.ts +72 -0
- package/dist/aws-cdk/interfaces/vpc-config.js +2 -0
- package/dist/aws-cdk/interfaces/waf-config.d.ts +180 -0
- package/dist/aws-cdk/interfaces/waf-config.js +2 -0
- package/dist/aws-cdk/utils/priority-tracker.d.ts +60 -0
- package/dist/aws-cdk/utils/priority-tracker.js +131 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +55 -0
- package/dist/terraform-cdk/constructs/alb-listener-rule.d.ts +33 -0
- package/dist/terraform-cdk/constructs/alb-listener-rule.js +81 -0
- package/dist/terraform-cdk/constructs/ecs-service.d.ts +29 -0
- package/dist/terraform-cdk/constructs/ecs-service.js +238 -0
- package/dist/terraform-cdk/interfaces/ecs-service-config.d.ts +53 -0
- package/dist/terraform-cdk/interfaces/ecs-service-config.js +25 -0
- package/dist/terraform-cdk/interfaces/infrastructure-refs.d.ts +16 -0
- package/dist/terraform-cdk/interfaces/infrastructure-refs.js +8 -0
- package/dist/terraform-cdk/utils/priority-tracker.d.ts +60 -0
- package/dist/terraform-cdk/utils/priority-tracker.js +131 -0
- package/package.json +46 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Priority Tracker for ALB Listener Rules
|
|
4
|
+
*
|
|
5
|
+
* Manages priority assignments for ALB Listener Rules to prevent conflicts.
|
|
6
|
+
* Priorities must be unique within a listener (range: 1-50000).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PriorityTracker = void 0;
|
|
10
|
+
class PriorityTracker {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.assignments = new Map();
|
|
13
|
+
this.serviceNames = new Set();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Register a priority assignment
|
|
17
|
+
* @param serviceName Name of the ECS service
|
|
18
|
+
* @param priority Priority value (1-50000)
|
|
19
|
+
* @param path Optional path pattern
|
|
20
|
+
* @param host Optional host header
|
|
21
|
+
* @throws Error if priority is already assigned or out of range
|
|
22
|
+
*/
|
|
23
|
+
registerPriority(serviceName, priority, path, host) {
|
|
24
|
+
// Validate priority range
|
|
25
|
+
if (priority < 1 || priority > 50000) {
|
|
26
|
+
throw new Error(`Invalid priority ${priority} for service ${serviceName}. Priority must be between 1 and 50000.`);
|
|
27
|
+
}
|
|
28
|
+
// Check for duplicate priority
|
|
29
|
+
if (this.assignments.has(priority)) {
|
|
30
|
+
const existing = this.assignments.get(priority);
|
|
31
|
+
throw new Error(`Priority conflict: Priority ${priority} is already assigned to service "${existing.serviceName}". ` +
|
|
32
|
+
`Cannot assign to service "${serviceName}".`);
|
|
33
|
+
}
|
|
34
|
+
// Check for duplicate service name
|
|
35
|
+
if (this.serviceNames.has(serviceName)) {
|
|
36
|
+
throw new Error(`Service name conflict: Service "${serviceName}" is already registered.`);
|
|
37
|
+
}
|
|
38
|
+
// Register the assignment
|
|
39
|
+
this.assignments.set(priority, {
|
|
40
|
+
serviceName,
|
|
41
|
+
priority,
|
|
42
|
+
path,
|
|
43
|
+
host,
|
|
44
|
+
});
|
|
45
|
+
this.serviceNames.add(serviceName);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get all priority assignments sorted by priority
|
|
49
|
+
* @returns Array of priority assignments
|
|
50
|
+
*/
|
|
51
|
+
getAssignments() {
|
|
52
|
+
return Array.from(this.assignments.values()).sort((a, b) => a.priority - b.priority);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if a priority is available
|
|
56
|
+
* @param priority Priority value to check
|
|
57
|
+
* @returns True if priority is available
|
|
58
|
+
*/
|
|
59
|
+
isPriorityAvailable(priority) {
|
|
60
|
+
return !this.assignments.has(priority);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the next available priority
|
|
64
|
+
* @param startFrom Starting priority (default: 1)
|
|
65
|
+
* @returns Next available priority
|
|
66
|
+
*/
|
|
67
|
+
getNextAvailablePriority(startFrom = 1) {
|
|
68
|
+
let priority = startFrom;
|
|
69
|
+
while (this.assignments.has(priority) && priority <= 50000) {
|
|
70
|
+
priority++;
|
|
71
|
+
}
|
|
72
|
+
if (priority > 50000) {
|
|
73
|
+
throw new Error('No available priorities. Maximum priority limit (50000) reached.');
|
|
74
|
+
}
|
|
75
|
+
return priority;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Print a summary of all priority assignments
|
|
79
|
+
*/
|
|
80
|
+
printSummary() {
|
|
81
|
+
const assignments = this.getAssignments();
|
|
82
|
+
if (assignments.length === 0) {
|
|
83
|
+
console.log('\n📋 Priority Tracker: No assignments registered\n');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.log('\n📋 Priority Tracker Summary');
|
|
87
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
88
|
+
console.log(`Total Services: ${assignments.length}`);
|
|
89
|
+
console.log('───────────────────────────────────────────────────────────────');
|
|
90
|
+
assignments.forEach((assignment) => {
|
|
91
|
+
const conditions = [];
|
|
92
|
+
if (assignment.path)
|
|
93
|
+
conditions.push(`Path: ${assignment.path}`);
|
|
94
|
+
if (assignment.host)
|
|
95
|
+
conditions.push(`Host: ${assignment.host}`);
|
|
96
|
+
const conditionStr = conditions.length > 0 ? ` (${conditions.join(', ')})` : '';
|
|
97
|
+
console.log(`Priority ${assignment.priority.toString().padStart(5)}: ${assignment.serviceName}${conditionStr}`);
|
|
98
|
+
});
|
|
99
|
+
console.log('═══════════════════════════════════════════════════════════════\n');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Validate all assignments for conflicts
|
|
103
|
+
* @throws Error if conflicts are detected
|
|
104
|
+
*/
|
|
105
|
+
validate() {
|
|
106
|
+
const priorities = Array.from(this.assignments.keys());
|
|
107
|
+
const uniquePriorities = new Set(priorities);
|
|
108
|
+
if (priorities.length !== uniquePriorities.size) {
|
|
109
|
+
throw new Error('Priority conflict detected: Duplicate priorities found.');
|
|
110
|
+
}
|
|
111
|
+
const services = Array.from(this.serviceNames);
|
|
112
|
+
if (services.length !== this.assignments.size) {
|
|
113
|
+
throw new Error('Service name conflict detected: Duplicate service names found.');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clear all assignments
|
|
118
|
+
*/
|
|
119
|
+
clear() {
|
|
120
|
+
this.assignments.clear();
|
|
121
|
+
this.serviceNames.clear();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get total number of assignments
|
|
125
|
+
* @returns Number of registered assignments
|
|
126
|
+
*/
|
|
127
|
+
get count() {
|
|
128
|
+
return this.assignments.size;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.PriorityTracker = PriorityTracker;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export * from './aws-cdk/constructs/vpc';
|
|
2
|
+
export * from './aws-cdk/constructs/alb';
|
|
3
|
+
export * from './aws-cdk/constructs/nlb';
|
|
4
|
+
export * from './aws-cdk/constructs/ecs-cluster';
|
|
5
|
+
export { EcsServiceConstruct as CdkEcsServiceConstruct, EcsServiceConstructProps as CdkEcsServiceConstructProps } from './aws-cdk/constructs/ecs-service';
|
|
6
|
+
export * from './aws-cdk/constructs/rds';
|
|
7
|
+
export * from './aws-cdk/constructs/elasticache';
|
|
8
|
+
export * from './aws-cdk/constructs/efs';
|
|
9
|
+
export * from './aws-cdk/constructs/bastion';
|
|
10
|
+
export { NaclConstruct, NaclConstructProps, NaclRuleConfig as CdkNaclRuleConfig, NaclConfig as CdkNaclConfig } from './aws-cdk/constructs/nacl';
|
|
11
|
+
export * from './aws-cdk/constructs/ecr';
|
|
12
|
+
export * from './aws-cdk/constructs/acm';
|
|
13
|
+
export * from './aws-cdk/constructs/cloudfront';
|
|
14
|
+
export * from './aws-cdk/constructs/sqs';
|
|
15
|
+
export * from './aws-cdk/constructs/waf';
|
|
16
|
+
export * from './aws-cdk/constructs/self-signed-cert';
|
|
17
|
+
export * from './aws-cdk/interfaces/vpc-config';
|
|
18
|
+
export * from './aws-cdk/interfaces/alb-config';
|
|
19
|
+
export * from './aws-cdk/interfaces/nlb-config';
|
|
20
|
+
export * from './aws-cdk/interfaces/ecs-cluster-config';
|
|
21
|
+
export { EcsServiceConfig as CdkEcsServiceConfig } from './aws-cdk/interfaces/ecs-service-config';
|
|
22
|
+
export * from './aws-cdk/interfaces/rds-config';
|
|
23
|
+
export * from './aws-cdk/interfaces/elasticache-config';
|
|
24
|
+
export * from './aws-cdk/interfaces/efs-config';
|
|
25
|
+
export * from './aws-cdk/interfaces/bastion-config';
|
|
26
|
+
export * from './aws-cdk/interfaces/ecr-config';
|
|
27
|
+
export * from './aws-cdk/interfaces/account-config';
|
|
28
|
+
export * from './aws-cdk/interfaces/tag-config';
|
|
29
|
+
export * from './aws-cdk/interfaces/acm-config';
|
|
30
|
+
export * from './aws-cdk/interfaces/cloudfront-config';
|
|
31
|
+
export * from './aws-cdk/interfaces/sqs-config';
|
|
32
|
+
export * from './aws-cdk/interfaces/waf-config';
|
|
33
|
+
export * from './aws-cdk/utils/priority-tracker';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.NaclConstruct = exports.CdkEcsServiceConstruct = void 0;
|
|
18
|
+
// AWS CDK Constructs
|
|
19
|
+
__exportStar(require("./aws-cdk/constructs/vpc"), exports);
|
|
20
|
+
__exportStar(require("./aws-cdk/constructs/alb"), exports);
|
|
21
|
+
__exportStar(require("./aws-cdk/constructs/nlb"), exports);
|
|
22
|
+
__exportStar(require("./aws-cdk/constructs/ecs-cluster"), exports);
|
|
23
|
+
var ecs_service_1 = require("./aws-cdk/constructs/ecs-service");
|
|
24
|
+
Object.defineProperty(exports, "CdkEcsServiceConstruct", { enumerable: true, get: function () { return ecs_service_1.EcsServiceConstruct; } });
|
|
25
|
+
__exportStar(require("./aws-cdk/constructs/rds"), exports);
|
|
26
|
+
__exportStar(require("./aws-cdk/constructs/elasticache"), exports);
|
|
27
|
+
__exportStar(require("./aws-cdk/constructs/efs"), exports);
|
|
28
|
+
__exportStar(require("./aws-cdk/constructs/bastion"), exports);
|
|
29
|
+
var nacl_1 = require("./aws-cdk/constructs/nacl");
|
|
30
|
+
Object.defineProperty(exports, "NaclConstruct", { enumerable: true, get: function () { return nacl_1.NaclConstruct; } });
|
|
31
|
+
__exportStar(require("./aws-cdk/constructs/ecr"), exports);
|
|
32
|
+
__exportStar(require("./aws-cdk/constructs/acm"), exports);
|
|
33
|
+
__exportStar(require("./aws-cdk/constructs/cloudfront"), exports);
|
|
34
|
+
__exportStar(require("./aws-cdk/constructs/sqs"), exports);
|
|
35
|
+
__exportStar(require("./aws-cdk/constructs/waf"), exports);
|
|
36
|
+
__exportStar(require("./aws-cdk/constructs/self-signed-cert"), exports);
|
|
37
|
+
// AWS CDK Interfaces
|
|
38
|
+
__exportStar(require("./aws-cdk/interfaces/vpc-config"), exports);
|
|
39
|
+
__exportStar(require("./aws-cdk/interfaces/alb-config"), exports);
|
|
40
|
+
__exportStar(require("./aws-cdk/interfaces/nlb-config"), exports);
|
|
41
|
+
__exportStar(require("./aws-cdk/interfaces/ecs-cluster-config"), exports);
|
|
42
|
+
__exportStar(require("./aws-cdk/interfaces/rds-config"), exports);
|
|
43
|
+
__exportStar(require("./aws-cdk/interfaces/elasticache-config"), exports);
|
|
44
|
+
__exportStar(require("./aws-cdk/interfaces/efs-config"), exports);
|
|
45
|
+
__exportStar(require("./aws-cdk/interfaces/bastion-config"), exports);
|
|
46
|
+
// nacl-config already exports from constructs, skip to avoid duplicates
|
|
47
|
+
__exportStar(require("./aws-cdk/interfaces/ecr-config"), exports);
|
|
48
|
+
__exportStar(require("./aws-cdk/interfaces/account-config"), exports);
|
|
49
|
+
__exportStar(require("./aws-cdk/interfaces/tag-config"), exports);
|
|
50
|
+
__exportStar(require("./aws-cdk/interfaces/acm-config"), exports);
|
|
51
|
+
__exportStar(require("./aws-cdk/interfaces/cloudfront-config"), exports);
|
|
52
|
+
__exportStar(require("./aws-cdk/interfaces/sqs-config"), exports);
|
|
53
|
+
__exportStar(require("./aws-cdk/interfaces/waf-config"), exports);
|
|
54
|
+
// AWS CDK Utils
|
|
55
|
+
__exportStar(require("./aws-cdk/utils/priority-tracker"), exports);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ALB Listener Rule Construct
|
|
3
|
+
*
|
|
4
|
+
* Creates an ALB Listener Rule with:
|
|
5
|
+
* - Priority management
|
|
6
|
+
* - Conditions (path pattern, host header)
|
|
7
|
+
* - Target Group integration
|
|
8
|
+
*/
|
|
9
|
+
import { Construct } from 'constructs';
|
|
10
|
+
import { LbListenerRule } from '@cdktf/provider-aws/lib/lb-listener-rule';
|
|
11
|
+
import { LbTargetGroup } from '@cdktf/provider-aws/lib/lb-target-group';
|
|
12
|
+
export interface AlbListenerRuleProps {
|
|
13
|
+
listenerArn: string;
|
|
14
|
+
priority: number;
|
|
15
|
+
targetGroup: LbTargetGroup;
|
|
16
|
+
pathPattern?: string;
|
|
17
|
+
hostHeader?: string;
|
|
18
|
+
serviceName: string;
|
|
19
|
+
environment: string;
|
|
20
|
+
tags?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export declare class AlbListenerRuleConstruct extends Construct {
|
|
23
|
+
readonly listenerRule: LbListenerRule;
|
|
24
|
+
constructor(scope: Construct, id: string, props: AlbListenerRuleProps);
|
|
25
|
+
/**
|
|
26
|
+
* Get a human-readable description of the rule conditions
|
|
27
|
+
*/
|
|
28
|
+
getConditionDescription(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Static helper to format condition description
|
|
31
|
+
*/
|
|
32
|
+
static formatConditions(pathPattern?: string, hostHeader?: string): string;
|
|
33
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ALB Listener Rule Construct
|
|
4
|
+
*
|
|
5
|
+
* Creates an ALB Listener Rule with:
|
|
6
|
+
* - Priority management
|
|
7
|
+
* - Conditions (path pattern, host header)
|
|
8
|
+
* - Target Group integration
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.AlbListenerRuleConstruct = void 0;
|
|
12
|
+
const constructs_1 = require("constructs");
|
|
13
|
+
const lb_listener_rule_1 = require("@cdktf/provider-aws/lib/lb-listener-rule");
|
|
14
|
+
class AlbListenerRuleConstruct extends constructs_1.Construct {
|
|
15
|
+
constructor(scope, id, props) {
|
|
16
|
+
super(scope, id);
|
|
17
|
+
const { listenerArn, priority, targetGroup, pathPattern, hostHeader, serviceName, environment, tags, } = props;
|
|
18
|
+
// Validate that at least one condition is provided
|
|
19
|
+
if (!pathPattern && !hostHeader) {
|
|
20
|
+
throw new Error(`At least one condition (pathPattern or hostHeader) must be provided for service ${serviceName}`);
|
|
21
|
+
}
|
|
22
|
+
// Build conditions array
|
|
23
|
+
const conditions = [];
|
|
24
|
+
if (pathPattern) {
|
|
25
|
+
conditions.push({
|
|
26
|
+
pathPattern: {
|
|
27
|
+
values: [pathPattern],
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (hostHeader) {
|
|
32
|
+
conditions.push({
|
|
33
|
+
hostHeader: {
|
|
34
|
+
values: [hostHeader],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// Create Listener Rule
|
|
39
|
+
this.listenerRule = new lb_listener_rule_1.LbListenerRule(this, 'listener-rule', {
|
|
40
|
+
listenerArn,
|
|
41
|
+
priority,
|
|
42
|
+
action: [
|
|
43
|
+
{
|
|
44
|
+
type: 'forward',
|
|
45
|
+
targetGroupArn: targetGroup.arn,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
condition: conditions,
|
|
49
|
+
tags: {
|
|
50
|
+
Name: `${environment}-${serviceName}-rule`,
|
|
51
|
+
Environment: environment,
|
|
52
|
+
Service: serviceName,
|
|
53
|
+
Priority: priority.toString(),
|
|
54
|
+
ManagedBy: 'banshee-rx-0',
|
|
55
|
+
...tags,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get a human-readable description of the rule conditions
|
|
61
|
+
*/
|
|
62
|
+
getConditionDescription() {
|
|
63
|
+
const conditions = [];
|
|
64
|
+
// Note: We can't access the actual values from the construct props after construction
|
|
65
|
+
// This method would need to be called with the original props
|
|
66
|
+
// For now, return a generic description
|
|
67
|
+
return 'ALB Listener Rule';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Static helper to format condition description
|
|
71
|
+
*/
|
|
72
|
+
static formatConditions(pathPattern, hostHeader) {
|
|
73
|
+
const conditions = [];
|
|
74
|
+
if (pathPattern)
|
|
75
|
+
conditions.push(`Path: ${pathPattern}`);
|
|
76
|
+
if (hostHeader)
|
|
77
|
+
conditions.push(`Host: ${hostHeader}`);
|
|
78
|
+
return conditions.join(', ');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.AlbListenerRuleConstruct = AlbListenerRuleConstruct;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ECS Service Construct
|
|
3
|
+
*
|
|
4
|
+
* Creates an ECS Service with all required resources:
|
|
5
|
+
* - Security Group
|
|
6
|
+
* - CloudWatch Log Group
|
|
7
|
+
* - IAM Roles (Task Role, Execution Role)
|
|
8
|
+
* - ECS Task Definition
|
|
9
|
+
* - ECS Service
|
|
10
|
+
* - Target Group
|
|
11
|
+
*/
|
|
12
|
+
import { Construct } from 'constructs';
|
|
13
|
+
import { SecurityGroup } from '@cdktf/provider-aws/lib/security-group';
|
|
14
|
+
import { EcsTaskDefinition } from '@cdktf/provider-aws/lib/ecs-task-definition';
|
|
15
|
+
import { EcsService } from '@cdktf/provider-aws/lib/ecs-service';
|
|
16
|
+
import { LbTargetGroup } from '@cdktf/provider-aws/lib/lb-target-group';
|
|
17
|
+
import { EcsServiceConfig } from '../interfaces/ecs-service-config';
|
|
18
|
+
import { InfrastructureRefs } from '../interfaces/infrastructure-refs';
|
|
19
|
+
export interface EcsServiceConstructProps {
|
|
20
|
+
config: EcsServiceConfig;
|
|
21
|
+
infrastructureRefs: InfrastructureRefs;
|
|
22
|
+
}
|
|
23
|
+
export declare class EcsServiceConstruct extends Construct {
|
|
24
|
+
readonly service: EcsService;
|
|
25
|
+
readonly targetGroup: LbTargetGroup;
|
|
26
|
+
readonly securityGroup: SecurityGroup;
|
|
27
|
+
readonly taskDefinition: EcsTaskDefinition;
|
|
28
|
+
constructor(scope: Construct, id: string, props: EcsServiceConstructProps);
|
|
29
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ECS Service Construct
|
|
4
|
+
*
|
|
5
|
+
* Creates an ECS Service with all required resources:
|
|
6
|
+
* - Security Group
|
|
7
|
+
* - CloudWatch Log Group
|
|
8
|
+
* - IAM Roles (Task Role, Execution Role)
|
|
9
|
+
* - ECS Task Definition
|
|
10
|
+
* - ECS Service
|
|
11
|
+
* - Target Group
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.EcsServiceConstruct = void 0;
|
|
15
|
+
const constructs_1 = require("constructs");
|
|
16
|
+
const security_group_1 = require("@cdktf/provider-aws/lib/security-group");
|
|
17
|
+
const security_group_rule_1 = require("@cdktf/provider-aws/lib/security-group-rule");
|
|
18
|
+
const cloudwatch_log_group_1 = require("@cdktf/provider-aws/lib/cloudwatch-log-group");
|
|
19
|
+
const iam_role_1 = require("@cdktf/provider-aws/lib/iam-role");
|
|
20
|
+
const iam_role_policy_attachment_1 = require("@cdktf/provider-aws/lib/iam-role-policy-attachment");
|
|
21
|
+
const ecs_task_definition_1 = require("@cdktf/provider-aws/lib/ecs-task-definition");
|
|
22
|
+
const ecs_service_1 = require("@cdktf/provider-aws/lib/ecs-service");
|
|
23
|
+
const lb_target_group_1 = require("@cdktf/provider-aws/lib/lb-target-group");
|
|
24
|
+
const ecs_service_config_1 = require("../interfaces/ecs-service-config");
|
|
25
|
+
class EcsServiceConstruct extends constructs_1.Construct {
|
|
26
|
+
constructor(scope, id, props) {
|
|
27
|
+
super(scope, id);
|
|
28
|
+
const { config, infrastructureRefs } = props;
|
|
29
|
+
const fullServiceName = `${config.environment}-${config.serviceName}`;
|
|
30
|
+
// Create Security Group for ECS Service
|
|
31
|
+
this.securityGroup = new security_group_1.SecurityGroup(this, 'security-group', {
|
|
32
|
+
name: `${fullServiceName}-ecs-sg`,
|
|
33
|
+
description: `Security group for ${fullServiceName} ECS service`,
|
|
34
|
+
vpcId: infrastructureRefs.vpcId,
|
|
35
|
+
tags: {
|
|
36
|
+
Name: `${fullServiceName}-ecs-sg`,
|
|
37
|
+
Environment: config.environment,
|
|
38
|
+
Service: config.serviceName,
|
|
39
|
+
ManagedBy: 'banshee-rx-0',
|
|
40
|
+
...config.tags,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
// Allow inbound traffic from ALB on container port
|
|
44
|
+
new security_group_rule_1.SecurityGroupRule(this, 'ingress-from-alb', {
|
|
45
|
+
type: 'ingress',
|
|
46
|
+
fromPort: config.containerPort,
|
|
47
|
+
toPort: config.containerPort,
|
|
48
|
+
protocol: 'tcp',
|
|
49
|
+
sourceSecurityGroupId: infrastructureRefs.albSecurityGroupId,
|
|
50
|
+
securityGroupId: this.securityGroup.id,
|
|
51
|
+
description: `Allow traffic from ALB to ${fullServiceName}`,
|
|
52
|
+
});
|
|
53
|
+
// Allow all outbound traffic
|
|
54
|
+
new security_group_rule_1.SecurityGroupRule(this, 'egress-all', {
|
|
55
|
+
type: 'egress',
|
|
56
|
+
fromPort: 0,
|
|
57
|
+
toPort: 0,
|
|
58
|
+
protocol: '-1',
|
|
59
|
+
cidrBlocks: ['0.0.0.0/0'],
|
|
60
|
+
securityGroupId: this.securityGroup.id,
|
|
61
|
+
description: 'Allow all outbound traffic',
|
|
62
|
+
});
|
|
63
|
+
// Create CloudWatch Log Group
|
|
64
|
+
const logGroup = new cloudwatch_log_group_1.CloudwatchLogGroup(this, 'log-group', {
|
|
65
|
+
name: `/ecs/${fullServiceName}`,
|
|
66
|
+
retentionInDays: config.logRetentionDays || ecs_service_config_1.ECS_SERVICE_DEFAULTS.logRetentionDays,
|
|
67
|
+
tags: {
|
|
68
|
+
Name: `/ecs/${fullServiceName}`,
|
|
69
|
+
Environment: config.environment,
|
|
70
|
+
Service: config.serviceName,
|
|
71
|
+
ManagedBy: 'banshee-rx-0',
|
|
72
|
+
...config.tags,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
// Create Task Execution Role
|
|
76
|
+
const executionRole = new iam_role_1.IamRole(this, 'execution-role', {
|
|
77
|
+
name: `${fullServiceName}-execution-role`,
|
|
78
|
+
assumeRolePolicy: JSON.stringify({
|
|
79
|
+
Version: '2012-10-17',
|
|
80
|
+
Statement: [
|
|
81
|
+
{
|
|
82
|
+
Effect: 'Allow',
|
|
83
|
+
Principal: {
|
|
84
|
+
Service: 'ecs-tasks.amazonaws.com',
|
|
85
|
+
},
|
|
86
|
+
Action: 'sts:AssumeRole',
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
}),
|
|
90
|
+
tags: {
|
|
91
|
+
Name: `${fullServiceName}-execution-role`,
|
|
92
|
+
Environment: config.environment,
|
|
93
|
+
Service: config.serviceName,
|
|
94
|
+
ManagedBy: 'banshee-rx-0',
|
|
95
|
+
...config.tags,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
// Attach ECS Task Execution Role Policy
|
|
99
|
+
new iam_role_policy_attachment_1.IamRolePolicyAttachment(this, 'execution-role-policy', {
|
|
100
|
+
role: executionRole.name,
|
|
101
|
+
policyArn: 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
|
|
102
|
+
});
|
|
103
|
+
// Create Task Role
|
|
104
|
+
const taskRole = new iam_role_1.IamRole(this, 'task-role', {
|
|
105
|
+
name: `${fullServiceName}-task-role`,
|
|
106
|
+
assumeRolePolicy: JSON.stringify({
|
|
107
|
+
Version: '2012-10-17',
|
|
108
|
+
Statement: [
|
|
109
|
+
{
|
|
110
|
+
Effect: 'Allow',
|
|
111
|
+
Principal: {
|
|
112
|
+
Service: 'ecs-tasks.amazonaws.com',
|
|
113
|
+
},
|
|
114
|
+
Action: 'sts:AssumeRole',
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
}),
|
|
118
|
+
tags: {
|
|
119
|
+
Name: `${fullServiceName}-task-role`,
|
|
120
|
+
Environment: config.environment,
|
|
121
|
+
Service: config.serviceName,
|
|
122
|
+
ManagedBy: 'banshee-rx-0',
|
|
123
|
+
...config.tags,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
// Build environment variables array
|
|
127
|
+
const environment = config.environmentVariables
|
|
128
|
+
? Object.entries(config.environmentVariables).map(([name, value]) => ({
|
|
129
|
+
name,
|
|
130
|
+
value,
|
|
131
|
+
}))
|
|
132
|
+
: [];
|
|
133
|
+
// Build container definition
|
|
134
|
+
const containerDefinitions = [
|
|
135
|
+
{
|
|
136
|
+
name: config.serviceName,
|
|
137
|
+
image: config.containerImage,
|
|
138
|
+
cpu: config.cpu,
|
|
139
|
+
memory: config.memory,
|
|
140
|
+
essential: true,
|
|
141
|
+
portMappings: [
|
|
142
|
+
{
|
|
143
|
+
containerPort: config.containerPort,
|
|
144
|
+
protocol: 'tcp',
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
environment,
|
|
148
|
+
secrets: config.secrets || [],
|
|
149
|
+
logConfiguration: {
|
|
150
|
+
logDriver: 'awslogs',
|
|
151
|
+
options: {
|
|
152
|
+
'awslogs-group': logGroup.name,
|
|
153
|
+
'awslogs-region': infrastructureRefs.region,
|
|
154
|
+
'awslogs-stream-prefix': 'ecs',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
// Create ECS Task Definition
|
|
160
|
+
this.taskDefinition = new ecs_task_definition_1.EcsTaskDefinition(this, 'task-definition', {
|
|
161
|
+
family: fullServiceName,
|
|
162
|
+
networkMode: 'awsvpc',
|
|
163
|
+
requiresCompatibilities: ['FARGATE'],
|
|
164
|
+
cpu: config.cpu.toString(),
|
|
165
|
+
memory: config.memory.toString(),
|
|
166
|
+
executionRoleArn: executionRole.arn,
|
|
167
|
+
taskRoleArn: taskRole.arn,
|
|
168
|
+
containerDefinitions: JSON.stringify(containerDefinitions),
|
|
169
|
+
tags: {
|
|
170
|
+
Name: fullServiceName,
|
|
171
|
+
Environment: config.environment,
|
|
172
|
+
Service: config.serviceName,
|
|
173
|
+
ManagedBy: 'banshee-rx-0',
|
|
174
|
+
...config.tags,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
// Create Target Group
|
|
178
|
+
this.targetGroup = new lb_target_group_1.LbTargetGroup(this, 'target-group', {
|
|
179
|
+
name: `${fullServiceName}-tg`,
|
|
180
|
+
port: config.containerPort,
|
|
181
|
+
protocol: config.targetGroupProtocol || ecs_service_config_1.ECS_SERVICE_DEFAULTS.targetGroupProtocol,
|
|
182
|
+
vpcId: infrastructureRefs.vpcId,
|
|
183
|
+
targetType: 'ip',
|
|
184
|
+
deregistrationDelay: (config.deregistrationDelay || ecs_service_config_1.ECS_SERVICE_DEFAULTS.deregistrationDelay).toString(),
|
|
185
|
+
healthCheck: {
|
|
186
|
+
enabled: true,
|
|
187
|
+
path: config.healthCheckPath,
|
|
188
|
+
protocol: config.targetGroupProtocol || ecs_service_config_1.ECS_SERVICE_DEFAULTS.targetGroupProtocol,
|
|
189
|
+
interval: config.healthCheckInterval || ecs_service_config_1.ECS_SERVICE_DEFAULTS.healthCheckInterval,
|
|
190
|
+
timeout: config.healthCheckTimeout || ecs_service_config_1.ECS_SERVICE_DEFAULTS.healthCheckTimeout,
|
|
191
|
+
healthyThreshold: config.healthCheckHealthyThreshold || ecs_service_config_1.ECS_SERVICE_DEFAULTS.healthCheckHealthyThreshold,
|
|
192
|
+
unhealthyThreshold: config.healthCheckUnhealthyThreshold || ecs_service_config_1.ECS_SERVICE_DEFAULTS.healthCheckUnhealthyThreshold,
|
|
193
|
+
matcher: '200',
|
|
194
|
+
},
|
|
195
|
+
tags: {
|
|
196
|
+
Name: `${fullServiceName}-tg`,
|
|
197
|
+
Environment: config.environment,
|
|
198
|
+
Service: config.serviceName,
|
|
199
|
+
ManagedBy: 'banshee-rx-0',
|
|
200
|
+
...config.tags,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
// Create ECS Service
|
|
204
|
+
this.service = new ecs_service_1.EcsService(this, 'service', {
|
|
205
|
+
name: fullServiceName,
|
|
206
|
+
cluster: infrastructureRefs.ecsClusterArn,
|
|
207
|
+
taskDefinition: this.taskDefinition.arn,
|
|
208
|
+
desiredCount: config.desiredCount,
|
|
209
|
+
launchType: 'FARGATE',
|
|
210
|
+
networkConfiguration: {
|
|
211
|
+
subnets: infrastructureRefs.privateSubnetIds,
|
|
212
|
+
securityGroups: [this.securityGroup.id],
|
|
213
|
+
assignPublicIp: false,
|
|
214
|
+
},
|
|
215
|
+
loadBalancer: [
|
|
216
|
+
{
|
|
217
|
+
targetGroupArn: this.targetGroup.arn,
|
|
218
|
+
containerName: config.serviceName,
|
|
219
|
+
containerPort: config.containerPort,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
tags: {
|
|
223
|
+
Name: fullServiceName,
|
|
224
|
+
Environment: config.environment,
|
|
225
|
+
Service: config.serviceName,
|
|
226
|
+
ManagedBy: 'banshee-rx-0',
|
|
227
|
+
...config.tags,
|
|
228
|
+
},
|
|
229
|
+
// Ignore changes to desired count if auto-scaling is enabled
|
|
230
|
+
lifecycle: config.enableAutoScaling
|
|
231
|
+
? {
|
|
232
|
+
ignoreChanges: ['desired_count'],
|
|
233
|
+
}
|
|
234
|
+
: undefined,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
exports.EcsServiceConstruct = EcsServiceConstruct;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ECS Service Configuration Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the configuration structure for creating ECS services with ALB integration.
|
|
5
|
+
*/
|
|
6
|
+
export interface EcsServiceConfig {
|
|
7
|
+
serviceName: string;
|
|
8
|
+
environment: string;
|
|
9
|
+
containerImage: string;
|
|
10
|
+
containerPort: number;
|
|
11
|
+
cpu: number;
|
|
12
|
+
memory: number;
|
|
13
|
+
desiredCount: number;
|
|
14
|
+
environmentVariables?: Record<string, string>;
|
|
15
|
+
secrets?: Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
valueFrom: string;
|
|
18
|
+
}>;
|
|
19
|
+
healthCheckPath: string;
|
|
20
|
+
healthCheckInterval?: number;
|
|
21
|
+
healthCheckTimeout?: number;
|
|
22
|
+
healthCheckHealthyThreshold?: number;
|
|
23
|
+
healthCheckUnhealthyThreshold?: number;
|
|
24
|
+
listenerRulePriority: number;
|
|
25
|
+
pathPattern?: string;
|
|
26
|
+
hostHeader?: string;
|
|
27
|
+
deregistrationDelay?: number;
|
|
28
|
+
targetGroupProtocol?: string;
|
|
29
|
+
enableAutoScaling?: boolean;
|
|
30
|
+
minCapacity?: number;
|
|
31
|
+
maxCapacity?: number;
|
|
32
|
+
targetCpuUtilization?: number;
|
|
33
|
+
targetMemoryUtilization?: number;
|
|
34
|
+
logRetentionDays?: number;
|
|
35
|
+
tags?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Default values for optional ECS service configuration
|
|
39
|
+
*/
|
|
40
|
+
export declare const ECS_SERVICE_DEFAULTS: {
|
|
41
|
+
readonly healthCheckInterval: 30;
|
|
42
|
+
readonly healthCheckTimeout: 5;
|
|
43
|
+
readonly healthCheckHealthyThreshold: 2;
|
|
44
|
+
readonly healthCheckUnhealthyThreshold: 3;
|
|
45
|
+
readonly deregistrationDelay: 30;
|
|
46
|
+
readonly targetGroupProtocol: "HTTP";
|
|
47
|
+
readonly logRetentionDays: 7;
|
|
48
|
+
readonly enableAutoScaling: false;
|
|
49
|
+
readonly minCapacity: 1;
|
|
50
|
+
readonly maxCapacity: 10;
|
|
51
|
+
readonly targetCpuUtilization: 70;
|
|
52
|
+
readonly targetMemoryUtilization: 80;
|
|
53
|
+
};
|