Skip to content

Commit

Permalink
feat: Migrate to running gluon-lang.org in ECS
Browse files Browse the repository at this point in the history
Currently there is just lonely EC2 instance + cron script which tries to
keep the server up and running. This isn't great as I need to ssh in to
look at logs and the service only restarts once per day.

By moving to ECS we get logs in cloudwatch, automatic restarts on
crashes and we can setup alarms for any error cases. (Terraform is
certainly overkill for this, but setting up a new terraform environment
is good for learning, I already have a decent understanding of maintaining
one so).

cc gluon-lang/gluon#881
  • Loading branch information
Marwes committed Apr 5, 2024
1 parent 68e7013 commit a356c5d
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ node_modules
target
std
try_gluon.env

.terraform
**.tfstate*

48 changes: 48 additions & 0 deletions terraform/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
resource "aws_iam_role" "ecs_task_execution_role" {
name = "gluon-lang"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role" "ecs_task_role" {
name = "gluon-lang-task"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy_attachment" "ecs-task-execution-role-policy-attachment" {
role = aws_iam_role.ecs_task_execution_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
resource "aws_iam_role_policy_attachment" "task_s3" {
role = aws_iam_role.ecs_task_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}
33 changes: 33 additions & 0 deletions terraform/network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "aws_ecs_cluster" "gluon-lang" {
name = "gluon-lang"
}

resource "aws_vpc" "aws-vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
}

resource "aws_subnet" "gluon-lang" {
vpc_id = aws_vpc.aws-vpc.id
cidr_block = aws_vpc.aws-vpc.cidr_block
map_public_ip_on_launch = true
}

resource "aws_internet_gateway" "gluon-lang" {
vpc_id = aws_vpc.aws-vpc.id
}

resource "aws_route_table" "gluon-lang" {
vpc_id = aws_vpc.aws-vpc.id
}

resource "aws_route" "default" {
route_table_id = aws_route_table.gluon-lang.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gluon-lang.id
}

resource "aws_route_table_association" "gluon-lang" {
subnet_id = aws_subnet.gluon-lang.id
route_table_id = aws_route_table.gluon-lang.id
}
4 changes: 4 additions & 0 deletions terraform/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
provider "aws" {
version = "3"
region = "eu-central-1"
}
79 changes: 79 additions & 0 deletions terraform/task.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
resource "aws_cloudwatch_log_group" "gluon-lang" {
name = "gluon-lang"
retention_in_days = "7"
}

locals {
container_definitions = <<DEFINITION
[
{
"image": "marwes/try_gluon",
"name": "gluon-lang",
"cpu": 0,
"memory": 128,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region" : "eu-central-1",
"awslogs-group" : "${aws_cloudwatch_log_group.gluon-lang.name}",
"awslogs-stream-prefix" : "gluon-lang"
}
}
}
]
DEFINITION
}


resource "aws_ecs_task_definition" "gluon_lang" {
family = "gluon-lang"
task_role_arn = aws_iam_role.ecs_task_role.arn
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
cpu = "256"
memory = "1024"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
container_definitions = local.container_definitions
}

resource "aws_ecs_service" "gluon-lang" {
name = "gluon-lang"
cluster = aws_ecs_cluster.gluon-lang.id
task_definition = aws_ecs_task_definition.gluon_lang.arn
launch_type = "FARGATE"

desired_count = 1

deployment_maximum_percent = 100
deployment_minimum_healthy_percent = 0

network_configuration {
subnets = aws_subnet.gluon-lang.*.id
assign_public_ip = "true"

security_groups = [aws_security_group.gluon_lang.id]
}
}

resource "aws_security_group" "gluon_lang" {
name_prefix = "gluon-lang-"
vpc_id = aws_vpc.aws-vpc.id

ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

lifecycle {
create_before_destroy = true
}
}

0 comments on commit a356c5d

Please sign in to comment.