Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minecraft Server on AWS (Infrastructure as Code)

Provisions and runs a Minecraft Java Edition server on AWS ECS Fargate using Terraform and a Docker image. The world is stored on EFS so it survives restarts. The whole thing is deployed from the command line (or GitHub Actions) without using the AWS Management Console.

Background

The server runs as a container on Fargate instead of a managed EC2 instance. Terraform builds the networking, an ECR repository, an EFS file system, the ECS cluster, and the service. A Docker image holds the server; the world data is mounted from EFS at /data. The ECS service keeps one task running and replaces it automatically if it stops, which covers the auto-restart requirement. On shutdown ECS sends SIGTERM to the container, where the JVM runs as PID 1 and saves the world before exiting.

Pipeline

Dockerfile  --build/push-->  ECR image
Terraform   --provisions-->  EFS + ECS Fargate service (+ security groups, logs)
ECS task    --public IP-->   port 25565
AWS CLI     --resolves IP-->  nmap -sV -Pn -p T:25565 <ip>
flowchart TD
    A[Dockerfile] -->|build + push| B[(ECR image)]
    C[Terraform] -->|provisions| D[ECS Fargate service]
    B --> D
    C --> E[(EFS world volume)]
    D -->|mounts /data| E
    D -->|public IP :25565| F[nmap]
Loading

Requirements

Run from Linux or WSL2 on Windows. Install:

  • Terraform >= 1.6
  • AWS CLI v2
  • Docker
  • nmap

Configure AWS credentials with aws configure (region us-west-2). Verify with aws sts get-caller-identity.

By default the stack creates its own IAM roles. In an AWS Academy Learner Lab, which does not allow creating roles, create terraform/terraform.tfvars with:

create_iam_roles   = false
existing_role_name = "LabRole"

Usage

./scripts/deploy.sh     # build image, push to ECR, provision everything
./scripts/connect.sh    # resolve the server IP and run the nmap check
./scripts/destroy.sh    # tear everything down

deploy.sh initializes Terraform, creates the ECR repository, builds and pushes the image, then applies the rest of the stack. connect.sh waits for the task to start, finds its public IP through the AWS CLI, and probes port 25565. Fargate assigns a new IP each time the task starts, so re-run connect.sh after a redeploy.

Connecting

After connect.sh prints Server: <ip>:25565, join from the Minecraft client (Multiplayer > Add Server > paste the IP), or confirm reachability with:

nmap -sV -Pn -p T:25565 <ip>

GitHub Actions

  • .github/workflows/validate.yml runs terraform fmt, validate, and a Docker build on every push.
  • .github/workflows/deploy.yml runs the full deploy on push to main. It needs the repository secrets AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

Layout

docker/      Dockerfile + entrypoint
terraform/   main, network, storage, iam, ecs, variables, outputs
scripts/     deploy, connect, destroy
.github/     CI workflows

Sources

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages