Launch a backended web portal with maximum data security

Saptarsiroy

--

On the industry level of approach towards various use-cases, we always have to consider the best and easiest way out to a problem which both caters the need of the clients, as well as does not underestimates their ethics and security. Today, technology has huge reach, integrating various resources can create magic! In this article, a very common use-case has been discussed, that is to launch a pre-configured WordPress instance on the top of AWS, which will be supported by a backend MySQL database server.

Now, we all know that the function of a backend database server to a web-portal is to store sensitive data of the clients, like — username, password, card details and so on. No one would like that their portal exposes their personal information to the outer world. So, maximum possible data security would be provided to the database instance working here, such that only the frontend would have the backend server access, although the backend will have internet access. To add cherry to the cake, this whole process would be automated using Terraform. Let’s see how!

Note : Just don’t forget to add the IAM provider for AWS at the beginning.

  • STEP-1: Create a VPC (Virtual Private Cloud). It is an on-demand configurable pool of shared computing resources allocated within a public cloud environment, providing a certain level of isolation between the different resources.
//Create VPC
resource "aws_vpc" "newVPC" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = "true"
tags = {
Name = "newVPC"
}
}
VPC created
  • STEP-2: Create the workstation subnets. A subnetwork or subnet is a logical subdivision of an IP network. WordPress shall be launched in a public subnet that will have an all-public access. MySQL database shall be launched in a private subnets that will be restricted for the public.
//Public subnet for Wordpress
resource "aws_subnet" "publicSubnet" {
vpc_id = aws_vpc.newVPC.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = "true"
tags = {
Name = "publicSubnet"
}
}
//Private subnet for mysql
resource "aws_subnet" "privateSubnet" {
vpc_id = aws_vpc.newVPC.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1b"
tags = {
Name = "privateSubnet"
}
}
Public and private subnets created
  • STEP-3: Create an internet gateway. An Internet gateway is a network “node” that connects two different networks that use different protocols (rules) for communicating. The internet gateway will provide internet access to the VPC created.
//Create internet gateway
resource "aws_internet_gateway" "IntGateway" {
vpc_id = aws_vpc.newVPC.id
tags = {
Name = "IntGateway"
}
}
  • STEP-4: Create an elastic IP. An Elastic IP address is a reserved public IP address that can be assigned to any EC2 instance in a particular region, The elastic IP created will be needed for creating a NAT gateway and will be not be associated to any instance; it will be discussed after this.
//Create an elastic ip
resource "aws_eip" "nat_eip" {
depends_on = [aws_internet_gateway.IntGateway]
vpc = true
tags = {
Name = "nat_eip"
}
}
Elastic IP created
  • STEP-5: Create a NAT gateway. A NAT gateway gives cloud resources without public IP addresses access to the internet without exposing those resources to incoming internet connections. This NAT gateway will be used to connect the private subnet with internet via the elastic IP so that our MySQL server has internet access without any loophole in its security.
//Create nat gateway for MySQL site
resource "aws_nat_gateway" "wp_nat" {
allocation_id = aws_eip.nat_eip.id
subnet_id = aws_subnet.publicSubnet.id
depends_on = [aws_internet_gateway.IntGateway]
tags = {
Name = "wp_nat"
}
}
Nat gateway created
  • STEP-6: Create Routing tables and associate them to the respective subnets. In computer networking a routing table, or routing information base, is a data table stored in a router or a network host that lists the routes to particular network destinations, and in some cases, metrics associated with those routes. here, the routing table for NAT gateway will be associated with the private subnet and the routing table for Internet gateway will be associated with the public subnet.
//Create routing table for int gateway
resource "aws_route_table" "internetRoutingTable" {
depends_on = [
aws_internet_gateway.IntGateway,
]
vpc_id = aws_vpc.newVPC.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.IntGateway.id
}
tags = {
Name = "internetRoutingTable"
}
}
//Associate internet route table with public subnet
resource "aws_route_table_association" "associate_intRT" {
depends_on = [
aws_subnet.publicSubnet,
aws_route_table.internetRoutingTable,
]
subnet_id = aws_subnet.publicSubnet.id
route_table_id = aws_route_table.internetRoutingTable.id
}
//Create route table for nat gateway
resource "aws_default_route_table" "natRoutingTable" {
depends_on = [
aws_vpc.newVPC,
aws_nat_gateway.wp_nat,
]
default_route_table_id = aws_vpc.newVPC.main_route_table_id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.wp_nat.id
}
tags = {
Name = "natRoutingTable"
}
}
//Associate nat routing table with private subnet
resource "aws_route_table_association" "associate_natRT" {
depends_on = [
aws_subnet.privateSubnet,
aws_default_route_table.natRoutingTable,
]
subnet_id = aws_subnet.privateSubnet.id
route_table_id = aws_default_route_table.natRoutingTable.id
}
Routing tables created and associated
  • STEP-7: Create the security groups. A security group acts as a virtual firewall for EC2 instances to control incoming and outgoing traffic. Inbound rules control the incoming traffic to the instance, and outbound rules control the outgoing traffic from the instance. WordPress instance will have the ingress protocols for SSH-22 as well as HTTP-80 so that web portal access to public is granted. MySQL server instance will have the ingress protocols for SSH-22 and MySQL-3306 so that only the database server and no other traffic can only hit the instance. Thus, the database would be quite safe.
//Create security group for Wordpress site
resource "aws_security_group" "wordpress-sg" {
name = "wordpress-sg"
vpc_id = aws_vpc.newVPC.id
description = "Allow ssh-22 and http-80 protocols for access to wordpress site"
ingress {
description = "HTTP-WP"
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 = "wordpress-sg"
}
}
//Create security group for Wordpress site
resource "aws_security_group" "mysql-sg" {
name = "mysql-sg"
vpc_id = aws_vpc.newVPC.id
description = "Allow ssh-22 and mysql-3306 ports for access to MySQL database"
ingress {
description = "MYSQL"
from_port = 3306
to_port = 3306
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 = "mysql-sg"
}
}
Security groups created
  • STEP-8: Launch the WordPress and MySQL instances within the respective subnets and using the respective security groups.
//Create Wordpress instance
resource "aws_instance" "secureWordpress" {
ami = "ami-000cbce3e1b899ebd"
associate_public_ip_address = "true"
instance_type = "t2.micro"
availability_zone = "ap-south-1a"
subnet_id = aws_subnet.publicSubnet.id
vpc_security_group_ids = [aws_security_group.wordpress-sg.id]
key_name = "newkey"
tags = {
Name = "Wordpress"
}
}
//Create MySQL instance
resource "aws_instance" "secureMySQL" {
ami = "ami-0019ac6129392a0f2"
instance_type = "t2.micro"
availability_zone = "ap-south-1b"
subnet_id = aws_subnet.privateSubnet.id
vpc_security_group_ids = [aws_security_group.mysql-sg.id]
key_name = "newkey"
tags = {
Name = "MySQL"
}
}

So, that’s all with the terraform coding part. Now, let’s deploy the architecture!

☆ DEPLOY STEP-1: Initialise the terraform in the workspace to get all proper providers required.

terraform init

☆ DEPLOY STEP-2: Run the terraform code so that all the resources get accordingly created and provisioned.

terraform apply -auto-approve

Seems good to go!!

The WordPress and MySQL instances have been successfully launched.

EC2 instances

In order to head over to the WordPress (note that the MySQL instance will not be accessible), all that is to be done is to copy the Public IPv4 DNS of the instance and paste it in a new tab.

That’s all guys! Our secured web portal architecture is all up and working :)

Thanks all!!

--

--

No responses yet