Scalable and secure Wordpress hosting on AWS

Build elastic Wordpress website on AWS using RDS, CloudFront, ElastiCache, Auto Scaling Groups, EFS. Secure access to the website hosts with Bastion hosts.

This article describes a Scalable Wordpress Incipience template

You can build a production-ready Wordpress web-site with this template using Incipience generator.

Build a Wordpress web-site using this template

Pets vs Cattle

Wordpress is one of the most popular CMSes in the world, initially released in 2003.

At that time Cloud computing didn’t exist, so this system was built in a paradigm of a single host.

PHP web application and the database are usually running on the same host (VM or a computer), all files are stored at the same host.

This approach looked ok in 2003, but is not acceptable in the world of cloud technologies.

The major issue can be illustrated by a known DevOps concept called Pets vs Cattle.

In the Pets service model, each pet server is treated with care, it’s given a loving names. The servers are “unique, lovingly hand-raised, and cared for, and when they get sick, you nurse them back to health”. You scale these up by making them bigger, and when they are unavailable, everyone notices.

In the Cattle service model, the servers are given identification numbers, the same way cattle are given numbers tagged to their ear. Each server is “almost identical to each other” and “when one gets sick, you replace it with another one”. You scale these by creating more of them, and when one is unavailable, no one notices.

So, let’s list the major issues of the “Pet” Wordpress set-up:

First, reliability: when your Pet web host dies or becomes sick, your web site becomes unavailable and your business suffers.

The second problem is scale. It’s quite problematic to adapt to an increasing traffic, as scaling a single web server is very difficult, sometimes impossible without a service interruption. Also, there’s an upper limit of your scale, because sooner or later you hit the hardware limits. And if your traffic has seasonal spikes, then you need to significantly overprovision server resources, as it will be impossible to elastically scale it following server load.

The third problem is security. The machine running PHP and Wordpress is exposed to the public Internet, and is thus vulnarable to potential attacks. To make things worse, all data are being hosted on the same machine, so from the security standpoint this solution is not acceptable.

Proper Wordpress set-up in the cloud

The solution is to use a scalable architecture, separating data storage, file storage and compute. Such architecture allows having multiple hosts running Wordpress, elastically changing the number of hosts based on load and system health.

Load balancer distributes the load between these hosts. Autoscaling group scales the fleet of VMs depending on the load.

The database has to be hosted at a managed database service (e.g. AWS RDS) which provides a high level of security, elasticity, durability and availability. In this case, again, if the VM hosting the database dies, it will be just replaced and the entire website won’t be affected at all. No user will notice the problem. The data in the database can be encrypted with customer managed key (CMK) providing a high level of security.

We can place Elasticache between the VMs hosting the Wordpress and the database. This caching level significantly decreases the database load and improves overall performance of the Wordpress website.

On top of the load balancer we can put a CDN (CloudFront) caching the traffic. The CDN will catch and serve majority of the traffic, especially the static content (javascript, css, pictures), again, significantly improving the Wordpress website performance and decreasing load of the wordpress application and the database.

Wordpress website architecture

Customizations

When you create the Wordpress infrastructure, you can change various parameters, in particular, Wordpress version, instance sizes for the worker instances, RDS Aurora, Elasticache, bastions, etc.

See the full list of parameters here.

You can also change the PHP parameters by tweaking the php.ini, which you can find here.

By default, you will have the following values there:

memory_limit = 128M

post_max_size = 0

upload_max_filesize = 64M

max_input_time = 60

max_execution_time = 30

Security

Worker wordpress instances are hidden in a private subnet, and do not have publicly accessible network interface. Thus, it’s not possible to access the instances from the Internet.

If you for some reason need to SSH to these instances, open AWS console, go to the EC2 console, navigate to Auto Scaling groups and find the Bastion launch configuration for your stack. Edit the launch configuration and set the desired instances to 1. Press Save and the Bastion instance will be created. Bastion is a gateway to your instances for enhanced security.

The Wordpress CLI is enabled on each instance, SSH into Bastion, then SSH into an instance. From the wordpress install directory /var/www/wordpress/wp use the wp command to interact with your wordpress install.

Elastic File System (EFS)

The storage level of this template is represented by an Amazon EFS file system. In addition to the EFS itself, the template will generate other AWS resources to monitor and send notifications if the burst credit balance of the file system drops below predefined thresholds. These alarms and other AWS CloudWatch metrics, including a file system size custom metric are added as widgets to a CloudWatch dashboard.

Throughput on Amazon EFS scales as a file system grows. Because file-based workloads are typically spiky—driving high levels of throughput for short periods of time, and low levels of throughput the rest of the time—Amazon EFS is designed to burst to high throughput levels for periods of time. Amazon EFS uses a credit system to determine when file systems can burst. Each file system earns credits over time at a baseline rate that is determined by the size of the file system, and uses credits whenever it reads or writes data. The baseline rate is 50 MiB/s per TiB of storage (equivalently, 50 KiB/s per GiB of storage). Accumulated burst credits give the file system permission to drive throughput above its baseline rate. When a file system has a positive burst credit balance, it can burst. The burst rate is 100 MiB/s per TiB of storage (equivalently, 100 KiB/s per GiB of storage).

If your WordPress deployment accessing the file system relies on the burst throughput for normal operations, running out of burst credits could negatively impact the workload, so monitoring the file system’s burst credit balance is essential. The efsalarms template will create two Amazon CloudWatch alarms that will send email notifications if the burst credit balance drops below two predefined thresholds, a ‘Warning’ threshold and a ‘Critical’ threshold. These thresholds are based on the number of minutes it would take to completely use all burst credits if the file system was being driven at the highest throughput rate possible, the permitted throughput rate. You enter these minute variables as input parameters in the Cloudformation template. The ‘Warning’ threshold and has a default value of 180 minutes. This means that a CloudWatch alarm will send an email notification 180 minutes before the credit balance drops to zero, based on the latest permitted throughput rate. The second alarm and notification is a ‘Critical’ notification and has a default value of 60 minutes. This alarm will send an email notification 60 minutes before the credit balance drops to zero, based on the latest permitted throughput rate. Permitted throughput is dynamic, scaling up as the file systems grows and scaling down as the file system shrinks. Therefore a third and fourth alarm is create that monitors permitted throughput. If the permitted throughput increases or decreases, an email notification is sent and an Auto Scaling Group will launch an EC2 instance that dynamically resets the ‘Warning’ and ‘Critical’ thresholds based on the latest permitted throughput rate. This EC2 instance will auto terminate and a new instance will launch to reset the thresholds only when the permitted throughput rate increases or decreases.

A new AWS CloudWatch dashboard is also created with some Amazon EFS, Amazon RDS, Amazon ELB, and custom metrics. Amazon EFS burst credit balance threshold alarms are also displayed if they were selected to be created.

Encrypting Amazon Aurora DB data at Rest

This template allows you to encrypt your databases using keys you manage through AWS Key Management Service (KMS). On a database instance running with Amazon Aurora encryption, data stored at rest in the underlying storage is encrypted, as are the automated backups, snapshots, and replicas in the same cluster. Encryption and decryption are handled seamlessly so you don’t have to modify your application to access your data. When you launch this AWS Cloudformation stack, you can choose to enable database encryption via a parameter in the master template. You may use the default RDS key automatically created in your account by leaving the “Existing AWS KMS CMK for RDS” parameter empty or use a key you created using KMS to encrypt your data.

Encrypting Amazon EFS Data & Metadata at Rest

Amazon EFS integrates with AWS Key Management Service (KMS) to support encryting file system contents using AWS KMS Customer Master Keys (CMKs). In an encrypted file system, data and metadata are automatically encrypted before being written to the file system. Similarly, as data and metadata are read, they are automatically decrypted before being presented to the application. These processes are handled transparently by Amazon EFS, so you don’t have to modify WordPress to take advantage of encrypted file systems. Encryption at rest is enabled by default for file systems you create using this cloudformation template. This option is exposed as a configurable Cloudformation template parameter. ‘true’ creates an encrypted file system. ‘false’ creates an unencrypted file system. To use the AWS-managed CMK for Amazon EFS (key alias: aws/elasticfilesystem) leave the “Existing AWS KMS CMK for EFS” parameter empty. To use a specific customer-managed CMK (within this AWS account or another AWS account) enter the CMKs ARN in the “Existing AWS KMS CMK for EFS” parameter field.

Amazon Certificate Manager SSL/TLS Certificates

This template will generate SSL/TLS certificate for you to make your newly website secure.

Build and Pipeline

We believe in “Code first” approach. So, this template will create a repository with the CloudFormation template, a deployment pipeline and build for the newly created infrastructure. You can easily modify parameters of the infrastructure as well as modify the infrastructure components by changing the template code. Changes to the source code will trigger the deployment which will update the generated Wordpress infrastructure.

Reference template

This template is created based on aws-refarch-wordpress AWS sample.