DEV Community

Cover image for How to Deploy a Tetris Game on AWS ECS with Terraform

How to Deploy a Tetris Game on AWS ECS with Terraform

💡 Introduction

Welcome to the world of cloud computing and automation!

In this blog, we’ll dive into one of AWS’s core container orchestration services: Amazon Elastic Container Service (ECS).

We’ll start by understanding what ECS is and how it works. Then, to bring theory into practice, we’ll deploy a Tetris game that has been containerized using Docker onto an ECS cluster — all provisioned and automated with Terraform.

By the end of this walkthrough, you’ll gain practical experience in:

✅ Writing Terraform configurations to provision AWS infrastructure

✅ Deploying containerized applications on ECS

✅ Understanding the overall workflow of infrastructure as code on AWS

So, without further ado — let’s get started!


🛠️ Pre-requisites

Before we dive into building and deploying, let’s make sure your environment is set up correctly.

To follow along, you’ll need:

✅ An AWS account with an IAM user configured

✅ The IAM user must have sufficient permissions to create and manage ECS, IAM roles, and other resources

AWS CLI installed and configured on your system with your Access Key and Secret Access Key

If you’re new to configuring the AWS CLI or IAM users, don’t worry — I’ve explained this step-by-step in another project guide on my blog:

👉 blog.praveshsudha.com

Having these prerequisites ready will help you focus directly on writing Terraform code and deploying the application smoothly.


🧩 What is ECS?

AWS Elastic Container Service (ECS) is a fully managed container orchestration service that simplifies the deployment, management, and scaling of containerized applications.

With ECS, you can easily start, stop, and manage Docker containers running on a cluster of EC2 instances or on a serverless architecture using AWS Fargate — all without worrying about managing the underlying infrastructure.

⚙️ How things work with AWS ECS

Let’s break down the basic workflow of deploying a containerized application on ECS:

  • Create an ECS Cluster

    • This acts as the logical grouping of your infrastructure.
    • You can choose the infrastructure type (EC2 instances or serverless Fargate) and configure logging, security, and tags.
  • Define a Task Definition Family

    • Think of this as the blueprint for your container.
    • Here you specify:

      • The processor architecture (e.g., AMD64 or ARM64)
      • The Docker image (public image from Docker Hub, an Amazon ECR repository, etc.)
      • Container details such as port mappings, container name, and other runtime configurations.
    • You can also configure multi-AZ deployments for high availability.

  • Create a Service

    • Inside your ECS cluster, you create a service that uses your task definition.
    • The service ensures the desired number of containers are running and handles deployment strategies and scaling.

With this setup, it’s completely possible to deploy our Dockerized Tetris game using the AWS Console (also known as clickops).

But wait — this isn’t how things are done in production.

In production, we use Infrastructure as Code (IaC) to provision and manage resources consistently and repeatably.

In our case, we’ll use Terraform to automate the entire process and deploy the Tetris game with just a single command.

Sounds exciting? Let’s continue!


🧪 Local Testing

Before we deploy the application to the cloud, it’s a good practice to test it locally to make sure everything runs as expected.

Assuming you have Docker installed on your system, you can start the Tetris game container with the following command:

docker run -d -p 80:80 uzyexe/tetris:latest 
Enter fullscreen mode Exit fullscreen mode

Once the container is running, open your browser and navigate to:

http://localhost:80

You should see the Tetris application live on your machine!

Press space to play — and enjoy your very own Dockerized Tetris game.

Testing locally helps ensure that your container image is working correctly before moving on to deployment on AWS ECS.


☁️ Deploying to AWS Cloud

Now that we’ve tested our Dockerized Tetris game locally, let’s move on to the exciting part — deploying it to AWS ECSusing Terraform.

The complete Terraform code for this project is available on my GitHub repository:

👉 https://github.com/Pravesh-Sudha/tetris-ecs-deploy

📦 Step 1: Clone the repository

Start by cloning the repository and moving into the Terraform configuration directory:

git clone https://github.com/Pravesh-Sudha/tetris-ecs-deploy cd tetris-ecs-deploy/terra-config 
Enter fullscreen mode Exit fullscreen mode

🗄 Step 2: Configure Terraform backend

We’re following Terraform best practices by storing the Terraform state file remotely in an S3 bucket.

Inside the backend.tf file, you’ll see this configuration:

terraform { backend "s3" { bucket = "pravesh-tetris-backend" key = "ecs-state-file/terraform.tfstate" region = "us-east-1" } } 
Enter fullscreen mode Exit fullscreen mode

This tells Terraform to store the state file in the pravesh-tetris-backend S3 bucket, keeping it secure and shareable across your team.

If the bucket doesn’t exist yet, create it using the AWS CLI:

aws s3 mb s3://pravesh-tetris-backend 
Enter fullscreen mode Exit fullscreen mode

Tip: You can change the bucket name in backend.tf if you’d prefer to use a different name.

⚙️ Step 3: Initialize Terraform

Initialize your Terraform project to install the required providers and configure the backend:

terraform init 
Enter fullscreen mode Exit fullscreen mode

🔍 Step 4: Preview infrastructure changes

Before applying changes, it’s always a good idea to see what Terraform is about to do:

terraform plan 
Enter fullscreen mode Exit fullscreen mode

🚀 Step 5: Apply and create resources

Finally, deploy everything to AWS:

terraform apply --auto-approve 
Enter fullscreen mode Exit fullscreen mode

Within a few minutes, your ECS cluster, task definition, and service will be created, and the Tetris game will go live.

📝 Understanding the Terraform code

While the resources are being provisioned, let’s briefly walk through what each file does:

values.tf

This file fetches the default VPC and its subnets, then creates a security group that allows inbound HTTP (port 80) traffic from anywhere and allows all outbound traffic.

data "aws_vpc" "default" { default = true } data "aws_subnets" "default" { filter { name = "vpc-id" values = [data.aws_vpc.default.id] } } resource "aws_security_group" "tetris_ecs_sg" { name = "allow-http" description = "Allow HTTP inbound traffic and all outbound traffic" vpc_id = data.aws_vpc.default.id tags = { Name = "tetris_ecs_sg" } } resource "aws_vpc_security_group_ingress_rule" "tetris_ecs_sg_ipv4" { security_group_id = aws_security_group.tetris_ecs_sg.id cidr_ipv4 = "0.0.0.0/0" from_port = 80 ip_protocol = "tcp" to_port = 80 } resource "aws_vpc_security_group_egress_rule" "allow_all_traffic" { security_group_id = aws_security_group.tetris_ecs_sg.id cidr_ipv4 = "0.0.0.0/0" ip_protocol = "-1" } 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Fetch the default VPC and its subnets

  • Create a security group to allow HTTP traffic so our Tetris game is reachable

  • Allow all outbound traffic for the containers to access the internet if needed

🗄 backend.tf

This file configures Terraform to store its state file in an S3 bucket:

terraform { backend "s3" { bucket = "pravesh-tetris-backend" key = "ecs-state-file/terraform.tfstate" region = "us-east-1" } } 
Enter fullscreen mode Exit fullscreen mode

This ensures your state file is safely stored remotely, enabling collaboration and avoiding local state conflicts.

🛠 main.tf

This is where the core infrastructure is defined:

# ECS Cluster resource "aws_ecs_cluster" "tetris_cluster" { name = "tetris-cluster" tags = { Name = "tetris-cluster" } } # IAM Role for ECS task execution resource "aws_iam_role" "ecs_task_execution_role" { name = "tetrisEcsTaskExecutionRole" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } }] }) } # Attach ECS task execution policy resource "aws_iam_role_policy_attachment" "ecs_task_execution_policy" { role = aws_iam_role.ecs_task_execution_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" } # ECS Task Definition resource "aws_ecs_task_definition" "tetris_task" { family = "tetris-task" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = "256" memory = "512" execution_role_arn = aws_iam_role.ecs_task_execution_role.arn container_definitions = jsonencode([ { name = "tetris" image = "uzyexe/tetris:latest" essential = true portMappings = [{ containerPort = 80 hostPort = 80 protocol = "tcp" }] } ]) tags = { Name = "tetris-task" } } # ECS Service resource "aws_ecs_service" "tetris_service" { name = "tetris-service" cluster = aws_ecs_cluster.tetris_cluster.id task_definition = aws_ecs_task_definition.tetris_task.arn desired_count = 1 launch_type = "FARGATE" network_configuration { subnets = data.aws_subnets.default.ids security_groups = [aws_security_group.tetris_ecs_sg.id] assign_public_ip = true } tags = { Name = "tetris-service" } } 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Create an ECS cluster to manage the containers

  • Define an IAM role and attach a policy so ECS can pull container images and write logs

  • Create an ECS task definition that points to the public Tetris Docker image and maps port 80

  • Launch an ECS service on AWS Fargate to keep the container running, connected to our security group and VPC subnets

✅ Done!

After the apply completes, your Tetris game should be running on ECS!


🎮 Access the Tetris Game

Once your ECS service is running, it’s time to see the Tetris game live in action!

But how do we get the public IP of the running ECS task?

While it’s technically possible to fetch this IP directly through Terraform and display it as an output, it can get a bit tricky due to the dynamic nature of Fargate tasks and network interfaces.

To keep things simple, I’ve added a bash script that uses the AWS CLI to retrieve the public IP programmatically.

🧰 Step 1: Make the script executable

Navigate to the parent directory of the project (tetris-ecs-deploy) and run:

chmod u+x get_ip.sh 
Enter fullscreen mode Exit fullscreen mode

🚀 Step 2: Run the script

Now execute the script to get the public IP of your ECS task:

./get_ip.sh 
Enter fullscreen mode Exit fullscreen mode

The script will output a link like:

http://<PUBLIC-IP> 
Enter fullscreen mode Exit fullscreen mode

Click on the link (or open it in your browser) — and you’ll see your Tetris game running live on AWS ECS!

Press space to start playing and enjoy your cloud-hosted Tetris.

🧹 Step 3: Clean up resources

When you’re done exploring the project, it’s important to destroy the infrastructure to avoid unwanted AWS costs.

From the terra-config directory, run:

terraform destroy --auto-approve 
Enter fullscreen mode Exit fullscreen mode

Tip: Don’t forget to manually delete the S3 bucket you created for the Terraform state file.

That’s it! You’ve now learned how to deploy a Dockerized Tetris game on AWS ECS using Terraform, and access it from anywhere.


✅ Conclusion

And that’s a wrap! 🎉

In this blog, we explored how to:

  • Understand AWS ECS and how it works under the hood

  • Test a Dockerized Tetris game locally

  • Use Terraform to provision AWS infrastructure automatically

  • Deploy the game on ECS with just a few commands

  • Access it from anywhere — and clean up afterwards to manage costs

Through this hands-on project, you’ve seen the power of combining Infrastructure as Code with container orchestration in the cloud — skills that are highly valuable in modern DevOps and cloud-native development.

🙌 Stay connected

If you enjoyed this blog or want to see more real-world DevOps, AWS, and Terraform projects:

Feel free to follow, connect, or drop me a message — I love sharing and discussing cloud projects, open source contributions, and DevOps topics.

Thanks for reading, and happy building on the cloud! ☁️🚀

Top comments (0)