Skip to content

Commit ca5e3e2

Browse files
v0 workflows terraform modules
1 parent 0171107 commit ca5e3e2

File tree

15 files changed

+1966
-0
lines changed

15 files changed

+1966
-0
lines changed

modules/workflows_aws_ecs/README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# AWS ECS + EC2 Module
2+
3+
This module deploys an ECS cluster with autoscaling group of EC2 instances.
4+
5+
# Usage
6+
7+
1. Directly use our module in your existing Terraform configuration and provide the required variables
8+
9+
```
10+
module "retool" {
11+
source = "[email protected]:tryretool/retool-terraform.git//modules/aws/ecs-ec2"
12+
13+
aws_region = "<your-aws-region>"
14+
vpc_id = "<your-vpc-id>"
15+
subnet_ids = [
16+
"<your-subnet-1>",
17+
"<your-subnet-2>"
18+
]
19+
ssh_key_name = "<your-key-pair>"
20+
ecs_retool_image = "<desired-retool-version>"
21+
22+
# Additional configuration
23+
...
24+
}
25+
```
26+
27+
2. Run `terraform init` to install all requirements for the module.
28+
29+
3. Replace `ecs_retool_image` with your desired [Retool Version](https://docs.retool.com/docs/updating-retool-on-premise#retool-release-versions). The format should be `tryretool/backend:X.Y.Z`, where `X.Y.Z` is your desired version number. Version 2.111 or greater is needed for Workflows (2.117 or later strongly recommended for performance improvements).
30+
31+
4. Ensure that the default security settings in `security.tf` matches your specifications. If you need to tighten down access, pass in custom ingress and egress rules into `container_egress_rules`, `container_ingress_rules`, `alb_egress_rules`, and `alb_ingress_rules`.
32+
33+
5. Check through `variables.tf` for any other input variables that may be required. Set `launch_type` to `EC2` if not using Fargate.
34+
35+
6. Run `terraform plan` to view all planned changes to your account.
36+
37+
7. Run `terraform apply` to apply the changes and deploy Retool.
38+
39+
8. You should now find a Load Balancer in your AWS EC2 Console associated with the deployment. The instance address should now be running Retool.
40+
41+
## Common Configuration
42+
43+
### Instances
44+
45+
**EC2 Instance Size**
46+
To configure the EC instance size, set the `instance_type` input variable (e.g. `t2.large`).
47+
48+
**RDS Instance Class**
49+
To configure the RDS instance class, set the `instance_class` input variable (e.g. `db.m6g.large`).
50+
51+
## Advanced Configuration
52+
53+
### Security Groups
54+
55+
To customize the ingress and egress rules on the security groups, you can override specific input variable defaults.
56+
57+
- `container_ingress_rules` controls the inbound rules for EC2 instances in autoscaling group or ECS services in Fargate
58+
- `container_egress_rules` controls the outbound rules for EC2 instances in autoscaling group or ECS services in Fargate
59+
- `alb_ingress_rules` controls the inbound rules for the Load Balancer
60+
- `alb_egress_rules` controls the outbound rules for the Load Balancer
61+
62+
```
63+
container_ingress_rules = [
64+
{
65+
description = "Global HTTP inbound"
66+
from_port = "80"
67+
to_port = "80"
68+
protocol = "tcp"
69+
cidr_blocks = ["0.0.0.0/0"]
70+
ipv6_cidr_blocks = ["::/0"]
71+
},
72+
{
73+
description = "Global HTTPS inbound"
74+
from_port = "443"
75+
to_port = "443"
76+
protocol = "tcp"
77+
cidr_blocks = ["0.0.0.0/0"]
78+
ipv6_cidr_blocks = ["::/0"]
79+
},
80+
{
81+
description = "SSH inbound"
82+
from_port = "22"
83+
to_port = "22"
84+
protocol = "tcp"
85+
cidr_blocks = ["0.0.0.0/0"]
86+
ipv6_cidr_blocks = ["::/0"]
87+
}
88+
]
89+
90+
container_egress_rules = [
91+
{
92+
description = "Global outbound"
93+
from_port = "0"
94+
to_port = "0"
95+
protocol = "-1"
96+
cidr_blocks = ["0.0.0.0/0"]
97+
ipv6_cidr_blocks = ["::/0"]
98+
}
99+
]
100+
```
101+
102+
### Environment Variables
103+
104+
To add additional [Retool environment variables](https://docs.retool.com/docs/environment-variables) to your deployment, populate the `additional_env_vars` input variable into the module.
105+
106+
NOTE: The `additional_env_vars` will only work as type `map(string)`. Convert all booleans and numbers into strings, e.g.
107+
108+
```
109+
additional_env_vars = [
110+
{
111+
name = "DISABLE_GIT_SYNCING"
112+
value = "true"
113+
}
114+
]
115+
```

modules/workflows_aws_ecs/ecs.tf

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
resource "aws_ecs_cluster" "this" {
2+
name = "${var.deployment_name}-ecs"
3+
4+
setting {
5+
name = "containerInsights"
6+
value = var.ecs_insights_enabled
7+
}
8+
}
9+
10+
# Fargate capacity provider
11+
resource "aws_ecs_cluster_capacity_providers" "this" {
12+
count = var.launch_type == "FARGATE" ? 1 : 0
13+
cluster_name = aws_ecs_cluster.this.name
14+
15+
capacity_providers = ["FARGATE"]
16+
17+
default_capacity_provider_strategy {
18+
base = 1
19+
weight = 100
20+
capacity_provider = "FARGATE"
21+
}
22+
}
23+
24+
# Required setup for EC2 instances (if not using Fargate)
25+
data "aws_ami" "this" {
26+
most_recent = true # get the latest version
27+
name_regex = "^amzn2-ami-ecs-hvm-\\d\\.\\d\\.\\d{8}-x86_64-ebs$"
28+
29+
filter {
30+
name = "virtualization-type"
31+
values = [
32+
"hvm"
33+
]
34+
}
35+
36+
owners = [
37+
"amazon" # only official images
38+
]
39+
}
40+
41+
resource "aws_launch_configuration" "this" {
42+
count = var.launch_type == "EC2" ? 1 : 0
43+
name_prefix = "${var.deployment_name}-ecs-launch-configuration-"
44+
image_id = data.aws_ami.this.id
45+
instance_type = var.instance_type # e.g. t2.medium
46+
47+
enable_monitoring = true
48+
associate_public_ip_address = true
49+
50+
# This user data represents a collection of “scripts” that will be executed the first time the machine starts.
51+
# This specific example makes sure the EC2 instance is automatically attached to the ECS cluster that we create earlier
52+
# and marks the instance as purchased through the Spot pricing
53+
user_data = <<-EOF
54+
#!/bin/bash
55+
echo ECS_CLUSTER=${var.deployment_name}-ecs >> /etc/ecs/ecs.config
56+
EOF
57+
58+
# We’ll see security groups later
59+
security_groups = [
60+
aws_security_group.containers.id
61+
]
62+
63+
# If you want to SSH into the instance and manage it directly:
64+
# 1. Make sure this key exists in the AWS EC2 dashboard
65+
# 2. Make sure your local SSH agent has it loaded
66+
# 3. Make sure the EC2 instances are launched within a public subnet (are accessible from the internet)
67+
key_name = var.ssh_key_name
68+
69+
# Allow the EC2 instances to access AWS resources on your behalf, using this instance profile and the permissions defined there
70+
iam_instance_profile = aws_iam_instance_profile.ec2[0].arn
71+
72+
lifecycle {
73+
create_before_destroy = true
74+
}
75+
}
76+
77+
resource "aws_autoscaling_group" "this" {
78+
count = var.launch_type == "EC2" ? 1 : 0
79+
name = "${var.deployment_name}-autoscaling-group"
80+
max_size = var.max_instance_count
81+
min_size = var.min_instance_count
82+
desired_capacity = var.min_instance_count
83+
vpc_zone_identifier = var.subnet_ids
84+
launch_configuration = aws_launch_configuration.this[0].name
85+
86+
default_cooldown = 30
87+
health_check_grace_period = 30
88+
89+
termination_policies = [
90+
"OldestInstance"
91+
]
92+
93+
tag {
94+
key = "AmazonECSManaged"
95+
value = ""
96+
propagate_at_launch = true
97+
}
98+
99+
tag {
100+
key = "Cluster"
101+
value = "${var.deployment_name}-ecs"
102+
propagate_at_launch = true
103+
}
104+
105+
tag {
106+
key = "Name"
107+
value = "${var.deployment_name}-ec2-instance"
108+
propagate_at_launch = true
109+
}
110+
111+
lifecycle {
112+
create_before_destroy = true
113+
}
114+
}
115+
116+
# Attach an autoscaling policy to the spot cluster to target 70% MemoryReservation on the ECS cluster.
117+
resource "aws_autoscaling_policy" "this" {
118+
count = var.launch_type == "EC2" ? 1 : 0
119+
name = "${var.deployment_name}-ecs-scale-policy"
120+
policy_type = "TargetTrackingScaling"
121+
adjustment_type = "ChangeInCapacity"
122+
autoscaling_group_name = aws_autoscaling_group.this[0].name
123+
124+
target_tracking_configuration {
125+
customized_metric_specification {
126+
metric_dimension {
127+
name = "ClusterName"
128+
value = "${var.deployment_name}-ecs"
129+
}
130+
metric_name = "MemoryReservation"
131+
namespace = "AWS/ECS"
132+
statistic = "Average"
133+
}
134+
target_value = var.autoscaling_memory_reservation_target
135+
}
136+
}
137+
138+
resource "aws_ecs_capacity_provider" "this" {
139+
count = var.launch_type == "EC2" ? 1 : 0
140+
name = "${var.deployment_name}-ecs-capacity-provider"
141+
142+
auto_scaling_group_provider {
143+
auto_scaling_group_arn = aws_autoscaling_group.this[0].arn
144+
}
145+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
resource "aws_lb" "this" {
2+
name = "${var.deployment_name}-alb"
3+
idle_timeout = var.alb_idle_timeout
4+
5+
security_groups = [aws_security_group.alb.id]
6+
subnets = var.subnet_ids
7+
}
8+
9+
resource "aws_lb_listener" "this" {
10+
load_balancer_arn = aws_lb.this.arn
11+
port = 80
12+
protocol = "HTTP"
13+
14+
default_action {
15+
type = "forward"
16+
target_group_arn = aws_lb_target_group.this.arn
17+
}
18+
}
19+
20+
resource "aws_lb_listener_rule" "this" {
21+
listener_arn = aws_lb_listener.this.arn
22+
priority = 1
23+
24+
action {
25+
type = "forward"
26+
target_group_arn = aws_lb_target_group.this.arn
27+
}
28+
29+
condition {
30+
path_pattern {
31+
values = ["/"]
32+
}
33+
}
34+
}
35+
36+
resource "aws_lb_target_group" "this" {
37+
name = "${var.deployment_name}-target"
38+
vpc_id = var.vpc_id
39+
deregistration_delay = 30
40+
port = 3000
41+
protocol = "HTTP"
42+
target_type = var.launch_type == "FARGATE" ? "ip" : "instance"
43+
44+
health_check {
45+
interval = 61
46+
path = "/api/checkHealth"
47+
protocol = "HTTP"
48+
timeout = 60
49+
healthy_threshold = 4
50+
unhealthy_threshold = 2
51+
}
52+
}

0 commit comments

Comments
 (0)