mirror of
https://github.com/ToolJet/ToolJet
synced 2026-04-21 13:37:28 +00:00
479 lines
12 KiB
HCL
479 lines
12 KiB
HCL
provider "aws" {
|
|
region = var.region
|
|
}
|
|
|
|
|
|
resource "aws_iam_role" "ecs_task_execution_role" {
|
|
name = "ToolJet-task-execution-role"
|
|
|
|
assume_role_policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Principal = {
|
|
Service = "ecs-tasks.amazonaws.com"
|
|
}
|
|
Action = "sts:AssumeRole"
|
|
}]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "ecs_cloudwatch_logs_policy" {
|
|
role = aws_iam_role.ecs_task_execution_role.name
|
|
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
|
|
role = aws_iam_role.ecs_task_execution_role.name
|
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
|
|
}
|
|
|
|
resource "aws_iam_policy" "ssm_policy" {
|
|
name = "ToolJet-ssm-policy"
|
|
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Action = [
|
|
"ssmmessages:CreateControlChannel",
|
|
"ssmmessages:CreateDataChannel",
|
|
"ssmmessages:OpenControlChannel",
|
|
"ssmmessages:OpenDataChannel"
|
|
]
|
|
Resource = "*"
|
|
}]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_policy" "secrets_manager_policy" {
|
|
name = "ToolJet-secrets-manager-policy"
|
|
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Action = "secretsmanager:GetSecretValue"
|
|
Resource = "arn:aws:secretsmanager:${var.region}:${data.aws_caller_identity.current.account_id}:secret:tooljet-secret"
|
|
}]
|
|
})
|
|
}
|
|
|
|
resource "aws_cloudwatch_log_group" "ecs_log_group" {
|
|
name = "/ecs/ToolJet"
|
|
retention_in_days = 30
|
|
}
|
|
|
|
resource "aws_cloudwatch_log_group" "postgrest_log_group" {
|
|
name = "/ecs/postgrest"
|
|
retention_in_days = 30
|
|
}
|
|
|
|
resource "aws_ecs_cluster" "tooljet_cluster" {
|
|
name = "ToolJet"
|
|
|
|
setting {
|
|
name = "containerInsights"
|
|
value = "enabled"
|
|
}
|
|
}
|
|
resource "aws_ecs_task_definition" "tooljet_task_definition" {
|
|
family = var.AppName
|
|
network_mode = "awsvpc"
|
|
requires_compatibilities = ["FARGATE"]
|
|
cpu = "4096"
|
|
memory = "8192"
|
|
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
|
|
task_role_arn = aws_iam_role.ecs_task_execution_role.arn
|
|
|
|
container_definitions = jsonencode([
|
|
{
|
|
name = var.AppName
|
|
image = "tooljet/tooljet:ee-lts-latest"
|
|
cpu = 2048
|
|
memory = 4096
|
|
logConfiguration = {
|
|
logDriver = "awslogs"
|
|
options = {
|
|
awslogs-group = aws_cloudwatch_log_group.ecs_log_group.name
|
|
awslogs-region = var.region
|
|
awslogs-stream-prefix = "tooljet"
|
|
|
|
}
|
|
}
|
|
portMappings = [{
|
|
containerPort = 3000
|
|
hostPort = 3000
|
|
protocol = "tcp"
|
|
name = "tooljet"
|
|
}]
|
|
command = ["npm", "run", "start:prod"]
|
|
environment = [
|
|
{
|
|
name = "TOOLJET_HOST"
|
|
value = aws_lb.tooljet_lb.dns_name
|
|
},
|
|
{
|
|
name = "TOOLJET_DB"
|
|
value = var.TOOLJET_DB
|
|
},
|
|
{
|
|
name = "TOOLJET_DB_HOST"
|
|
value = aws_db_instance.tooljet_database.endpoint
|
|
},
|
|
{
|
|
name = "TOOLJET_DB_USER"
|
|
value = var.TOOLJET_DB_USER
|
|
},
|
|
{
|
|
name = "TOOLJET_DB_PASS"
|
|
value = var.TOOLJET_DB_PASS
|
|
},
|
|
{
|
|
name = "PG_HOST"
|
|
value = aws_db_instance.tooljet_database.endpoint
|
|
},
|
|
{
|
|
name = "PG_USER"
|
|
value = var.PG_USER
|
|
},
|
|
{
|
|
name = "PG_PASS"
|
|
value = var.PG_PASS
|
|
},
|
|
{
|
|
name = "PG_DB"
|
|
value = var.PG_DB
|
|
},
|
|
{
|
|
name = "LOCKBOX_MASTER_KEY"
|
|
value = var.LOCKBOX_MASTER_KEY
|
|
},
|
|
{
|
|
name = "SECRET_KEY_BASE"
|
|
value = var.SECRET_KEY_BASE
|
|
},
|
|
{
|
|
name = "DEPLOYMENT_PLATFORM"
|
|
value = "aws:ecs"
|
|
},
|
|
{
|
|
name = "REDIS_HOST"
|
|
value = var.REDIS_HOST
|
|
},
|
|
{
|
|
name = "REDIS_PORT"
|
|
value = var.REDIS_PORT
|
|
},
|
|
{
|
|
name = "REDIS_USER"
|
|
value = var.REDIS_USER
|
|
},
|
|
{
|
|
name = "REDIS_PASSWORD"
|
|
value = var.REDIS_PASSWORD
|
|
},
|
|
{
|
|
name = "PGSSLMODE"
|
|
value = "require"
|
|
},
|
|
# use this incase using RDS with SSL
|
|
# {
|
|
# name = "NODE_EXTRA_CA_CERTS"
|
|
# value = "/certs/global-bundle.pem"
|
|
# }
|
|
{
|
|
name = "PGRST_HOST"
|
|
value = "127.0.0.1:3002"
|
|
},
|
|
{
|
|
name = "PGRST_SERVER_PORT"
|
|
value = "3002"
|
|
},
|
|
{
|
|
name = "PGRST_DB_URI"
|
|
value = "postgres://${var.TOOLJET_DB_USER}:${var.TOOLJET_DB_PASS}@${aws_db_instance.tooljet_database.endpoint}/${var.TOOLJET_DB}"
|
|
},
|
|
{
|
|
name = "PGRST_JWT_SECRET"
|
|
value = var.PGRST_JWT_SECRET
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name = "redis"
|
|
image = "redis:6.2"
|
|
cpu = 512
|
|
memory = 1024
|
|
essential = true
|
|
logConfiguration = {
|
|
logDriver = "awslogs"
|
|
options = {
|
|
awslogs-group = aws_cloudwatch_log_group.ecs_log_group.name
|
|
awslogs-region = var.region
|
|
awslogs-stream-prefix = "redis"
|
|
}
|
|
}
|
|
portMappings = [{
|
|
containerPort = 6379
|
|
hostPort = 6379
|
|
protocol = "tcp"
|
|
name = "redis"
|
|
}]
|
|
},
|
|
{
|
|
name = "postgrest"
|
|
image = "postgrest/postgrest:v12.2.0"
|
|
cpu = 512
|
|
memory = 1024
|
|
essential = true
|
|
logConfiguration = {
|
|
logDriver = "awslogs"
|
|
options = {
|
|
awslogs-group = aws_cloudwatch_log_group.postgrest_log_group.name
|
|
awslogs-region = var.region
|
|
awslogs-stream-prefix = "postgrest"
|
|
awslogs-create-group = "true"
|
|
}
|
|
}
|
|
portMappings = [{
|
|
containerPort = 3002
|
|
hostPort = 3002
|
|
protocol = "tcp"
|
|
name = "postgrest"
|
|
appProtocol = "http"
|
|
}]
|
|
environment = [
|
|
{
|
|
name = "PGRST_HOST"
|
|
value = "127.0.0.1:3002"
|
|
},
|
|
{
|
|
name = "PGRST_LOG_LEVEL"
|
|
value = "info"
|
|
},
|
|
{
|
|
name = "PGRST_DB_PRE_CONFIG"
|
|
value = "postgrest.pre_config"
|
|
},
|
|
{
|
|
name = "PGRST_SERVER_PORT"
|
|
value = "3002"
|
|
},
|
|
{
|
|
name = "PGRST_DB_URI"
|
|
value = "postgres://${var.TOOLJET_DB_USER}:${var.TOOLJET_DB_PASS}@${aws_db_instance.tooljet_database.endpoint}/${var.TOOLJET_DB}"
|
|
},
|
|
{
|
|
name = "PGRST_JWT_SECRET"
|
|
value = var.PGRST_JWT_SECRET
|
|
}
|
|
]
|
|
}
|
|
])
|
|
|
|
depends_on = [
|
|
aws_db_instance.tooljet_database
|
|
]
|
|
}
|
|
|
|
# depends_on = [
|
|
# aws_db_instance.tooljet_database,
|
|
# aws_memorydb_cluster.tooljet_mem_cluster
|
|
# ]
|
|
|
|
|
|
|
|
resource "aws_ecs_service" "tooljet_service" {
|
|
name = var.ServiceName
|
|
cluster = aws_ecs_cluster.tooljet_cluster.id
|
|
task_definition = aws_ecs_task_definition.tooljet_task_definition.arn
|
|
launch_type = "FARGATE"
|
|
desired_count = 2
|
|
|
|
network_configuration {
|
|
subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
|
|
security_groups = [aws_security_group.task_sg.id]
|
|
assign_public_ip = true
|
|
}
|
|
|
|
load_balancer {
|
|
target_group_arn = aws_lb_target_group.tooljet_target_group.arn
|
|
container_name = var.AppName
|
|
container_port = 3000
|
|
}
|
|
|
|
health_check_grace_period_seconds = 900 # tooljet requires 900 seconds to start
|
|
deployment_maximum_percent = 200
|
|
deployment_minimum_healthy_percent = 100
|
|
}
|
|
|
|
resource "aws_lb" "tooljet_lb" {
|
|
name = "tooljet-lb"
|
|
internal = false
|
|
load_balancer_type = "application"
|
|
security_groups = [aws_security_group.lb_sg.id]
|
|
subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
|
|
}
|
|
|
|
resource "aws_lb_target_group" "tooljet_target_group" {
|
|
name = "tooljet-tg"
|
|
port = 3000
|
|
protocol = "HTTP"
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
target_type = "ip"
|
|
|
|
health_check {
|
|
path = "/api/health"
|
|
protocol = "HTTP"
|
|
}
|
|
}
|
|
|
|
resource "aws_lb_listener" "listener_80" {
|
|
load_balancer_arn = aws_lb.tooljet_lb.arn
|
|
port = 80
|
|
protocol = "HTTP"
|
|
|
|
default_action {
|
|
type = "forward"
|
|
target_group_arn = aws_lb_target_group.tooljet_target_group.arn
|
|
}
|
|
}
|
|
|
|
# resource "aws_lb_listener" "listener_443" {
|
|
# load_balancer_arn = aws_lb.tooljet_lb.arn
|
|
# port = 443
|
|
# protocol = "HTTPS"
|
|
# ssl_policy = "ELBSecurityPolicy-2016-08"
|
|
# certificate_arn = "" # Replace with your certificate ARN
|
|
|
|
# default_action {
|
|
# type = "forward"
|
|
# target_group_arn = aws_lb_target_group.tooljet_target_group.arn
|
|
# }
|
|
# }
|
|
|
|
resource "aws_vpc" "tooljet_vpc" {
|
|
cidr_block = "10.0.0.0/16"
|
|
}
|
|
|
|
resource "aws_subnet" "subnet1" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
cidr_block = "10.0.1.0/24"
|
|
availability_zone = var.aws_subnet_subnet1_AZ
|
|
map_public_ip_on_launch = true
|
|
}
|
|
|
|
resource "aws_subnet" "subnet2" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
cidr_block = "10.0.2.0/24"
|
|
availability_zone = var.aws_subnet_subnet2_AZ
|
|
map_public_ip_on_launch = true
|
|
}
|
|
|
|
resource "aws_internet_gateway" "tooljet_igw" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
}
|
|
|
|
resource "aws_route_table" "public_rt" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
}
|
|
|
|
resource "aws_route" "public_route" {
|
|
route_table_id = aws_route_table.public_rt.id
|
|
destination_cidr_block = "0.0.0.0/0"
|
|
gateway_id = aws_internet_gateway.tooljet_igw.id
|
|
}
|
|
|
|
resource "aws_route_table_association" "subnet1_association" {
|
|
subnet_id = aws_subnet.subnet1.id
|
|
route_table_id = aws_route_table.public_rt.id
|
|
}
|
|
|
|
resource "aws_route_table_association" "subnet2_association" {
|
|
subnet_id = aws_subnet.subnet2.id
|
|
route_table_id = aws_route_table.public_rt.id
|
|
}
|
|
|
|
resource "aws_security_group" "task_sg" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
|
|
ingress {
|
|
description = "ToolJet application port"
|
|
from_port = 3000
|
|
to_port = 3000
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.lb_sg.id]
|
|
}
|
|
ingress {
|
|
description = "PostgREST port"
|
|
from_port = 3002
|
|
to_port = 3002
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.lb_sg.id]
|
|
}
|
|
|
|
ingress {
|
|
description = "Redis port (internal)"
|
|
from_port = 6379
|
|
to_port = 6379
|
|
protocol = "tcp"
|
|
self = true
|
|
}
|
|
|
|
ingress {
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
}
|
|
|
|
resource "aws_security_group" "lb_sg" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
|
|
ingress {
|
|
from_port = 80
|
|
to_port = 80
|
|
protocol = "tcp"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
ingress {
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
}
|
|
|
|
|
|
resource "aws_db_instance" "tooljet_database" {
|
|
allocated_storage = 100
|
|
instance_class = "db.t3.micro"
|
|
engine = "postgres"
|
|
engine_version = "16"
|
|
db_name = "postgres"
|
|
username = "postgres"
|
|
password = "postgres"
|
|
vpc_security_group_ids = [aws_security_group.rds_sg.id]
|
|
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name
|
|
skip_final_snapshot = true
|
|
}
|
|
|
|
resource "aws_security_group" "rds_sg" {
|
|
vpc_id = aws_vpc.tooljet_vpc.id
|
|
|
|
ingress {
|
|
description = "PostgreSQL"
|
|
from_port = 5432
|
|
to_port = 5432
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.task_sg.id]
|
|
}
|
|
}
|
|
|
|
resource "aws_db_subnet_group" "rds_subnet_group" {
|
|
name = "tooljet-rds-subnet-group"
|
|
subnet_ids = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
|
|
}
|