LAUNCHING WORDPRESS ON PUBLIC SUBNET AND MYSQL ON PRIVATE SUBNET ON AWS USING Terraform.

Rohit Raut
7 min readAug 23, 2020

TASK DESCRIPTION

In this task we will create a new PVC having public and private subnet using terraform and launch wordpress in public subnet and mysql in private subnet using pre-configure AIM images.

here we will not provide any outside connectivity to private subnet

NOTE: Go through all the tasteps we cannot run this code directaly we have to do some changes.

What is Bastion host?

A bastion host is a server whose purpose is to provide access to a private network from an external network, such as the Internet. Because of its exposure to potential attack, a bastion host must minimize the chances of penetration.

STEPS

Provider

provider "aws" {region     = "ap-south-1"profile = "rohit"}

Step 1: Creating VPC

In one VPC aws provides already with precreated network so any instance can ping to other instance using private IP becuse of this feture we will connect our worpress running on public subnet to mysql running on private subnet.

#VPCresource "aws_vpc" "main" {cidr_block       = "192.168.0.0/16"instance_tenancy = "default"enable_dns_hostnames = truetags = {Name = "MyVPC"     }}

Step 2: Creating TWO subnet’s to make one as public and another private

precaution : your subnet cidr must be in rage of VPC’s cidr

#subnet-1aresource "aws_subnet" "subnet1" {vpc_id     =  aws_vpc.main.idcidr_block = "192.168.0.0/24"availability_zone = "ap-south-1a"map_public_ip_on_launch = truetags = {Name = "MyVPCSub-1a"    }}#subnet-1bresource "aws_subnet" "subnet2" {vpc_id     =  aws_vpc.main.idcidr_block = "192.168.1.0/24"availability_zone = "ap-south-1b"tags = {Name = "MyVPCSub-1b"       }}

Step 3: Creating Internet Gateway for VPC so it has outside Connectivity

Now we create one Internet gateway. We create this gateway because all the traffic of VPC goes out and comes in using this internet gateway. We only attach internet gateway to one VPC. Without the Internet getaway, we can’t connect to the outside world.

#Internet Gatewayresource "aws_internet_gateway" "gw" {vpc_id = aws_vpc.main.idtags = {Name = "myIG"    }}

Step 4: Creating Routing table and associating it with subnet 1

Even we have created internet gate in vpc no instance have outside connectivity beacuse instance don’t How to go to internet that is why we have to create route table which tell the route of intenet.

resource "aws_route_table" "IG" {vpc_id = aws_vpc.main.idroute {cidr_block = "0.0.0.0/0"gateway_id = aws_internet_gateway.gw.id}tags = {Name = "IG"     }}#Assosicationresource "aws_route_table_association" "subnet-a-ass" {subnet_id      = aws_subnet.subnet1.idroute_table_id = aws_route_table.IG.id}

Step 5: Creating Security Groups for worpress and mysql with specific RULE.

Security Group 1: Create Security Group for wordpress allowing port 80 and 22

#Webserver Security Groupresource "aws_security_group" "For-webserver" {name        = "webserver"description = "Allow http,ssh,ICMP"vpc_id      = aws_vpc.main.idingress {from_port = -1to_port = -1protocol = "icmp"cidr_blocks = ["0.0.0.0/0"]}ingress {from_port = 80to_port = 80protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}ingress {from_port = 22to_port = 22protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "webserver"  }}

Security Group 2 : for bation Host

Creating Security Group for bation Host which allows only 22 port.

#Bastion Host Security Groupresource "aws_security_group" "For-bastion-Host" {name        = "BastionHost"description = "Allow ssh"vpc_id      = aws_vpc.main.idingress {from_port = 22to_port = 22protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "BastionHost"}}

security Group 3: Creating Security Group for mysql allowing port 3306

here we added one security group rule which allow only that request which comming from webserver security group id so no other can able to access mysql. Only those instance can access port 3306 having webserver security group.

#Mysql allowing only webserverresource "aws_security_group_rule" "For-MysqlPort3306" {  type              = "ingress"   from_port = 3306   to_port = 3306   protocol = "tcp"   security_group_id =  aws_security_group.MysqlPort3306.id   source_security_group_id  = aws_security_group.For-webserver.id}resource "aws_security_group" "MysqlPort3306" {  name        = "MysqlPort3306"  description = "Allow 3306"  vpc_id      = aws_vpc.main.id  egress {     from_port   = 0      to_port     = 0     protocol    = "-1"     cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "MysqlPort3306"    }}

Second Security4 : Group for mysql

here only bastion host can able to connect to mysql vm using only port 22 that SSH connectivity.

#Mysql Allowing Bastion Host security groupresource "aws_security_group_rule" "For-MysqlBastionHostSSh" {type              = "ingress"from_port = 22to_port = 22protocol = "tcp"security_group_id = aws_security_group.MysqlBastionHostSSh.idsource_security_group_id  =  aws_security_group.For-bastion-Host.id}resource "aws_security_group" "MysqlBastionHostSSh" {name        = "MysqlBastionHostSSh"description = "Allow ssh"vpc_id      = aws_vpc.main.idegress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "MysqlBastionHostSSh"     }
}

Short Explaination:

why we attach security group of wordpress and bation host to mysql and what is use of it?

here because of first security group worpress can only connect to mysql instance using port 3306 which is for database connectivity and second second is for bastion Host it only connect via SSH.

Step 6 : Creating key which we will attach to instance.

#Creating Key
resource "tls_private_key" "Key_generator" {
algorithm = "RSA"rsa_bits = "2048"}resource "local_file" "Store_KEY" {content = tls_private_key.Key_generator.private_key_pemfilename = "mykey.pem"}resource "aws_key_pair" "key" {key_name = "key123"public_key = tls_private_key.Key_generator.public_key_openssh}

Step 7: Launching Wordpress

#launching Instanceresource "aws_instance" "wordpress" {depends_on = [aws_security_group.For-webserver,aws_key_pair.key]ami           = "ami-0dd91ccd275338ff4"instance_type = "t2.micro"vpc_security_group_ids  = ["${aws_security_group.For-webserver.id}"]key_name  =  aws_key_pair.key.key_namesubnet_id = aws_subnet.subnet1.idtags = {Name = "wordpress"}}

Step 8: Launching Bation Host

resource "aws_instance" "BastionHost" {depends_on = [aws_security_group.For-bastion-Host,aws_key_pair.key]ami           = "ami-08706cb5f68222d09"instance_type = "t2.micro"vpc_security_group_ids  = ["${aws_security_group.For-bastion-Host.id}"]key_name  =  aws_key_pair.key.key_namesubnet_id = aws_subnet.subnet1.idtags = {Name = "BastionHost"   }}

Step 9 : Launching MYSQL instance

resource "aws_instance" "Mysql" {depends_on = [aws_security_group.MysqlPort3306,aws_security_group.MysqlBastionHostSSh,aws_key_pair.key]ami           = "ami-01dffa1205ae2def9"instance_type = "t2.micro"vpc_security_group_ids  = ["${aws_security_group.MysqlPort3306.id}","${aws_security_group.MysqlBastionHostSSh.id}"]key_name  =  aws_key_pair.key.key_namesubnet_id = aws_subnet.subnet2.idtags = {Name = "Mysql"}}

Outputs Required

output "bastion_Public_IP"{value = aws_instance.BastionHost.public_ip}output "Wordpress_Public_IP"{value = aws_instance.wordpress.public_ip}output "mysql_Private_IP"{value = aws_instance.Mysql.private_ip}

You Can not run this code as it is because this AMI are configure by me.

How I configure this AMI ?

Create Two instance for Wordpress and MYSQL

Run the following commands in Wordpress instance.

sudo su
yum install httpd -y
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
cp wordpress/* /var/www/html/

yum update
yum remove httpd*
yum clean all
yum upgrade -y

yum install httpd24 -y
yum install php70 php70-mysqlnd php70-imap php70-pecl-memcache php70-pecl-apcu php70-gd -y
yum install mod24_ssl -y
start the service : systemctl start httpd
enable the ststemctl enable httpd

Run the following Commands in MSYQL instance

sudo su
yum install mysql-server -y
chkconfig mysqld on
Start the MySQL
service mysqld start
cat /etc/my.cnf
vi /etc/my.cnf
add this: bind-address = 0.0.0.0
service mysqld restart
login to MySQL: mysql -u root -p
>>>CREATE USER 'ishan'@'localhost' IDENTIFIED BY 'redhat';

>>>CREATE USER 'ishan'@'%' IDENTIFIED BY 'redhat';

>>>GRANT ALL PRIVILEGES ON *.* to ishan@localhost IDENTIFIED BY 'redhat' WITH GRANT OPTION;

>>>GRANT ALL PRIVILEGES ON *.* to ishan@'%' IDENTIFIED BY 'redhat' WITH GRANT OPTION;

>FLUSH PRIVILEGES;
>EXIT;

MYSQL remote server is ready

  • Go back to WordPress instance.
#cd /var/www/html/
#cp wp-config-sample.php wp-config.php
#vi wp-config.php
  • Edit the lines with configured MySQL as shown:

Save the file and create AMI images. and use it in above code.

Note: Every time when we run the code we only need to change private ip of mysql instance in this file and restart the httpd service

Commands:

Create infrastructure

terraform init 
terraform apply

destroy infrastructure

terraform destroy

GitHub Link : https://github.com/rohitraut3366/AWS_public_private_subnet.git

LinkedIn: https://www.linkedin.com/in/rohit-raut-71b8a119a/

I hope you had find this article interesting !!

Thank You !!

--

--