Launch a Web App Containing Web Server and Database Server on AWS EC2 and Complete Infrastructure Created Using Terraform

Shashi Kant
6 min readJan 10, 2021

--

Task Overview

1) Write a Infrastructure as code using terraform, which automatically create a VPC.

2) In that VPC we have to create 2 subnets:

a) public subnet [ Accessible for Public World! ]

b) private subnet [ Restricted for Public World! ]

3) Create a public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC.

4) Create a routing table for Internet gateway so that instance can connect to outside world, update and associate it with public subnet.

5) Launch an ec2 instance which has Wordpress setup already having the security group allowing port 80 so that our client can connect to our wordpress site.

Also attach the key to instance for further login into it.

6) Launch an ec2 instance which has MYSQL setup already with security group allowing port 3306 in private subnet so that our wordpress vm can connect with the same. Also attach the key with the same.

Note: Wordpress instance has to be part of public subnet so that our client can connect our site.

mysql instance has to be part of private subnet so that outside world can’t connect to it.

Don’t forgot to add auto IP assign and auto DNSname assignment option to be enabled.

Amazon Virtual Private Cloud (Amazon VPC) enables you to launch AWS resources into a virtual network that you’ve defined. It provides the virtual or private space or data center inside the AWS Data Center.

Subnet is “part of the network”, or part of entire availability zone. A subnet is a range of IP addresses in your VPC.

Setup to be done before moving ahead

1. Need a AWS account

2. Configure AWS CLI in your System

Let’s Get Started

Add Provider in your “.tf” file.

provider "aws" {

region = "ap-south-1"
profile = "shashikant"
}

Create VPC

For creating VPC, we write

resource "aws_vpc" "shashikant_vpc" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = true

tags = {
Name = "shashikant_vpc"
}
}
VPC Created

Create Public Subnet

Now we have to create public subnet on which we have to launch our web server for public world.

resource "aws_subnet" "shashikant_public_subnet" {
vpc_id = aws_vpc.shashikant_vpc.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-south-1a"

tags = {
Name = "shashikant_public_subnet"
}
}
Public Subnet Created in VPC

Here we want our public subnet has Internet connectivity so, for that we have to create a Internet gateway and attach to a Route table.

resource "aws_internet_gateway" "my_internet_gateway" {
vpc_id = aws_vpc.shashikant_vpc.id

tags = {
Name = "my_internet_gateway"
}
}

resource "aws_route_table" "my_route_table" {
vpc_id = aws_vpc.shashikant_vpc.id

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

tags = {
Name = "my_route_table"
}
}

resource "aws_route_table_association" "assign_route_table_topublic" {
subnet_id = aws_subnet.shashikant_public_subnet.id
route_table_id = aws_route_table.my_route_table.id
}
Internet Gateway created
Route table for public subnet

Now our Public Subnet is Ready for connecting with the World.

Create Private Subnet

Now we have to create a Private Subnet for launching our Database server.

Here we don’t want to connect with the outside world as we make it private so don’t create any Internet Gateway.

resource "aws_subnet" "shashikant_private_subnet" {
vpc_id = aws_vpc.shashikant_vpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1b"

tags = {
Name = "shashikant_private_subnet"
}
}
Private subnet created for Database server

Now our Private Subnet is created.

Create Security Group

Now we have to create Two Security groups, one is for our Web server and second is for our Database server.

so, first we create Security group for Frontend — web server.

Here in web server security group we allowed SSH protocol for some reasons, but in real world we don’t allow SSH protocol.

resource "aws_security_group" "webserver_security_group" {
name = "webserver_security_group"
description = "Allow ssh and http"
vpc_id = aws_vpc.shashikant_vpc.id

ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "SSH"
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 = "webserver_security_group"
}
}
Security Group created for web server

Now we create Security group for Backend — Database server

Here, In Database security group we only allow 3306 Port number as MySQL Database works on this port number.

resource "aws_security_group" "database_security_group" {
name = "database_security_group"
description = "Allow MYSQL"
vpc_id = aws_vpc.shashikant_vpc.id

ingress {
description = "MYSQL"
security_groups = [aws_security_group.webserver_security_group.id]
from_port = 3306
to_port = 3306
protocol = "tcp"

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

tags = {
Name = "database_security_group"
}
}
Security Group created for Database server

Launch Web Server

Now we have to launch our web server. Here we are using WordPress site for our Frontend web server

resource "aws_instance" "wordpress" {
ami = "ami-000cbce3e1b899ebd"
instance_type = "t2.micro"
associate_public_ip_address = true
subnet_id = aws_subnet.shashikant_public_subnet.id
vpc_security_group_ids = [aws_security_group.webserver_security_group.id]
key_name = "mykey"

tags = {
Name = "wordpress"
}
}
web server instance launched (WordPress)

Launch Database Server

resource "aws_instance" "MySQL" {
ami = "ami-0019ac6129392a0f2"
instance_type = "t2.micro"
subnet_id = aws_subnet.shashikant_private_subnet.id
vpc_security_group_ids = [aws_security_group.database_security_group.id]

tags = {
Name = "MySQL"
}
}
Database server Launched (MySQL)

So, here our Secured Infrastructure is Created with a VPC having two subnets, private subnet having Database server and public subnet having web server.

Important Instructions

At the first time of running Terraform code on AWS CLI, use “terraform init” to install the plugins. do this process only once.

terraform init
terraform init

To check syntax of code use “terraform validate”. if you get some error, check syntax of code, and try again it until success come.

terraform validate
terraform validate

To apply Terraform code, use

terraform apply
terraform apply

To destroy all the infrastructure made by your Terraform code , use

terraform destroy
terraform destroy

GitHub Repository Link for Terraform code

Thank You for Reading!!!

Any suggestions are most welcome!!!

--

--