Skip to main content

Command Palette

Search for a command to run...

Project :Deploy a multi-tier architecture application on AWS using Terraform.

Updated
5 min read

In this project, I will deploy 3 tier infrastructure using Terraform.

Prerequisite:

  1. You should have Aws Account

  2. You should have installed Terraform in your system. (You can follow the below blog, if you don't have installed.)

    %[https://hashnode.com/post/cljbzmnad000109mv11753vyu]

Our infrastructure will look like this:

our files structure will look like this :

Let's configure your aws using the following code:

aws configure

Enter your Access Key ID and secret key.

Create provider.tf using following code:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "us-east-1"
}

create vars.tf using following code:

# Defining CIDR Block for VPC
variable "vpc_cidr" {
  default = "10.0.0.0/16"
}
# Defining CIDR Block for 1st Subnet
variable "subnet1_cidr" {
  default = "10.0.1.0/24"
}
# Defining CIDR Block for 2nd Subnet
variable "subnet2_cidr" {
  default = "10.0.2.0/24"
}
# Defining CIDR Block for 3rd Subnet
variable "subnet3_cidr" {
  default = "10.0.3.0/24"
}
# Defining CIDR Block for 3rd Subnet
variable "subnet4_cidr" {
  default = "10.0.4.0/24"
}
# Defining CIDR Block for 3rd Subnet
variable "subnet5_cidr" {
  default = "10.0.5.0/24"
}
# Defining CIDR Block for 3rd Subnet
variable "subnet6_cidr" {
  default = "10.0.6.0/24"
}

Create vpc.tf using following code:

resource "aws_vpc" "main" {
  cidr_block       = "${var.vpc_cidr}"
  instance_tenancy = "default"

  tags = {
    Name = "my-vpc"
  }
}

Create subnet.tf using following code:

#web tier subnet 1
resource "aws_subnet" "web-subnet-1" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet1_cidr}"
  map_public_ip_on_launch = true
  availability_zone = "us-east-1a"

  tags = {
    Name = "web-subnet-1"
  }
}

#web tier subnet 2
resource "aws_subnet" "web-subnet-2" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet2_cidr}"
  map_public_ip_on_launch = true
  availability_zone = "us-east-1b"

  tags = {
    Name = "web-subnet-2"
  }
}

#application  tier subnet 1
resource "aws_subnet" "app-subnet-1" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet3_cidr}"
  map_public_ip_on_launch = false
  availability_zone = "us-east-1a"

  tags = {
    Name = "app-subnet-1"
  }
}

#application tier subnet 2
resource "aws_subnet" "app-subnet-2" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet4_cidr}"
  map_public_ip_on_launch = false
  availability_zone = "us-east-1b"

  tags = {
    Name = "app-subnet-2"
  }
}

#DB tier subnet 1
resource "aws_subnet" "db-subnet-1" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet5_cidr}"
  availability_zone = "us-east-1a"

  tags = {
    Name = "DB-subnet-1"
  }
}

#DB tier subnet 1
resource "aws_subnet" "db-subnet-2" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "${var.subnet6_cidr}"
  availability_zone = "us-east-1b"

  tags = {
    Name = "DB-subnet-2"
  }
}

Create igw.tf using following code:

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "my internet gateway"
  }
}

Create rt_public.tf using following code:

resource "aws_route_table" "route_public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }

  tags = {
    Name = "Route to Internet"
  }
}

#Route table association
resource "aws_route_table_association" "rt1" {
  subnet_id      = aws_subnet.web-subnet-1.id
  route_table_id = aws_route_table.route_public.id
}

resource "aws_route_table_association" "rt2" {
  subnet_id      = aws_subnet.web-subnet-2.id
  route_table_id = aws_route_table.route_public.id
}

create web_security_group.tf using this code:

resource "aws_security_group" "My_SG" {
  name        = "my_security_group"
  description = "Allow TLS inbound traffic"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description      = "TLS from VPC"
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
  ingress {
    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"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "Web SG"
  }

}

create data.sh using following code:

#!/bin/bash
apt update -y
apt install -y apache2
systemctl start apache2
systemctl enable apache2
echo "Hello World from $(hostname -f)" > /var/www/html/index.html

Create Ec2.tf using following code :

resource "aws_instance" "web_server1" {
  ami                         = "ami-053b0d53c279acc90"
  instance_type               = "t2.micro"
  #count                       = 1
  key_name                    = "ajay-admin"
  subnet_id                   = aws_subnet.web-subnet-1.id
  associate_public_ip_address = true
  vpc_security_group_ids = [aws_security_group.My_SG.id]
  user_data                   = "${file("data.sh")}"
tags = {
    Name = "My web Instance 1"
  }
}

#my second web tier Ec2 instance
resource "aws_instance" "web_server2" {
  ami                         = "ami-053b0d53c279acc90"
  instance_type               = "t2.micro"
  #count                       = 1
  key_name                    = "ajay-admin"
  subnet_id                   = aws_subnet.web-subnet-2.id
  associate_public_ip_address = true
  vpc_security_group_ids = [aws_security_group.My_SG.id]
  user_data                   = "${file("data.sh")}"
tags = {
    Name = "My web Instance 2"
  }
}

Create database_SG.tf using following code:

resource "aws_security_group" "db_SG" {
  name        = "Database SG"
  description = "Allow inbound traffic from application layer"
  vpc_id      = aws_vpc.main.id

  ingress {
    description     = "Allow traffic from application layer"
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.My_SG.id]
  }

  egress {
    from_port   = 32768
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "Database SG"
  }

}

create alb.tf using following code:

resource "aws_lb" "my-lb" {
  name               = "My-web-load-balancer"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.My_SG.id]
  subnets            = [aws_subnet.web-subnet-1.id, aws_subnet.web-subnet-2.id]
}
  resource "aws_lb_target_group" "target-elb" {
  name     = "Target-group-lb"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id
  }

  resource "aws_lb_target_group_attachment" "target-goup-attachment" {
  target_group_arn = aws_lb_target_group.target-elb.arn
  target_id        = aws_instance.web_server1.id
  port             = 80

  depends_on = [
    aws_instance.web_server1,
  ]
  }

  resource "aws_lb_target_group_attachment" "target-goup-attachment1" {
  target_group_arn = aws_lb_target_group.target-elb.arn
  target_id        = aws_instance.web_server2.id
  port             = 80

  depends_on = [
    aws_instance.web_server2,
  ]
  }

  resource "aws_lb_listener" "external-elb" {
  load_balancer_arn = aws_lb.my-lb.arn
  port              = "80"
  protocol          = "HTTP"
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.target-elb.arn
  }
 }

Create rds.tf using following code:

resource "aws_db_subnet_group" "rds-subnet-group" {
  name       = "main"
  subnet_ids = [aws_subnet.db-subnet-1.id, aws_subnet.db-subnet-2.id]
tags = {
    Name = "My DB subnet group"
  }
}

resource "aws_db_instance" "rds_instance" {
  allocated_storage    = 10
  db_name              = "mydb"
  engine               = "mysql"
  engine_version       = "8.0.32"
  instance_class       = "db.t2.micro"
  username             = "admin"
  password             = "password"
  skip_final_snapshot  = true
  multi_az             = true
  db_subnet_group_name = aws_db_subnet_group.rds-subnet-group.id
  vpc_security_group_ids = [aws_security_group.db_SG.id]
}

Create output.tf using following code:

output "lb_dns_name" {
  description = "The DNS name of the load balancer"
  value       = "${aws_lb.my-lb.dns_name}"
}

That was all. You can check your Web server using the output url.

If you have any queries/suggestions please write in comment.

More from this blog

Ajay Patel

116 posts

Project :Deploy a multi-tier architecture application on AWS using Terraform.