diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..395fe76d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.terraform* +terraform.tfstate diff --git a/fargate/Dockerfile b/fargate/Dockerfile new file mode 100644 index 00000000..a5372ef3 --- /dev/null +++ b/fargate/Dockerfile @@ -0,0 +1,8 @@ +FROM dtandersen/factorio:latest + +RUN apk add --update python py-pip +RUN pip install awscli + +COPY fargate-entrypoint.sh fargate-entrypoint.sh + +ENTRYPOINT ["/fargate-entrypoint.sh"] diff --git a/fargate/fargate-entrypoint.sh b/fargate/fargate-entrypoint.sh new file mode 100644 index 00000000..82a451b8 --- /dev/null +++ b/fargate/fargate-entrypoint.sh @@ -0,0 +1,25 @@ +# SIGTERM-handler +term_handler() { + if [ $pid -ne 0 ]; then + aws s3 cp /factorio $STORAGE --recursive + kill -SIGTERM "$pid" + wait "$pid" + fi + exit 143; # 128 + 15 -- SIGTERM +} + +trap 'kill ${!}; term_handler' SIGTERM + +# Load last saved game state +aws s3 cp $STORAGE /factorio --recursive + +# run application +./docker-entrypoint.sh & +pid="$!" + +# save game state every five minutes +while true +do + aws s3 cp /factorio $STORAGE --recursive + sleep $AUTOSAVE_RATE +done diff --git a/fargate/infra/main.tf b/fargate/infra/main.tf new file mode 100644 index 00000000..09e3cf85 --- /dev/null +++ b/fargate/infra/main.tf @@ -0,0 +1,97 @@ +provider "aws" { + region = "us-west-2" +} + +resource "aws_s3_bucket" "factorio" { + bucket_prefix = "factorio-" + versioning { + enabled = true + } +} + +resource "aws_ecs_cluster" "factorio" { + name = "factorio-ecs-cluster" +} + +data "template_file" "factorio" { + template = "${file("${path.module}/tasks/factorio.json")}" + + vars { + image = "rangerscience/factorio:fargate" + storage = "s3://${aws_s3_bucket.factorio.id}" + autosave_rate = 300 # Seconds between saves to S3 + } +} + +resource "aws_ecs_task_definition" "factorio" { + family = "factorio" + container_definitions = "${data.template_file.factorio.rendered}" + + requires_compatibilities = ["FARGATE"] + network_mode = "awsvpc" + + requires_compatibilities = ["FARGATE"] + cpu = "4096" // 4 vCPU + memory = "8192" // 8 GB (min for 4 vCPU) + + task_role_arn = "${aws_iam_role.factorio.arn}" +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_subnet" "factorio" { + cidr_block = "10.0.1.0/26" + vpc_id = "${aws_vpc.main.id}" +} + +resource "aws_ecs_service" "factorio" { + name = "factorio" + launch_type = "FARGATE" + cluster = "${aws_ecs_cluster.factorio.id}" + task_definition = "${aws_ecs_task_definition.factorio.arn}" + desired_count = 1 + + network_configuration { + subnets = ["${aws_subnet.factorio.id}"] + assign_public_ip = true + } +} + +resource "aws_iam_role" "factorio" { + name = "factorio" + + assume_role_policy = <