WordPress || AWS || MariaDB

Hosting Public WordPress & Private Database on AWS EC2

Looking for a way to host your own secure WordPress website, here you can. Here the steps you need to follow to set up your server.

NOTE: The terraform has been used on a Windows system as the host.

Pre-requisites on the host system:

main.tf

provider is used for telling Terraform as to which infrastructure/service provider will it be connecting to like in my use case, it will be an Iaas i.e. AWS. It is responsible for understanding API interactions and exposing resources.

To keep my credentials secure, I configured a profile with the required credentials and default region using AWS CLI and will be using it here. The profile can be configured with the following command.

aws configure --profile <profilename>

You can get your credentials from AWS Dashboard under the My Security Credentials.

Setup profile credentials

Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration. Use of data sources allows a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration.

I have used it to get the details of default and existing resources in my AWS. We will get the live availability zones in the selected VPC. This will be used later while creating other resources.

variables.tf

These input variables have been used across the file to make the code cleaner. I have set the default values as per my test case. I am testing the following setup in Mumbai (ap-south-1) availability zone. The aws credential profile used has been mentioned. The vpc name that will be given at the creation of VPC and as a part of subnet names has been mentioned.

The specific reason for using the availability zone as ap-south-1a or ap-south-1b is because t2.micro instances are not supported in ap-south-1c. Please make the changes according to your setup.

tls_private_key is used to generate RSA encrypted private and public key-pair and also encodes it as PEM.

Using local_file, we will save the private key generated by tls_private_key on our host system to be used later as if we require to connect to our instance via SSH.

aws_key_pair will create a Key Pair in the AWS account using the public key generated previously. This key will be bound to EC2 instances for SSH connections.

vpc.tf

Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including the selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways. You can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications.

For our VPC, the name will come as set in variables and the IPv4 CIDR as 192.168.0.0/16. Hostnames and DNS support have been kept as true so as auto public IP allocation can be done.

vpc.tf

Now, we will create two subnets. The public is for hosting the webserver which is open for public ingress and the other one being in the private network which only the Webserver and Developers can access. Public IP will be allocated to resources in the public subnet whereas only private IP will be allocated in the private subnet.

vpc.tf

We will be creating two gateways. One that has both way connectivity and another one with Egress only. The resources in the public subnet will have connectivity both ways with the internet i.e. both ingress and egress open as per the requirement, hence the Internet Gateway for it.

However, the database servers in the private subnet do not have internet connectivity as they don’t have a public IP. So we provide a NAT gateway which has a public IP given via Elastic IP resource that will allow these resources to connect to the internet so that the servers can download updates.

vpc.tf

We will have two route tables. One only with egress and another one with both way connectivity. The default route table will be given to private subnet with Egress only to the internet whereas the secondary table will have Internet Gateway for both way connectivity and will be given to public subnet.

wp-instance.tf || sql-instance.tf

Now time to set up our servers. We will start by creating security groups for our instances. For the WordPress instance, we will open 80 port for webserver and 22 for remote-exec commands in Ingress. Egress is completely open. For Database instance, 3306 port is open for webservers(set using the CIDR block) to access the database. Egress is completely open.

Then we will create an instance using Amazon Linux 2 AMI so that we get its private IP to be used while setting up our servers. This instance is the WordPress server.

Next, we create another instance of Amazon Linux 2 AMI and configure it using the User Data script. We will install the MariaDB server for the database, start its service. We also create a user for WordPress to access through and also it’s hostname is set so no one else can access the database from outside.

Next, a null resource with remote-exec will install Webserver on the WordPress instance. Then we will set up WordPress and configure its database details. We will set up the security exceptions for the webserver to work.

After we run the code. We will have a WordPress Page up and running to work on. Open it using its public IP.

Setup Page

Once you setup the account, log in into admin page.

Go to Tools > Site Health > Info > Database. You can see your database details there.

Database Details

The accumulated code can be found here:

To run the code, clone the repository and go inside the directory then run

terraform initterraform apply

To destroy the infrastructure, run

terraform destroy

References:

For any queries, corrections or suggestions, connect with me on my LinkedIn.

Worked in collaboration with Daksh Jain.

Just a tech enthusiast… Research, implement and share is what I like to do

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store