Akshat Soni

Jul 22, 2020

9 min read


Task description:-

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

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

1. public subnet [ Accessible for Public World! ]

2. 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. Create a NAT gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC in the public network

6. Update the routing table of the private subnet, so that to access the internet it uses the nat gateway created in the public subnet

7. 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.

8. 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.

In my previous blog. I have explained this complete setup of public and private subnet but even though if we do that setup their is one issue we can face and that is the private subnet have no internet connection. It will be the best infrastructure in terms of security, but what if we have to update some package in that os or update the database server in that situation we might get some trouble. So to overcome that problem in this blog. I am going to explain how we can troubleshoot that error. Also in my previous blog I have explained the configuration of wordpress and mysql on ubuntu:16.04 os and in this blog I will explain about the configuration on rhel8. Their might be some new terms which i will explain while explaining the code.

STEP 1. Create a new vpc using terraform.

STEP 2. Creating the public and private subnets.

Step 3. Creating the internet gateway and assosciating the routing table to the public subnet.

Step 4. Creating an EIP for the NAT gateway and attaching it with the route table to the private subnet.


An Elastic IP address is the reserved public ip in the aws that we can assign to any instance and it will not be changed even after the reboot of the instance.


NAT Gateway is a highly available AWS managed service that makes it easy to connect to the Internet from instances within a private subnet in an Amazon Virtual Private Cloud (Amazon VPC).

STEP 5. Create security groups for the wordpress instance , mysql instance and for the bastion host instance which allows port 80 , 3306 and 22.

NOTE: Here to connect to the mysql host we need to use two different security groups and in those sgs we have to provide security groups id instead of cidr block. In my case sg1 is used by the wordpress instance and we need to allow anyone coming from this security group to the port no 3306 on mysql instance. And for the bastion host to connect to this instance we need to allow port 22 and cidr block will be means anyone from the outside world can connect to the bastion host or instead of allowing this we can provide a particular range of ip to make it more secure , anyone from the bastion host security group can connect to the port no. of 22 on the mysql instance.


A bastion host is a server or instance whose purpose is to provide access to a private network from an external network, such as the Internet.

In our case we will use the bastion host to connect through the mysql instance and use it to for updating the packages or server in that instance.

STEP 6. Launch the instances in their respective subnets.

After completing the code use terraform validate and apply.

In my case I have created a my own customized image in which i have configured the wordpress and the mysql on RHEL8. I will explain that part in the end of the blog.

After those commands it will create all the gateways and route tables which we can see on the aws dashboard.

In my previous blog, I have explained all this part but their was still a constraint at that time everytime we launch a new instance the private ip will change and the whole database configuration will fail at that time. So to avoid that part I have tweaked some part I will explain that after explaining the configuration procedure in the rhel8.

First to setup the database server use rhel8 image (ami-052c08d70def0ac62) and launch an instance on the aws.

sudo dnf remove @mysql
sudo dnf module reset mysql && sudo dnf module disable mysql
sudo vi /etc/yum.repos.d/mysql-community.repo
name=MySQL 5.7 Community Server

name=MySQL Connectors Community

name=MySQL Tools Community
sudo dnf — enablerepo=mysql57-community install mysql-community-server

sudo systemctl enable — now mysqld.service

This commands will be used to setup the mysql server on rhel8 and will be common for both the wp and mysql instance.

After this you need to remove the password authentication system for the mysql because while writing the code in terraform it shows a warning for using the password on the command line and it will fail to launch this instance. To remove the password

password=$(grep -oP ‘temporary password(.*): \K(\S+)’ /var/log/mysqld.log)

mysqladmin — user=root — password=”$password” password aaBB@@cc1122

mysql — user=root — password=aaBB@@cc1122 -e “UNINSTALL PLUGIN validate_password;”

mysqladmin — user=root — password=”aaBB@@cc1122" password “”

After doing this you need to run multiple commands in mysql console which again cant be possible using the terraform so either we can use some scripts , but i dont know much about that so i have used a different alternative. I have created on commands.txt file in the mysql instance and written all the commands for creating the database , user and granting them the power for remote login and from that one single file we can easily run multiple commands in one go using the terraform. Use the following commands to write commands.txt file.

CREATE USER 'derek'@'wpserverip' IDENTIFIED BY "Strong34S;#";
GRANT ALL PRIVILEGES ON test_db.* TO 'derek'@'wpserverip';

And also for the remote login we need to change the bind address in the configuration file.

sudo vi /etc/my.cnf



sudo systemctl restart mysqld.service

Now our configuration for the mysql is completed. You can create one snapshot for this volume and then create your own ami-image.

We can launch again a new instance on the same rhel ami-image and install the mysql server explain just like above their is no need to remove the password in this server as we use this only as a client. After installing the mysql we have to install the php package and also the wordpress site pages.

dnf install php-mysqlnd php-fpm httpd tar curl php-json
systemctl start httpd
systemctl enable httpd

You can check the connection of the mysql database from the wordpress instance by using.

mysql -u username -ppasswordgiven -h serverprivateip

After this download the webpages of the wordpress from the official website and copy them to the /var/www/html folder.

curl https://wordpress.org/latest.tar.gz --output wordpress.tar.gz
tar xf wordpress.tar.gz
cp -r wordpress /var/www/html
chown -R apache:apache /var/www/html/wordpress
chcon -t httpd_sys_rw_content_t /var/www/html/wordpress -R

After doing this simply go to the http://wpserverpublicip/wordpress it will show you the installation page where it will ask for the database connection. You can either provide the details of the database and user their or you can create one configuration file of wp-config.php in the /var/www/html/wordpress folder as shown in the images.

But every time we launch the instance we need to change the private ip in the configuration files so we can use the sed command to change the private ip by using the terraform as shown.

However we cant change the files in the mysql instance using the terraform because we can’t have the direct connectivity to it. First we need to login to the bastion host and from their we can check the internet connectivity for the instance and also we can change the serverprivateip. I have copied a key from the windows to the bastion host and then connected to the mysql instance which is running in the private subnet.

After all this setup we can finally go to the public ip of the wpinstance and can run out wordpress site.

This code might get a little bit longer as the configuration part is a little bit hard. It can be a lot easier by using the scripts , but i dont know much about it. In future i’ll definitely try to improvise this project with some more modifications.


LINKEDIN PROFILE: https://www.linkedin.com/in/akshat-soni-011b461a6

GITHUB LINK: https://github.com/akshat-crypto/HCC_TASK4.git