nodejs-quickstart-structure 2.2.0 → 2.3.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/CHANGELOG.md +15 -0
- package/README.md +14 -13
- package/bin/index.js +2 -1
- package/lib/generator.js +10 -1
- package/lib/modules/project-setup.js +41 -0
- package/lib/modules/terraform-setup.js +131 -0
- package/lib/prompts.js +22 -3
- package/package.json +1 -1
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +2 -0
- package/templates/clean-architecture/js/src/usecases/CreateUser.js.ejs +5 -2
- package/templates/clean-architecture/ts/src/index.ts.ejs +2 -0
- package/templates/clean-architecture/ts/src/usecases/createUser.ts.ejs +4 -2
- package/templates/clean-architecture/ts/src/utils/httpCodes.ts +1 -0
- package/templates/common/auth/js/controllers/authController.js.ejs +42 -12
- package/templates/common/auth/js/controllers/authController.spec.js.ejs +95 -5
- package/templates/common/auth/js/services/jwtService.js.ejs +3 -3
- package/templates/common/auth/js/services/socialAuthService.spec.js.ejs +0 -2
- package/templates/common/auth/ts/controllers/authController.spec.ts.ejs +29 -7
- package/templates/common/auth/ts/controllers/authController.ts.ejs +34 -5
- package/templates/common/caching/clean/js/CreateUser.js.ejs +4 -2
- package/templates/common/caching/clean/ts/createUser.ts.ejs +4 -2
- package/templates/common/eslint.config.mjs.ejs +4 -1
- package/templates/common/kafka/js/services/kafkaService.js.ejs +1 -1
- package/templates/common/package.json.ejs +2 -0
- package/templates/common/terraform/main.tf +52 -0
- package/templates/common/terraform/modules/cache/main.tf +41 -0
- package/templates/common/terraform/modules/cache/outputs.tf +7 -0
- package/templates/common/terraform/modules/cache/variables.tf +4 -0
- package/templates/common/terraform/modules/compute/main.tf +69 -0
- package/templates/common/terraform/modules/compute/outputs.tf +7 -0
- package/templates/common/terraform/modules/compute/variables.tf +20 -0
- package/templates/common/terraform/modules/database/main.tf +57 -0
- package/templates/common/terraform/modules/database/outputs.tf +16 -0
- package/templates/common/terraform/modules/database/variables.tf +27 -0
- package/templates/common/terraform/modules/security/main.tf +130 -0
- package/templates/common/terraform/modules/security/outputs.tf +15 -0
- package/templates/common/terraform/modules/security/variables.tf +12 -0
- package/templates/common/terraform/modules/vpc/main.tf +134 -0
- package/templates/common/terraform/modules/vpc/outputs.tf +19 -0
- package/templates/common/terraform/modules/vpc/variables.tf +45 -0
- package/templates/common/terraform/outputs.tf +29 -0
- package/templates/common/terraform/provider.tf +17 -0
- package/templates/common/terraform/variables.tf +33 -0
- package/templates/mvc/js/src/index.js.ejs +2 -0
- package/templates/mvc/js/src/utils/httpCodes.js +1 -0
- package/templates/mvc/ts/src/index.ts.ejs +2 -0
- package/templates/mvc/ts/src/utils/httpCodes.ts +1 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Security Group for RDS (Only from App SG)
|
|
2
|
+
resource "aws_security_group" "db_sg" {
|
|
3
|
+
name = "${var.project_name}-db-sg"
|
|
4
|
+
description = "Allow traffic from App only"
|
|
5
|
+
vpc_id = var.vpc_id
|
|
6
|
+
|
|
7
|
+
ingress {
|
|
8
|
+
from_port = var.db_engine == "mysql" ? 3306 : 5432
|
|
9
|
+
to_port = var.db_engine == "mysql" ? 3306 : 5432
|
|
10
|
+
protocol = "tcp"
|
|
11
|
+
security_groups = [var.app_sg_id]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
egress {
|
|
15
|
+
from_port = 0
|
|
16
|
+
to_port = 0
|
|
17
|
+
protocol = "-1"
|
|
18
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
tags = { Name = "${var.project_name}-db-sg" }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Subnet Group for RDS
|
|
25
|
+
resource "aws_db_subnet_group" "main" {
|
|
26
|
+
name = "${var.project_name}-db-subnet-group"
|
|
27
|
+
subnet_ids = var.isolated_subnet_ids
|
|
28
|
+
|
|
29
|
+
tags = { Name = "${var.project_name}-db-subnet-group" }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Generate random password
|
|
33
|
+
resource "random_password" "db_password" {
|
|
34
|
+
length = 16
|
|
35
|
+
special = true
|
|
36
|
+
override_special = "!#$%&*()-_=+[]{}<>:?"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# RDS Instance
|
|
40
|
+
resource "aws_db_instance" "main" {
|
|
41
|
+
identifier = "${var.project_name}-db"
|
|
42
|
+
allocated_storage = 20
|
|
43
|
+
engine = var.db_engine
|
|
44
|
+
instance_class = var.db_instance_class
|
|
45
|
+
db_name = var.db_name
|
|
46
|
+
username = var.db_user
|
|
47
|
+
password = random_password.db_password.result
|
|
48
|
+
db_subnet_group_name = aws_db_subnet_group.main.name
|
|
49
|
+
vpc_security_group_ids = [aws_security_group.db_sg.id]
|
|
50
|
+
skip_final_snapshot = true
|
|
51
|
+
multi_az = var.multi_az
|
|
52
|
+
|
|
53
|
+
# Encryption at rest (Security Hardening)
|
|
54
|
+
storage_encrypted = true
|
|
55
|
+
|
|
56
|
+
tags = { Name = "${var.project_name}-db" }
|
|
57
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
output "db_endpoint" {
|
|
2
|
+
value = aws_db_instance.main.endpoint
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
output "db_name" {
|
|
6
|
+
value = aws_db_instance.main.db_name
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
output "db_user" {
|
|
10
|
+
value = aws_db_instance.main.username
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
output "db_password" {
|
|
14
|
+
value = random_password.db_password.result
|
|
15
|
+
sensitive = true
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
variable "project_name" { type = string }
|
|
2
|
+
variable "environment" { type = string }
|
|
3
|
+
variable "vpc_id" { type = string }
|
|
4
|
+
variable "isolated_subnet_ids" { type = list(string) }
|
|
5
|
+
variable "app_sg_id" { type = string }
|
|
6
|
+
variable "multi_az" {
|
|
7
|
+
type = bool
|
|
8
|
+
default = false
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "db_engine" {
|
|
12
|
+
description = "Database engine (mysql, postgres)"
|
|
13
|
+
type = string
|
|
14
|
+
default = "mysql"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
variable "db_instance_class" {
|
|
18
|
+
default = "db.t3.micro"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
variable "db_name" {
|
|
22
|
+
default = "myappdb"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
variable "db_user" {
|
|
26
|
+
default = "admin"
|
|
27
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# --- Security Groups ---
|
|
2
|
+
|
|
3
|
+
# ALB Security Group (Public access)
|
|
4
|
+
resource "aws_security_group" "alb_sg" {
|
|
5
|
+
name = "${var.project_name}-alb-sg"
|
|
6
|
+
description = "Allow HTTP/HTTPS from everywhere"
|
|
7
|
+
vpc_id = var.vpc_id
|
|
8
|
+
|
|
9
|
+
ingress {
|
|
10
|
+
from_port = 80
|
|
11
|
+
to_port = 80
|
|
12
|
+
protocol = "tcp"
|
|
13
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
egress {
|
|
17
|
+
from_port = 0
|
|
18
|
+
to_port = 0
|
|
19
|
+
protocol = "-1"
|
|
20
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
tags = { Name = "${var.project_name}-alb-sg" }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# App Security Group (Only from ALB)
|
|
27
|
+
resource "aws_security_group" "app_sg" {
|
|
28
|
+
name = "${var.project_name}-app-sg"
|
|
29
|
+
description = "Allow traffic only from ALB"
|
|
30
|
+
vpc_id = var.vpc_id
|
|
31
|
+
|
|
32
|
+
ingress {
|
|
33
|
+
from_port = var.app_port
|
|
34
|
+
to_port = var.app_port
|
|
35
|
+
protocol = "tcp"
|
|
36
|
+
security_groups = [aws_security_group.alb_sg.id]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
egress {
|
|
40
|
+
from_port = 0
|
|
41
|
+
to_port = 0
|
|
42
|
+
protocol = "-1"
|
|
43
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tags = { Name = "${var.project_name}-app-sg" }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# --- Load Balancer ---
|
|
50
|
+
resource "aws_lb" "main" {
|
|
51
|
+
name = "${var.project_name}-alb"
|
|
52
|
+
internal = false
|
|
53
|
+
load_balancer_type = "application"
|
|
54
|
+
security_groups = [aws_security_group.alb_sg.id]
|
|
55
|
+
subnets = var.public_subnet_ids
|
|
56
|
+
|
|
57
|
+
tags = { Name = "${var.project_name}-alb" }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
resource "aws_lb_target_group" "app" {
|
|
61
|
+
name = "${var.project_name}-tg"
|
|
62
|
+
port = var.app_port
|
|
63
|
+
protocol = "HTTP"
|
|
64
|
+
vpc_id = var.vpc_id
|
|
65
|
+
|
|
66
|
+
health_check {
|
|
67
|
+
path = "/health"
|
|
68
|
+
healthy_threshold = 2
|
|
69
|
+
unhealthy_threshold = 10
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
resource "aws_lb_listener" "http" {
|
|
74
|
+
load_balancer_arn = aws_lb.main.arn
|
|
75
|
+
port = "80"
|
|
76
|
+
protocol = "HTTP"
|
|
77
|
+
|
|
78
|
+
default_action {
|
|
79
|
+
type = "forward"
|
|
80
|
+
target_group_arn = aws_lb_target_group.app.arn
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# --- AWS WAF (Web Application Firewall) ---
|
|
85
|
+
# Simple WAF with Common Rules (SQLi, Linux, etc.)
|
|
86
|
+
resource "aws_wafv2_web_acl" "main" {
|
|
87
|
+
count = var.enable_waf ? 1 : 0
|
|
88
|
+
name = "${var.project_name}-waf"
|
|
89
|
+
description = "WAF for Node.js Application"
|
|
90
|
+
scope = "REGIONAL"
|
|
91
|
+
|
|
92
|
+
default_action {
|
|
93
|
+
allow {}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
rule {
|
|
97
|
+
name = "AWSManagedRulesCommonRuleSet"
|
|
98
|
+
priority = 1
|
|
99
|
+
|
|
100
|
+
override_action {
|
|
101
|
+
none {}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
statement {
|
|
105
|
+
managed_rule_group_statement {
|
|
106
|
+
name = "AWSManagedRulesCommonRuleSet"
|
|
107
|
+
vendor_name = "AWS"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
visibility_config {
|
|
112
|
+
cloudwatch_metrics_enabled = true
|
|
113
|
+
metric_name = "WAFCommonRule"
|
|
114
|
+
sampled_requests_enabled = true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
visibility_config {
|
|
119
|
+
cloudwatch_metrics_enabled = true
|
|
120
|
+
metric_name = "WAFMain"
|
|
121
|
+
sampled_requests_enabled = true
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Associate WAF with ALB
|
|
126
|
+
resource "aws_wafv2_web_acl_association" "main" {
|
|
127
|
+
count = var.enable_waf ? 1 : 0
|
|
128
|
+
resource_arn = aws_lb.main.arn
|
|
129
|
+
web_acl_arn = aws_wafv2_web_acl.main[0].arn
|
|
130
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
output "alb_dns_name" {
|
|
2
|
+
value = aws_lb.main.dns_name
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
output "alb_target_group_arn" {
|
|
6
|
+
value = aws_lb_target_group.app.arn
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
output "app_sg_id" {
|
|
10
|
+
value = aws_security_group.app_sg.id
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
output "alb_sg_id" {
|
|
14
|
+
value = aws_security_group.alb_sg.id
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
variable "project_name" { type = string }
|
|
2
|
+
variable "environment" { type = string }
|
|
3
|
+
variable "vpc_id" { type = string }
|
|
4
|
+
variable "public_subnet_ids" { type = list(string) }
|
|
5
|
+
variable "enable_waf" {
|
|
6
|
+
type = bool
|
|
7
|
+
default = false
|
|
8
|
+
}
|
|
9
|
+
variable "app_port" {
|
|
10
|
+
type = number
|
|
11
|
+
default = 3000
|
|
12
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
resource "aws_vpc" "main" {
|
|
2
|
+
cidr_block = var.vpc_cidr
|
|
3
|
+
enable_dns_hostnames = true
|
|
4
|
+
enable_dns_support = true
|
|
5
|
+
|
|
6
|
+
tags = {
|
|
7
|
+
Name = "${var.project_name}-vpc"
|
|
8
|
+
Environment = var.environment
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
# --- Internet Gateway ---
|
|
13
|
+
resource "aws_internet_gateway" "igw" {
|
|
14
|
+
vpc_id = aws_vpc.main.id
|
|
15
|
+
|
|
16
|
+
tags = {
|
|
17
|
+
Name = "${var.project_name}-igw"
|
|
18
|
+
Environment = var.environment
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# --- Subnets ---
|
|
23
|
+
|
|
24
|
+
# Public Subnets (For ALB and NAT GW)
|
|
25
|
+
resource "aws_subnet" "public" {
|
|
26
|
+
count = length(var.public_subnets)
|
|
27
|
+
vpc_id = aws_vpc.main.id
|
|
28
|
+
cidr_block = var.public_subnets[count.index]
|
|
29
|
+
availability_zone = var.availability_zones[count.index]
|
|
30
|
+
map_public_ip_on_launch = true
|
|
31
|
+
|
|
32
|
+
tags = {
|
|
33
|
+
Name = "${var.project_name}-public-${count.index + 1}"
|
|
34
|
+
Type = "Public"
|
|
35
|
+
Environment = var.environment
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Private Subnets (For Application)
|
|
40
|
+
resource "aws_subnet" "private" {
|
|
41
|
+
count = length(var.private_subnets)
|
|
42
|
+
vpc_id = aws_vpc.main.id
|
|
43
|
+
cidr_block = var.private_subnets[count.index]
|
|
44
|
+
availability_zone = var.availability_zones[count.index]
|
|
45
|
+
|
|
46
|
+
tags = {
|
|
47
|
+
Name = "${var.project_name}-private-${count.index + 1}"
|
|
48
|
+
Type = "Private"
|
|
49
|
+
Environment = var.environment
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Isolated Subnets (For Database)
|
|
54
|
+
resource "aws_subnet" "isolated" {
|
|
55
|
+
count = length(var.isolated_subnets)
|
|
56
|
+
vpc_id = aws_vpc.main.id
|
|
57
|
+
cidr_block = var.isolated_subnets[count.index]
|
|
58
|
+
availability_zone = var.availability_zones[count.index]
|
|
59
|
+
|
|
60
|
+
tags = {
|
|
61
|
+
Name = "${var.project_name}-isolated-${count.index + 1}"
|
|
62
|
+
Type = "Isolated"
|
|
63
|
+
Environment = var.environment
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# --- NAT Gateway (1 per AZ for Production, 1 total for Standard) ---
|
|
68
|
+
resource "aws_eip" "nat" {
|
|
69
|
+
count = var.is_production ? length(var.public_subnets) : 1
|
|
70
|
+
domain = "vpc"
|
|
71
|
+
tags = { Name = "${var.project_name}-nat-eip-${count.index + 1}" }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
resource "aws_nat_gateway" "main" {
|
|
75
|
+
count = var.is_production ? length(var.public_subnets) : 1
|
|
76
|
+
allocation_id = aws_eip.nat[count.index].id
|
|
77
|
+
subnet_id = aws_subnet.public[count.index].id
|
|
78
|
+
|
|
79
|
+
tags = {
|
|
80
|
+
Name = "${var.project_name}-nat-gw-${count.index + 1}"
|
|
81
|
+
Environment = var.environment
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# --- Routing Tables ---
|
|
86
|
+
|
|
87
|
+
# Public Route Table
|
|
88
|
+
resource "aws_route_table" "public" {
|
|
89
|
+
vpc_id = aws_vpc.main.id
|
|
90
|
+
|
|
91
|
+
route {
|
|
92
|
+
cidr_block = "0.0.0.0/0"
|
|
93
|
+
gateway_id = aws_internet_gateway.igw.id
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
tags = { Name = "${var.project_name}-public-rt" }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
resource "aws_route_table_association" "public" {
|
|
100
|
+
count = length(var.public_subnets)
|
|
101
|
+
subnet_id = aws_subnet.public[count.index].id
|
|
102
|
+
route_table_id = aws_route_table.public.id
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Private Route Tables (1 per AZ for Production, 1 total for Standard)
|
|
106
|
+
resource "aws_route_table" "private" {
|
|
107
|
+
count = var.is_production ? length(var.private_subnets) : 1
|
|
108
|
+
vpc_id = aws_vpc.main.id
|
|
109
|
+
|
|
110
|
+
route {
|
|
111
|
+
cidr_block = "0.0.0.0/0"
|
|
112
|
+
nat_gateway_id = aws_nat_gateway.main[count.index].id
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
tags = { Name = "${var.project_name}-private-rt-${count.index + 1}" }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
resource "aws_route_table_association" "private" {
|
|
119
|
+
count = length(var.private_subnets)
|
|
120
|
+
subnet_id = aws_subnet.private[count.index].id
|
|
121
|
+
route_table_id = var.is_production ? aws_route_table.private[count.index].id : aws_route_table.private[0].id
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Isolated Route Table (No internet route)
|
|
125
|
+
resource "aws_route_table" "isolated" {
|
|
126
|
+
vpc_id = aws_vpc.main.id
|
|
127
|
+
tags = { Name = "${var.project_name}-isolated-rt" }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
resource "aws_route_table_association" "isolated" {
|
|
131
|
+
count = length(var.isolated_subnets)
|
|
132
|
+
subnet_id = aws_subnet.isolated[count.index].id
|
|
133
|
+
route_table_id = aws_route_table.isolated.id
|
|
134
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
output "vpc_id" {
|
|
2
|
+
value = aws_vpc.main.id
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
output "public_subnet_ids" {
|
|
6
|
+
value = aws_subnet.public[*].id
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
output "private_subnet_ids" {
|
|
10
|
+
value = aws_subnet.private[*].id
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
output "isolated_subnet_ids" {
|
|
14
|
+
value = aws_subnet.isolated[*].id
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
output "nat_gateway_ip" {
|
|
18
|
+
value = aws_nat_gateway.main[*].public_ip
|
|
19
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
variable "vpc_cidr" {
|
|
2
|
+
description = "CIDR block for the VPC"
|
|
3
|
+
type = string
|
|
4
|
+
default = "10.0.0.0/16"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
variable "project_name" {
|
|
8
|
+
description = "Project name for tagging"
|
|
9
|
+
type = string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
variable "environment" {
|
|
13
|
+
description = "Environment name (dev, staging, prod)"
|
|
14
|
+
type = string
|
|
15
|
+
default = "dev"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
variable "availability_zones" {
|
|
19
|
+
description = "List of availability zones"
|
|
20
|
+
type = list(string)
|
|
21
|
+
default = ["us-east-1a", "us-east-1b"]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
variable "public_subnets" {
|
|
25
|
+
description = "CIDR blocks for public subnets"
|
|
26
|
+
type = list(string)
|
|
27
|
+
default = ["10.0.1.0/24", "10.0.2.0/24"]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
variable "private_subnets" {
|
|
31
|
+
description = "CIDR blocks for private subnets"
|
|
32
|
+
type = list(string)
|
|
33
|
+
default = ["10.0.10.0/24", "10.0.11.0/24"]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
variable "isolated_subnets" {
|
|
37
|
+
description = "CIDR blocks for isolated subnets"
|
|
38
|
+
type = list(string)
|
|
39
|
+
default = ["10.0.20.0/24", "10.0.21.0/24"]
|
|
40
|
+
}
|
|
41
|
+
variable "is_production" {
|
|
42
|
+
description = "Enable Production features (Multi-NAT)"
|
|
43
|
+
type = bool
|
|
44
|
+
default = false
|
|
45
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
output "application_url" {
|
|
2
|
+
description = "URL of the application (Load Balancer)"
|
|
3
|
+
value = "http://${module.security.alb_dns_name}"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "database_endpoint" {
|
|
7
|
+
value = module.database.db_endpoint
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
output "database_name" {
|
|
11
|
+
value = module.database.db_name
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
output "database_user" {
|
|
15
|
+
value = module.database.db_user
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
output "database_password" {
|
|
19
|
+
value = module.database.db_password
|
|
20
|
+
sensitive = true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
output "nat_gateway_ip" {
|
|
24
|
+
value = module.vpc.nat_gateway_ip
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
output "redis_endpoint" {
|
|
28
|
+
value = module.cache.redis_endpoint
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
terraform {
|
|
2
|
+
required_version = ">= 1.0.0"
|
|
3
|
+
required_providers {
|
|
4
|
+
aws = {
|
|
5
|
+
source = "hashicorp/aws"
|
|
6
|
+
version = "~> 5.0"
|
|
7
|
+
}
|
|
8
|
+
random = {
|
|
9
|
+
source = "hashicorp/random"
|
|
10
|
+
version = "~> 3.0"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
provider "aws" {
|
|
16
|
+
region = var.aws_region
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
variable "aws_region" {
|
|
2
|
+
description = "AWS region"
|
|
3
|
+
default = "us-east-1"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "project_name" {
|
|
7
|
+
description = "Name of the project"
|
|
8
|
+
default = "nodejs-quickstart"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "environment" {
|
|
12
|
+
description = "Environment (dev, staging, prod)"
|
|
13
|
+
default = "dev"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "db_engine" {
|
|
17
|
+
description = "Database engine (mysql or postgres)"
|
|
18
|
+
default = "mysql"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
variable "db_name" {
|
|
22
|
+
default = "myappdb"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
variable "db_user" {
|
|
26
|
+
default = "admin"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
variable "is_production" {
|
|
30
|
+
description = "Enable production-grade features (Multi-AZ, WAF, Scaling)"
|
|
31
|
+
type = bool
|
|
32
|
+
default = false
|
|
33
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { env } = require('./config/env');
|
|
2
2
|
const express = require('express');
|
|
3
3
|
const cors = require('cors');
|
|
4
|
+
const cookieParser = require('cookie-parser');
|
|
4
5
|
<%_ if (communication === 'REST APIs' || communication === 'Kafka') { -%>const apiRoutes = require('./routes/api');<%_ } %>
|
|
5
6
|
const healthRoutes = require('./routes/healthRoute');
|
|
6
7
|
<%_ if (communication === 'Kafka') { -%>const { connectKafka, sendMessage } = require('./services/kafkaService');<%_ } -%>
|
|
@@ -28,6 +29,7 @@ const morgan = require('morgan');
|
|
|
28
29
|
const { errorMiddleware } = require('./utils/errorMiddleware');
|
|
29
30
|
|
|
30
31
|
app.use(cors());
|
|
32
|
+
app.use(cookieParser());
|
|
31
33
|
app.use(express.json());
|
|
32
34
|
app.use(express.urlencoded({ extended: true }));
|
|
33
35
|
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }));
|
|
@@ -7,6 +7,7 @@ import cors from 'cors';
|
|
|
7
7
|
import helmet from 'helmet';
|
|
8
8
|
import hpp from 'hpp';
|
|
9
9
|
import rateLimit from 'express-rate-limit';
|
|
10
|
+
import cookieParser from 'cookie-parser';
|
|
10
11
|
import logger from '@/utils/logger';
|
|
11
12
|
import morgan from 'morgan';
|
|
12
13
|
import { errorMiddleware } from '@/utils/errorMiddleware';
|
|
@@ -52,6 +53,7 @@ app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
|
|
|
52
53
|
const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
|
|
53
54
|
app.use(limiter);
|
|
54
55
|
|
|
56
|
+
app.use(cookieParser());
|
|
55
57
|
app.use(express.json());
|
|
56
58
|
app.use(express.urlencoded({ extended: true }));
|
|
57
59
|
app.use(morgan('combined', { stream: { write: (message) => logger.info(message.trim()) } }));
|