1. Supercharge your WordPress site with AWS Elastic Beanstalk

    Today I supercharged my blog with all the load-balancing and content distribution power you can get with Amazon AWS. My blog readership boasts a pathetic readership now but I’m so addicted to speed that these surgical procedures just had to be done nevertheless. Truthfully, I really just wanted to write a tutorial for some of you who are deploying heavy-traffic WordPress sites and to impress a girl.

     

    What the fuck am I trying to do?

    WordPress runs on PHP and uses a MySQL database. Every time you request a URL on a WordPress site, a whole bunch of PHP scripts kick in and make often multiple connections to MySQL in order to produce the content you requested. When your site’s traffic goes up, performance can take a beating. So here’s what we’re going to use:

    1. S3 + CloudFront – all static assets such as CSS, JavaScript and images will be served through a content distribution network to relieve your web servers (the ones running PHP) from having to deal with them.
    2. Elastic Beanstalk (EBS) – this is used to deploy a scalable WordPress environment. EBS can automatically increase/decrease the number of servers used and perform load-balancing for you.
    3. RDS – this replaces having MySQL installed on the localhost of the web servers and offers the benefit of replicas.
    4. ElastiCache – this caches frequent MySQL requests so that the database can chill.
    5. W3 Total Cache – this is a WordPress plugin that further enhances the optimisation experience by caching the output of page requests, eliminating the need for those numerous PHP scripts from having to run everytime the same pages are requested. This plugin will also store images you upload to S3.

    Prepare your wp-config.php file

    Normally, you would enter your MySQL credentials manually into the wp-config.php file. This time however, replace them with environmental variables that AWS Elastic Beanstalk will create. Thats pretty much all you have to do. How cool is that!

    Zip your WordPress installation

    The top level directory of your zip file should contain all the web-root directory files of WordPress, including your updated wp-config.php file. For me, this creates a file named “Archive.zip”. It doesn’t matter what this file is named. We will upload this file to AWS Elastic Beanstalk later (say goodbye to sFTP).

    compress

    Create an S3 Bucket

    This is where all your static assets from your theme as well as uploads will be stored. We will supercharge this with CloudFront later so that users from all over the planet will experience super fast loading speeds.

    Go to S3 and create a new bucket. In my example, I named it cdn.theghostcoder.com. At the “Permissions” properties of your new bucket, add a bucket policy with the following configuration (Change the value of the “Resource” node to reference your bucket).

    s3-policy

    Go to the “Static Website Hosting” section and turn on the selection “Enable website hosting”.

    s3-static

    Finally, just create index.html and 404.html files and upload them to your new S3 Bucket’s root directory. Test your S3 Bucket setup by going to the URL specified under the “Static Website Hosting” labelled “Endpoint”. In my case it is http://cdn.theghostcoder.com.s3-website-ap-southeast-1.amazonaws.com/ and http://cdn.theghostcoder.com.s3-website-ap-southeast-1.amazonaws.com/404.html.

    Start your CloudFront distribution

    In the CloudFront dashboard, create a new “Web” distribution. In the field “Origin Domain Name”, choose the S3 Bucket you created in the previous section. You can fiddle around with other settings later but for now, let’s just keep moving.

    Important Note: Do not use the auto-filled value that Amazon gives you. Instead enter the actual bucket name. In my example, CloudFront recommended cdn.theghostcoder.com.s3.amazonaws.com but I only used cdn.theghostcoder.com (the name of my S3 Bucket).

    cf-origin

    For the “Price Class”, I am going to choose “Use All Edge Locations (Best Performance)”. Hopefully the promise is delivered (#coderJoke).

    cf-distribution

    CloudFront will give you a distribution URL, in my case it was dl00jo7c9hndb.cloudfront.net. After several minutes from your setup process, you should be able to access that URL and see the contents of the index.html file you created earlier. This means CloudFront is now creating a worldwide distribution of content you upload to that S3 Bucket (the origin).

    You have the option of pointing a sub-domain to the CloudFront installation. I’m not covering this topic here but I’m effectively using cdn.theghostcoder.com via Route53.

    Create a IAM user for S3

    The WordPress plugin we will be using to cache files is W3 Total Cache. It will need to connect to your S3 Bucket in order to store your site’s static assets. Doing so requires it to have some credentials so this step aims to create a user account that limits W3 Total Cache’s access to only that S3 Bucket.

    Go to “Security Credentials” for your AWS account and add a new user. I used iam-theghostcoder as the new username. After your user is created, you will have just one oppotunity to download the security credentials as a .csv file so make sure you keep this file safe.

    Under the “Permissions” tab in the user details, create a new inline policy and use the following configuration (once again change values of the “Resource” property to your S3 bucket name).

    iam-policy

    Now for the fun part … AWS Elastic Beanstalk!

    Go to your Elastic Beanstalk dashboard and create a new application.

    ebs-create

    Choose to create a “Web Server Environment”.

    ebs-server

    Use the PHP pre-configuration and choose “Load balancing, auto scaling” (obviously).

    ebs-env

    Next, and now it will all make sense, under “Application Version”, upload the zipped WordPress installation you created earlier. Then under “Deployment Limits”, choose to update instances one at a time.

    ebs-upload

    Give your environment a name. I like to use my domain prefixed with “env-”.

    ebs-name

    Since WordPress requires a MySQL database, allow Elastic Beanstalk launch an RDS instance for you.

    ebs-db-selection

    You’ll pick the instance types depending on what type of functionality your WordPress site will have. If you’re only using WordPress for a blog or brochure site, t1.micro is sufficient. If you are running a membership or e-commerce site (or simply enjoy having power), then use something larger. 

    ebs-config

    ebs-tag

    Configure your RDS settings. It isn’t really necessary to use a large RDS instance because we’re going to use WP Total Cache and ElastiCache to optimise database usage.

    Important Note: Your database name should not contain any symbols. In the screenshot below, my browser had autofilled my database name with what I use on my local drive. Essentially instead of “db_theghostcoder”, I would use “dbtheghostcoder”.

    ebs-rds-config

    You’re almost there. AWS will request for you to allow the creation of an IAM user. Finally, you can review your deployment’s configuration and launch it! Elastic Beanstalk will start creating your environment. This will take a while.

    ebs-launching