Setting up the Secured WordPress setup for Company on the AWS platform.

Gauravkumargupta
6 min readJul 20, 2020

Hi Readers,

In, this article you will get to know how we can keep our web portal environment secure for our company. So keeping the security as the highest priority we have created two instances on the AWS platform one instance is Public instance and one instance is Private instance. We can take an example of WordPress setup where WordPress can be part of Public instance which is accessible from the outside world and the MySQL DataBase server will be part of Private instance users can’t access the database server directly if they want to access the database server then they have to go through WordPress. In, this way we can keep our environment secure.

The best part about this article is that we are doing everything through Terraform code. Let’s go through the article to achieve this setup.

Prerequisite:- I am hoping that u have a basic understanding of the Terraform and AWS CLI program to configure aws profile so that we can manage AWS services from the command line.

Let’s gets started :

STEP 1: To, setup the secure environment I have created a custom VPC with IPv4 range 192.168.0.0/16

Custom VPC created

STEP 2: Create two subnet and the CIDR block of those subnets will be a subset of the VPC CIDR block.

public-subnet and private-subnet are just names.

STEP 3: Create two Security groups for both of the instances.

STEP 3.1: The security group that will attach to the instance which is accessible to the outside world will have the inbound rules allow are HTTP and SSH and for outbound rules, everything is allowed.

STEP 3.2: The security group that will attach to the instance which is only accessible by the instance which has a WordPress setup will have the Inbound rules allow MySQL and SSH and for outbound rules, everything is allowed.

STEP 4: Create an Internet Gateway that provides a target in our VPC route tables

Internet Gateway

STEP 5: Create the route table and associate it with the instance that is accessible to the Outside world.

Route Table.

STEP 6: Now we have to launch an instance that is accessible to the public world and most important we have to attach the Security Group that we have created which has inbound rules allow HTTP and SSH.

STEP 7: Launch another instance that is only accessible by the above instance and moreover attach the Security Group that we have created which has inbound rules allow MySQL and SSH.

The whole code looks like :

provider "aws" {
region = "ap-south-1"
profile = "gaurav"
}
################ Creating VPC ##############################resource "aws_vpc" "gaurav-vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true
instance_tenancy = "default"
tags = {
Name = "gaurav-vpc-task3"
}
}
################ Creating VPC ############################################## Creating Public and Private Subnet ##############################resource "aws_subnet" "public-subnet" {
vpc_id = aws_vpc.gaurav-vpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1a"
tags = {
Name = "public_subnet"
}
}
resource "aws_subnet" "private-subnet" {
vpc_id = aws_vpc.gaurav-vpc.id
cidr_block = "192.168.2.0/24"
availability_zone = "ap-south-1b"
tags = {
Name = "private_subnet"
}
}
################ Creating Public and Private Subnet ####################################### Creating Security Group for Public instance and Private instance########resource "aws_security_group" "public_subnets_wordpress_SG" {
name = "public_gaurav_vpc"
description = "ssh,http"
vpc_id = aws_vpc.gaurav-vpc.id
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "http"
from_port = 80
to_port = 80
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 = "public_subnets_wordpress_SG"
}
}
resource "aws_security_group" "private_subnets_mysql_SG" {
name = "private_gaurav_vpc"
description = "ssh,http for private access only "
vpc_id = aws_vpc.gaurav-vpc.id
ingress {
description = "mysql"
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [ "${aws_security_group.public_subnets_wordpress_SG.id}" ]
}
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [ "${aws_security_group.public_subnets_wordpress_SG.id}" ]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "private_subnets_mysql_SG"
}

}
######### Creating Security Group for Public instance and Private instance########
########### Creating an Internet Gateways ###########resource "aws_internet_gateway" "gateway" {
vpc_id = aws_vpc.gaurav-vpc.id
tags = {
Name = "gaurav-vpc-task3-gateways"
}
}
########### Creating an Internet Gateways ###################### Creating Routing table and binding it with Public Subnet###########resource "aws_route_table" "r" {
vpc_id = aws_vpc.gaurav-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gateway.id
}
tags = {
Name = "public_subnets_routing_tables"
}
depends_on = [
aws_internet_gateway.gateway
]
}
########### Creating Routing table and binding it with Public Subnet################### Creating subnet association ######resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.public-subnet.id
route_table_id = aws_route_table.r.id

depends_on = [
aws_subnet.public-subnet

]
}######## Creating subnet association ######

######### Launch EC2-instance in public instance ######
resource "aws_instance" "instance1" {
ami = "ami-0447a12f28fddb066"
instance_type = "t2.micro"
subnet_id = aws_subnet.public-subnet.id
key_name = "deployer-key"
associate_public_ip_address = true
vpc_security_group_ids = [ "${aws_security_group.public_subnets_wordpress_SG.id}" ]
tags = {
Name = "WordPress"
}

}

######### Launch EC2-instance in private instance ######
resource "aws_instance" "instance2" {
ami = "ami-0732b62d310b80e97"
instance_type = "t2.micro"
subnet_id = aws_subnet.private-subnet.id
key_name = "deployer-key"
associate_public_ip_address = false
vpc_security_group_ids = [ "${aws_security_group.private_subnets_mysql_SG.id}" ]

tags = {
Name = "MySQL"
}

}

STEP 8: Run the above code.

As the code has been successfully run, so let’s see what are the changes our code has made on the AWS console.

Instance Created
VPC Created
Security Group with Inbound Rules HTTP and SSH.
Security Group with Inbound Rules MySQL and SSH.
Internet Gateway Created.
Route Table Created.

Since our setup has been ready, now we can test our environment for that. I am accessing my server that is accessible to the public world through putty and for that, I have to use a key that I have created but no worries for your reference I have uploaded a private key into the GitHub and from that server (open to the external world) we will access our private server.

Accessing the public server and transferring key into it to access the private instance
from the public server, we are accessing our private server.

Summary:- Since the Public IP is only attached to the server which has a WordPress setup so our Database server is only accessed by this server.

GitHub URL:-

To connect me you can check my Linkedin profile.

Thanks and Regards

Gaurav Kumar Gupta

Direct: +91- 7003708664

--

--