Creating a Highly Scalable WordPress Site on AWS using ElasticBeanstalk
These days organizations using AWS need highly-scalable and highly-available server infrastructures in order to host their web applications securely. They want to be able to quickly deploy applications to servers, connect the same database from multiple places.
In order to do this, we will be exploring how to create a highly scalable WordPress site in AWS on a linux server in this tutorial. However, you should be able to deploy this infrastructure using an AMI of your choosing. This site is an example demo of a site on a highly scalable server architecture described by the article.
Table of Contents:
- Getting started
- Setting up the Virtual Private Cloud (VPC), subnets & bastion host
- Altering the route tables for the new VPC
- Creating Relational Database System (RDS) Aurora Cluster
- Creating an Elastic File Storage (EFS) & filemount.config file
- Configuring WordPress & creating an .ebextensions folder
- Deploying WordPress into a new Elasticbeanstalk environment
1. Getting started
In order to start setting up this highly-available WordPress site, you will need to have some working knowledge of basic AWS services and the ability to run command line through terminal or putty.
We will be using the latest version of WordPress from the public repo as well as php 7.x for the centos server, but the same steps are taken for php 5.6.
If you don’t have an SSH key you would like to use for subsequent steps, create one now:
- Go to “Services” and “EC2”
- Click on “Key Pairs” & “Create key pair”, then enter the key pair name and the key format whether .pem or .ppk
- Click “Create key pair” to finish making the SSH key
2. Setting up the VPC, subnets & bastion host
Now that you know what you are getting into, it’s time to setup the virtual private cloud (VPC). The VPC will allow us to define the subnets that live in the public and the private regions of our cloud and designate the proper components to each.
- Go to “Services” and “VPC“
- Click on “Launch VPC Wizard” & select “VPC with Public and Private Subnets” subnets
- In the following screen, fill out the fields as below replacing VPC name with your preference, choosing the server type for the bastion, and naming the public and private subnets.
- Make sure you select NAT instance instead of a NAT gateway to allow SSH connectivity into your backend instances. Use the key that you made in the Getting Started section
Once you click “Create VPC”, AWS will create:
- A VPC with a public and a private subnet
- A routing table and Network Address Translation (NAT)
- A bastion host with the given key pair in the public subnet
- An elastic IP for the bastion host to access the internet
We still need to create two more subnets (Public subnet B and Private subnet B), one in each availability zone chosen earlier with a different IPv4 CIDR in order to make this a highly available setup. Let’s do that now while we are in the VPC subnet service of AWS.
- Go to “Services” and “VPC” under “Networking & Content Delivery“
- Click on “Subnets” and then “Create subnet”
- Fill out the name of the new public subnet, select the VPC you just created, and set the availability zone to something besides the one you used in the creation of the VPC:
- Click on “Create“, and then repeat those steps for the new private subnet:
You should also setup the security group that you will be using for the resources yet to be made.
- Go to “Services“, “EC2“, and then “Security Groups”
- Click “Create Security Group“, and enter your group name, description, and the VPC you just made
- To allow inbound http traffic on ports 80 and 443 as well as SSH access, edit the inbound rules like so:
- Outbound traffic can just be set to all traffic:
3. Altering the route table for the new VPC
We will need to set the subnet associations of the two private subnets to the main route table in the Route Tables section.
- Go to “Services” and “VPC” and “Route Tables“
- Select the route table noted “Yes” under the main column, and click “Subnet Associations” and “Edit Subnet Associations“
- Here you can add the private subnets you created and save them to the main route table
- Do the same for the non-main route table associated with the VPC, but associate both public subnets into that table.
4. Creating Relational Database System (RDS) Aurora Cluster
Once we have the VPC built, subnets created, and route tables modified, we can start thinking about the WordPress database. Aurora Cluster databases are scalable and quick.
- Go to the RDS service and click on “Create Database“
- In the following screen, make sure you have the Amazon Aurora box selected.
- Fill out the rest of the details about your database including the name, master username, master password, server type.
- At the bottom of the config settings, is a tab for additional configuration where you can select scheduled backups, encryption, logging, and deletion prevention.
- Click “Create Database” to start creating the Aurora database
- Make sure you note the username, password, database, port, and hostname of the database
5. Creating an Elastic File Storage (EFS) & filemount.config file
After the database is up, we can start making the file system needed for a truly scalable and tolerant setup. To do this we will use Amazon Elastic File System or EFS.
- Go to “Services“, “EFS“, and then click “Create file system“
- Select the VPC you created as well as the the public subnets in both availability zones
- Next select the security group you created earlier in the Getting Started section
- In the next screens, you can add key name values to describe the EFS encrypt the content, and set access point controls for users. Finally click “Create File System“
6. Configuring WordPress & creating an .ebextensions folder
Now that we have the file system created and ready for files, we can download the default WordPress files and add the .ebextensions hidden folder that runs the configs you want when a server is created.
On your local machine download WordPress using this command:
curl -LO https://wordpress.org/latest.zip unzip latest.zip cd wordpress
Then using command line you can create your hidden .ebextensions file inside the WordPress folder:
sudo mkdir .ebextensions
Finally, add the code to mount the EFS on any new servers that get spun up:
packages: yum: fuse:  files: "/opt/elasticbeanstalk/hooks/appdeploy/pre/11_unmount_filemount.sh": mode: "000755" owner: webapp group: webapp content: | #!/usr/bin/env bash if mountpoint -q /var/www/html/wp-content/uploads; then sudo umount /var/www/html/wp-content/uploads fi "/opt/elasticbeanstalk/hooks/appdeploy/enact/02_mount_filemount.sh": mode: "000755" owner: webapp group: webapp content: | #!/usr/bin/env bash sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport [efs-id]:/ /var/www/html/wp-content/uploads
Save this code as filemount.config and place it into the .ebextensions folder. After this, you will want to use environment variables for your database credentials in wp-config.php, so change this file to use environment variables like below:
// ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define( 'DB_NAME', $_SERVER["RDS_DB_NAME"] ); /** MySQL database username */ define( 'DB_USER', $_SERVER["RDS_USERNAME"] ); /** MySQL database password */ define( 'DB_PASSWORD', $_SERVER["RDS_PASSWORD"] ); /** MySQL hostname */ define( 'DB_HOST', $_SERVER["RDS_HOSTNAME"] );
Finally zip the modified WordPress code for uploading into the Elasticbeanstalk container:
sudo zip -R wordpress.zip wordpress/
7. Deploying WordPress into a new Elasticbeanstalk environment
Now you can put all the pieces together in the AWS Elasticbeanstalk service.
- Go to “Services“, “Elasticbeanstalk“
- Click “Get Started” to start making an application to store your Elasticbeanstalk environments
- Enter your application name, the platform language it will use (PHP) and upload a zip of the WordPress code with the .ebextensions folder included
- Click on “Configure more options” and then click on each individual box to configure the container to your needs
- In the “Software” box, add the environment variables you set in the wp-config and set their values ( RDS_DB_NAME, RDS_HOSTNAME, RDS_PASSWORD, RDS_USERNAME )
- In the “Instances” box, select the security group that you made in this tutorial
- Next go to the Network box and select
With that you should have a highly scalable WordPress architecture up and running.
The next step is to provision a ssl certificate using Certificate Manager and applying it to the load balancer in the Elasticbeanstalk configuration. We will delve into this topic in a separate article.