0% found this document useful (0 votes)
10 views21 pages

Deploy 2-Tier App on AWS with Terraform

This document outlines a DevOps project focused on deploying a 2-tier application on AWS using Terraform and Docker. The project includes creating an automated infrastructure, deploying applications, and testing the solution, with specific scripts and configurations provided for each stage. The application features a frontend for user interaction and a backend database for data storage, ensuring secure communication between the two tiers.

Uploaded by

joy239038
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views21 pages

Deploy 2-Tier App on AWS with Terraform

This document outlines a DevOps project focused on deploying a 2-tier application on AWS using Terraform and Docker. The project includes creating an automated infrastructure, deploying applications, and testing the solution, with specific scripts and configurations provided for each stage. The application features a frontend for user interaction and a backend database for data storage, ensuring secure communication between the two tiers.

Uploaded by

joy239038
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

DEVOPS-PROJECT

DevOps Project Report


On
Deploying a 2-tier Application on AWS Cloud Using
Terraform

Submitted by

Name: Dibyajyoti Nayak


Regd. No. 2241014076
Branch: CSE
Section: 2241051
Project Overview
Title: Deploying a 2-Tier Application on AWS Cloud Using Terraform and Docker

Objective:​
The goal of this project is to design and deploy a 2-tier application architecture on
AWS using Terraform, Docker, and Bash scripting. The application comprises a
frontend for user interaction and a backend database for data storage, ensuring
secure and efficient communication between the two tiers.

Problem Statement
The task involves creating an automated infrastructure and deployment pipeline for
a 2-tier application using Terraform, AWS resources, Docker containers, and Bash
scripting. The project is divided into three main stages:

1.​ Create_Infra
2.​ Deploy_Apps
3.​ Test_Solution

Stage 1: Create_Infra

[Link]

provider "aws" {
region = var.aws_region
}
resource "aws_vpc" "devops_vpc" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true

tags = {
Name = "DevOps-VPC"
}
}

resource "aws_subnet" "public" {


vpc_id = aws_vpc.devops_vpc.id
cidr_block = var.public_subnet_cidr
map_public_ip_on_launch = true
availability_zone = var.availability_zone

tags = {
Name = "Public-Subnet"
}
}

resource "aws_subnet" "private" {


vpc_id = aws_vpc.devops_vpc.id
cidr_block = var.private_subnet_cidr
availability_zone = var.availability_zone

tags = {
Name = "Private-Subnet"
}
}

resource "aws_internet_gateway" "gw" {


vpc_id = aws_vpc.devops_vpc.id

tags = {
Name = "DevOps-IGW"
}
}
data "aws_eip" "nat_eip" {
id = var.nat_eip_allocation_id
}

resource "aws_nat_gateway" "nat_gw" {


allocation_id = data.aws_eip.nat_eip.id
subnet_id = aws_subnet.[Link]

tags = {
Name = "DevOps-NAT-GW"
}

depends_on = [aws_internet_gateway.gw]
}

resource "aws_route_table" "public_rt" {


vpc_id = aws_vpc.devops_vpc.id

route {
cidr_block = "[Link]/0"
gateway_id = aws_internet_gateway.[Link]
}

tags = {
Name = "Public-Route-Table"
}
}

resource "aws_route_table_association" "public_rta" {


subnet_id = aws_subnet.[Link]
route_table_id = aws_route_table.public_rt.id
}

resource "aws_route_table" "private_rt" {


vpc_id = aws_vpc.devops_vpc.id
route {
cidr_block = "[Link]/0"
nat_gateway_id = aws_nat_gateway.nat_gw.id
}

tags = {
Name = "Private-Route-Table"
}
}

resource "aws_route_table_association" "private_rta" {


subnet_id = aws_subnet.[Link]
route_table_id = aws_route_table.private_rt.id
}

resource "aws_security_group" "frontend_sg" {


name = "frontend-sg"
description = "Allow HTTP and SSH"
vpc_id = aws_vpc.devops_vpc.id

ingress {
description = "Allow HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["[Link]/0"]
}

ingress {
description = "Allow SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["[Link]/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["[Link]/0"]
}

tags = {
Name = "Frontend-SG"
}
}

resource "aws_security_group" "backend_sg" {


name = "backend-sg"
description = "Allow PostgreSQL & SSH from frontend subnet"
vpc_id = aws_vpc.devops_vpc.id

ingress {
description = "PostgreSQL"
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = [var.public_subnet_cidr]
}

ingress {
description = "SSH from frontend"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.public_subnet_cidr]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["[Link]/0"]
}

tags = {
Name = "Backend-SG"
}
}

resource "aws_instance" "frontend" {


ami = var.ami_id
instance_type = var.instance_type
subnet_id = aws_subnet.[Link]
key_name = var.key_pair_name
vpc_security_group_ids = [aws_security_group.frontend_sg.id]

provisioner "file" {
source = "[Link]"
destination = "/home/ubuntu/[Link]"
}

provisioner "remote-exec" {
inline = [
"chmod +x /home/ubuntu/[Link]",
"bash /home/ubuntu/[Link]"
]
}

connection {
type = "ssh"
user = "ubuntu"
private_key = file("${var.key_pair_name}.pem")
host = self.public_ip
}

tags = {
Name = "Frontend-EC2"
}
}
resource "aws_instance" "backend" {
ami = var.ami_id
instance_type = var.instance_type
subnet_id = aws_subnet.[Link]
key_name = var.key_pair_name
vpc_security_group_ids = [aws_security_group.backend_sg.id]

provisioner "file" {
source = "[Link]"
destination = "/home/ubuntu/[Link]"
}

provisioner "remote-exec" {
inline = [
"chmod +x /home/ubuntu/[Link]",
"bash /home/ubuntu/[Link]"
]
}

connection {
type = "ssh"
user = "ubuntu"
private_key = file("${var.key_pair_name}.pem")
host = self.private_ip
bastion_host = aws_instance.frontend.public_ip
bastion_user = "ubuntu"
bastion_private_key = file("${var.key_pair_name}.pem")
}

tags = {
Name = "Backend-EC2"
}
}

[Link]
variable "aws_region" {
description = "AWS region"
default = "eu-north-1"
}

variable "vpc_cidr" {
description = "CIDR block for the VPC"
default = "[Link]/16"
}

variable "public_subnet_cidr" {
description = "CIDR block for the public subnet"
default = "[Link]/24"
}

variable "private_subnet_cidr" {
description = "CIDR block for the private subnet"
default = "[Link]/24"
}

variable "availability_zone" {
description = "Availability zone for the subnets"
default = "eu-north-1a"
}

variable "nat_eip_allocation_id" {
description = "Elastic IP allocation ID for NAT Gateway"
default = "eipalloc-0a0777cb608ca6716"
}

variable "ami_id" {
description = "AMI ID for EC2 instances"
default = "ami-042b4708b1d05f512"
}

variable "instance_type" {
description = "EC2 instance type"
default = "[Link]"
}

variable "key_pair_name" {
description = "Name of the AWS key pair"
default = "PROJECT-KEY"
}

[Link]

output "frontend_public_ip" {
description = "Public IP of the frontend EC2 instance"
value = aws_instance.frontend.public_ip
}

output "backend_private_ip" {
description = "Private IP of the backend EC2 instance"
value = aws_instance.backend.private_ip
}
Stage 2: Deploy_Apps

[Link]

#!/bin/bash

sudo apt-get update -y


sudo apt-get install -y [Link]

sudo systemctl start docker


sudo systemctl enable docker

sudo docker pull kanhax04/frontend:latest


sudo docker run -d -p 5000:5000 --name frontend-app kanhax04/frontend:latest

[Link]

#!/bin/bash

sudo apt-get update -y


sudo apt-get install -y [Link]

sudo systemctl start docker


sudo systemctl enable docker
sudo docker pull kanhax04/backend:latest
sudo docker run -d -p 5432:5432 --name backend kanhax04/backend

cd APP/FRONTEND

docker build -t kanhax04/frontend:latest .


docker push kanhax04/frontend:latest

cd APP/BACKEND

docker build -t kanhax04/backend:latest .


docker push kanhax04/backend:latest
Stage 3: Test_Solution
1. Terraform Output

- Public IP: [Link]


2. Frontend URL

- [Link]

3. Curl Test

- Confirmed app loads via curl [Link]


Manual Testing
1. Entered Name “Dibyajyoti Nayak” & Email “sitanayak1980@[Link]” in Frontend
Form

2. Verified DB on BACKEND using SQLite

- Output: SELECT * FROM users;


2TIER-APPLICATION
2TIER-APPLICATION

APP/
├── FRONTEND/
├── [Link]
└── Dockerfile
├── backend/
├── [Link]
├── [Link]
└── Dockerfile

APP/FRONTEND/[Link]

<!DOCTYPE html>
<html>
<head>
<title>Simple Form</title>
</head>
<body>
<h1>Enter Your Details</h1>
<form id="userForm">
<label for="name">Name:</label><br />
<input type="text" id="name" name="name" required /><br />
<label for="email">Email:</label><br />
<input type="email" id="email" name="email" required /><br /><br />
<button type="submit">Submit</button>
</form>

<p id="message"></p>

<script>
[Link]("userForm").addEventListener("submit", async function(e) {
[Link]();
const name = [Link]("name").value;
const email = [Link]("email").value;

try {
const response = await fetch("[Link] {

method: "POST",
headers: {
"Content-Type": "application/json",
},
body: [Link]({ name, email }),
});
const result = await [Link]();
[Link]("message").textContent = [Link];
} catch (err) {
[Link]("message").textContent = "Error contacting backend!";
}
});
</script>

</body>
</html>

APP/FRONTEND/Dockerfile

FROM nginx:alpine
COPY [Link] /usr/share/nginx/html/[Link]
EXPOSE 80

APP/BACKEND/[Link]

from flask import Flask, request, jsonify


from flask_cors import CORS
import sqlite3

app = Flask(__name__)
CORS(app)

def init_db():
conn = [Link]('[Link]')
cursor = [Link]()
[Link]('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL
)
''')
[Link]()
[Link]()

init_db()

@[Link]("/submit", methods=["POST"])
def submit():
data = request.get_json()
name = [Link]("name")
email = [Link]("email")

if not name or not email:


return jsonify({"message": "Missing name or email"}), 400

conn = [Link]('[Link]')
cursor = [Link]()
[Link]("INSERT INTO users (name, email) VALUES (?, ?)", (name, email))
[Link]()
[Link]()

return jsonify({"message": "User saved successfully!"}), 200

if __name__ == "__main__":
[Link](host="[Link]", port=5000)

APP/BACKEND/[Link]

Flask

APP/BACKEND/Dockerfile

FROM python:3.9-slim
WORKDIR /app
COPY . .
RUN pip install -r [Link]
EXPOSE 5000
CMD ["python", "[Link]"]

You might also like