Introduction:
In today's fast-paced world of DevOps and cloud computing, automating the deployment and management of infrastructure is crucial. Terraform, a popular Infrastructure as Code (IaC) tool, allows you to define and provision infrastructure in a declarative manner. In this article, we will explore how to use Terraform to deploy an EC2 instance on AWS, install Docker, build a Docker image using a specified Dockerfile, and push that image to Docker Hub. Finally, we’ll deploy a containerized e-commerce website using the deployed image.
Prerequisites:
Before we begin, make sure you have the following prerequisites:
- An AWS account with appropriate access.
- Terraform installed on your local machine.
- An understanding of Docker and a Docker Hub account.
Step 1: Create a repository on Docker Hub
• Login to your docker hub account and create a new repository for the Project.
• An empty repository is created.
Step 2: Set up project environment.
• Create a project folder on your local machine.
• Open your code editor and open the project folder from the code editor (will be using VScode)
• Create the following files within the project folder.
Deployment Script: (deployment.sh)-This shell script contains the required commands based on the deployment requirements. Copy below codes into the file.
#!/bin/bash
# install and configure docker on the ec2 instance
sudo yum update -y
sudo amazon-linux-extras install docker -y
sudo service docker start
sudo systemctl enable docker
# create a dockerfile
# build the docker image
#sudo docker build -t <image-tag>
sudo docker build -t e-commerce .
# login to your docker hub account
#cat ~/my_password.txt | sudo docker login --username <your-docker-id> --password-stdin
cat ~/docker_password.txt | sudo docker login --username ojosamuel --password-stdin
# use the docker tag command to give the image a new name
#sudo docker tag <image-tag> <repository-name>
sudo docker tag e-commerce ojosamuel/e-commerce_terraform
# push the image to your docker hub repository
#sudo docker push <repository-name>
sudo docker push ojosamuel/e-commerce_terraform
# start the container to test the image
#sudo docker run -dp 80:80 <repository-name>
sudo docker run -dp 80:80 ojosamuel/e-commerce_terraform
Note: The line of command below enables you to connect to your docker hub account.
# login to your docker hub account
#cat ~/my_password.txt | sudo docker login --username <your-docker-id> --password-stdin
But you have to provide the password for authentication. so you will create a txt file on your local machine and type in your docker hub password. Please take note of the location of this file because your will make reference to it.
Dockerfile: This is a simple text file that contains all the command that is required to build a Docker image. Copy below codes into the file. The comment above each command explains the action to be performed by the command.
FROM amazonlinux:latest
# Install dependencies
RUN yum update -y && \
yum install -y httpd && \
yum search wget && \
yum install wget -y && \
yum install unzip -y
# change directory
RUN cd /var/www/html
# download webfiles
RUN wget https://github.com/7hundredtech/E-Commerce/raw/main/E-Commerce.zip
# unzip folder
RUN unzip E-Commerce.zip
# copy files into html directory
RUN cp -r furni-1.0.0/* /var/www/html/
# remove unwanted folder
RUN rm -rf furni-1.0.0 E-Commerce.zip
# exposes port 80 on the container
EXPOSE 80
# set the default application that will start when the container start
ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]
Terraform File: (ec2.tf) - This file provides declarative configurations statements for provisioning EC2 instance on AWS. This will also automate the installation of docker on the Ec2 instance by executing the deployment script, build a docker image and push the image to the specified docker repository and finally deploy a containerized e-commerce website using the built image. Copy below codes into the file. The comment above each command explains the action to be performed by the command.
# configured aws provider with proper credentials
provider "aws" {
region = "us-east-2"
profile = "terraform_user"
}
# create default vpc if one does not exit
resource "aws_default_vpc" "default_vpc" {
tags = {
Name = "default vpc"
}
}
# use data source to get all avalablility zones in region
data "aws_availability_zones" "available_zones" {}
# create default subnet if one does not exit
resource "aws_default_subnet" "default_az1" {
availability_zone = data.aws_availability_zones.available_zones.names[0]
tags = {
Name = "default subnet"
}
}
# create security group for the ec2 instance
resource "aws_security_group" "ec2_security_group" {
name = "ec2 security group"
description = "allow access on ports 80 and 22"
vpc_id = aws_default_vpc.default_vpc.id
ingress {
description = "http access"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "ssh access"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "docker server sg"
}
}
# use data source to get a registered amazon linux 2 ami
data "aws_ami" "amazon_linux_2" {
most_recent = true
owners = ["amazon"]
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
}
# launch the ec2 instance
resource "aws_instance" "ec2_instance" {
ami = data.aws_ami.amazon_linux_2.id
instance_type = "t2.micro"
subnet_id = aws_default_subnet.default_az1.id
vpc_security_group_ids = [aws_security_group.ec2_security_group.id]
key_name = "ec2_key"
tags = {
Name = "docker server"
}
}
# an empty resource block
resource "null_resource" "name" {
# ssh into the ec2 instance
connection {
type = "ssh"
user = "ec2-user"
private_key = file("~/Downloads/ec2_key.pem")
host = aws_instance.ec2_instance.public_ip
}
# copy the password file for your docker hub account
# from your computer to the ec2 instance
provisioner "file" {
source = "~/Downloads/docker_password.txt"
destination = "/home/ec2-user/docker_password.txt"
}
# copy the dockerfile from your computer to the ec2 instance
provisioner "file" {
source = "Dockerfile"
destination = "/home/ec2-user/Dockerfile"
}
# copy the deployment.sh from your computer to the ec2 instance
provisioner "file" {
source = "deployment.sh"
destination = "/home/ec2-user/deployment.sh"
}
# set permissions and run the build_docker_image.sh file
provisioner "remote-exec" {
inline = [
"sudo chmod +x /home/ec2-user/deployment.sh",
"sh /home/ec2-user/deployment.sh",
]
}
# wait for ec2 to be created
depends_on = [aws_instance.ec2_instance]
}
# print the url of the container
output "container_url" {
value = join("", ["http://", aws_instance.ec2_instance.public_dns])
}
Step 3: Run Terraform Commands
Run the following Terraform commands to initialize, plan, and apply the configuration.
Open the Terminal in your project folder to run terraform commands
terraform init
terraform plan
terraform apply
Type yes to give approval to Terraform to deploy an EC2 instance on AWS, install Docker, build a Docker image using a specified Dockerfile, push that image to Docker Hub and deploy a containerized e-commerce website using the image.
Copy and paste the container url on your web browser to access our website. if everything is done properly, your e-commerce website should appear as shown below
Also check from docker hub to confirm that the image was pushed to the specified repository
Conclusion:
By combining Docker for containerization and Terraform for infrastructure automation, you can streamline the deployment of your e-commerce website. This approach provides a lightweight, scalable, and consistent environment for your application.
Clean Up
Run terraform destroy
command to clean up all infrastructure deployed.
Thank you for Reading
Top comments (5)
Great article. I’m facing a verification issue on my AWS account, can you help me out?
lets connect please
Please what’s your LinkedIn handle?
linkedin.com/in/samuel-ojo-oluwagb...
Sent a connection request. Looking forward to your assistance.