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!

Feb 18, 2025 - 11:39
 0
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!