Deploying a Custom Docker App with Terraform and Docker Compose
Introduction In this blog, we will walk through deploying an AWS EC2 instance using Terraform Modules and setting up a custom Dockerized multi-container application using Docker Compose. This is a great project for those looking to enhance their Terraform, Docker, and AWS skills while automating infrastructure provisioning. Prerequisites Before we begin, ensure you have: ✅ Terraform installed → Download Here ✅ AWS CLI installed and configured → Run aws configure ✅ An AWS Key Pair (to SSH into the instance) ✅ A Dockerized custom application (a simple web app) Project Overview We will create: ✔️ An EC2 instance with a security group allowing SSH and HTTP traffic ✔️ Terraform Modules for better reusability ✔️ Docker installation via Terraform's user_data ✔️ A custom multi-container application using Docker Compose Step 1: Define the Terraform Provider Create a file named provider.tf and specify AWS as the provider: provider "aws" { region = "us-east-1" # Change this as needed } Step 2: Create a Terraform Module for EC2 Instance Create a new folder modules/ec2 and inside it, create main.tf, variables.tf, and outputs.tf files. modules/ec2/main.tf resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI (update if needed) instance_type = var.instance_type key_name = var.key_name security_groups = [var.security_group] user_data = file("${path.module}/install_docker.sh") tags = { Name = var.instance_name } } modules/ec2/variables.tf variable "instance_type" {} variable "key_name" {} variable "security_group" {} variable "instance_name" {} modules/ec2/outputs.tf output "public_ip" { value = aws_instance.web.public_ip } Step 3: Define Security Group Module Create a new folder modules/security_group and define security rules. modules/security_group/main.tf resource "aws_security_group" "ec2_sg" { name = "terraform-sg" description = "Allow SSH and HTTP" ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # Allows SSH access } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # Allows HTTP access } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] # Allows all outbound traffic } } Step 4: Install Docker and Docker Compose Create a shell script install_docker.sh inside modules/ec2: #!/bin/bash sudo yum update -y sudo yum install docker -y sudo systemctl start docker sudo systemctl enable docker sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose Step 5: Deploy a Multi-Container App using Docker Compose Create a docker-compose.yml file on the EC2 instance after provisioning: version: '3.8' services: app: image: my-custom-app:latest ports: - "5000:5000" depends_on: - db db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mydb Run the following commands on the instance: docker-compose up -d Step 6: Deploy with Terraform Initialize Terraform terraform init Preview the Changes terraform plan Apply the Configuration terraform apply -auto-approve Terraform will output the public IP address of the instance. Step 7: Access the Deployed Application Once the deployment is complete, open your browser and visit: http://:5000 Your custom web app should now be running successfully!

Introduction
In this blog, we will walk through deploying an AWS EC2 instance using Terraform Modules and setting up a custom Dockerized multi-container application using Docker Compose. This is a great project for those looking to enhance their Terraform, Docker, and AWS skills while automating infrastructure provisioning.
Prerequisites
Before we begin, ensure you have:
✅ Terraform installed → Download Here
✅ AWS CLI installed and configured → Run aws configure
✅ An AWS Key Pair (to SSH into the instance)
✅ A Dockerized custom application (a simple web app)
Project Overview
We will create:
✔️ An EC2 instance with a security group allowing SSH and HTTP traffic
✔️ Terraform Modules for better reusability
✔️ Docker installation via Terraform's user_data
✔️ A custom multi-container application using Docker Compose
Step 1: Define the Terraform Provider
Create a file named provider.tf
and specify AWS as the provider:
provider "aws" {
region = "us-east-1" # Change this as needed
}
Step 2: Create a Terraform Module for EC2 Instance
Create a new folder modules/ec2
and inside it, create main.tf
, variables.tf
, and outputs.tf
files.
modules/ec2/main.tf
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI (update if needed)
instance_type = var.instance_type
key_name = var.key_name
security_groups = [var.security_group]
user_data = file("${path.module}/install_docker.sh")
tags = {
Name = var.instance_name
}
}
modules/ec2/variables.tf
variable "instance_type" {}
variable "key_name" {}
variable "security_group" {}
variable "instance_name" {}
modules/ec2/outputs.tf
output "public_ip" {
value = aws_instance.web.public_ip
}
Step 3: Define Security Group Module
Create a new folder modules/security_group
and define security rules.
modules/security_group/main.tf
resource "aws_security_group" "ec2_sg" {
name = "terraform-sg"
description = "Allow SSH and HTTP"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allows SSH access
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allows HTTP access
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # Allows all outbound traffic
}
}
Step 4: Install Docker and Docker Compose
Create a shell script install_docker.sh
inside modules/ec2
:
#!/bin/bash
sudo yum update -y
sudo yum install docker -y
sudo systemctl start docker
sudo systemctl enable docker
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Step 5: Deploy a Multi-Container App using Docker Compose
Create a docker-compose.yml
file on the EC2 instance after provisioning:
version: '3.8'
services:
app:
image: my-custom-app:latest
ports:
- "5000:5000"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
Run the following commands on the instance:
docker-compose up -d
Step 6: Deploy with Terraform
Initialize Terraform
terraform init
Preview the Changes
terraform plan
Apply the Configuration
terraform apply -auto-approve
Terraform will output the public IP address of the instance.
Step 7: Access the Deployed Application
Once the deployment is complete, open your browser and visit:
http://:5000
Your custom web app should now be running successfully!