After setting up WordPress in AWS and then switching off CloudFlare so I can use certificates from Amazon Certificate Manager, I noticed a pretty big drop in the GTMetrix score, specifically the YSlow report, and this was due to the lack of CDN (Content Delivery Network). Thankfully, I can progress with my studies of all things AWS, and set up CloudFront.
What is CloudFront?
CloudFront is a content delivery network, data can be pushed to it, or pulled by it to Amazons CloudFront edge locations, and delivered to the end-user. This should (hopefully) improve my YSlow score.
Setting up CloudFront
From the AWS console, find the CloudFront option, or search for it.
- Origin Domain Name: As it suggests this is where CloudFront will get its content from.
- Origin Path: This is used if your content is in an S3 bucket.
- Origin ID: This is a description of the origin.
- Origin SSL Protocols: What protocols our origin uses (if any, but it should) such as TLS1.2.
- Origin Protocol Policy: What this does is if set to “Match Viewer” then if the client requests the site via HTTP, then CloudFront will pull the data using HTTP from the origin server, if the client is using HTTPS, then CloudFront will use HTTPS. Or we can force it to use HTTP or HTTPS. There are a few caveats about this setting:
If your Amazon S3 bucket is configured as a website endpoint, you must specify HTTP Only. Amazon S3 doesn’t support HTTPS connections in that configuration.
For HTTPS viewer requests that CloudFront forwards to this origin, one of the domain names in the SSL certificate on your origin server must match the domain name that you specify for Origin Domain Name. Otherwise, CloudFront responds to the viewer requests with an HTTP status code 502 (Bad Gateway) instead of the requested object.
Both of these tips came from this guide to CloudFront.
Most of the other settings I left as the default, apart from when we get down to Distribution Settings. If we are going to use a custom DNS for this (which I am) then it needs to be added as an Alternate Domain Name (CNAMEs), there is also the option as to whether we want to use the default CloudFront certificate or our own IF it has been generated by ACM (Amazon Certificate Manager). I do have one from the previous post, so will use that instead. Clicking on the text field allows us to select a certificate from a drop-down menu:
You can also request a new certificate if there is not one already.
I left the rest of the settings as default. Finally, click “Create Distribution”.
As always, it takes a little time for it to be set up:
Next it’s a good idea to create a CNAME in your DNS to point something more memorable to the CloudFront DNS. I set mine up as aws-cdn.802101.com.
Setting up W3 Total Cache for CloudFront
From the W3 Total Cache (W3TC) General settings, select the CDN option. Tick the box to enable CDN, and then select the CDN type. For CloudFront, we can have it pull or push. With Origin Pull, CloudFront will pull the files as they are needed. With Origin Push the files are pushed to CloudFront. I am using the Pull option.
**Edit 1: See my note at the end – it’s safer (less costly) to use the Generic Mirror option instead**
Clicking on this option opens up IAM, and click on Users to start creating our first user. Click on “Add user”. W3TC is asking for an access key and secret key. From the IAM page, we can see that this means we need to set the option for Programmatic access.
On the next screen, select the option to “Create group”. I have seen a number of posts about this using full administrative access, but that seems like overkill and, quite frankly a little dangerous. Instead, do a search for CloudFront and add it to the CloudFrontFullAccess policy:
Scroll down and click on the button that says Next: Review. Click on it, then select “Create user” on the next page.
Make a note of the URL that;’s shown and download the CSV file. Store it somewhere nice and safe.
For our immediate purposes, copy the Access key ID, and also get the Secret Access Key. Return to W3, and put the details in there.
Test the distribution, what we want to see is this, when we click on the test button:
There is an easier way, which is to create the group and the user in IAM, then let W3TC do the heavy lifting by adding the access key ID and secret key, then clicking on “Create Distribution”. Although the way I have done it is longer, we get to see more of the AWS scenery!
If we look at the previous post, we can see that the links have already updated to reflect the new settings. When we hover over an image, it shows the aws-cdn URL instead:
Once this was turned of, the image opened from the correct URL, but the certificate was actually that of CloudFlare, not CloudFront. Agin, I needed to go back into the CloudFlare settings and switch the CNANE to DNS only (clicking on the orange cloud in the CloudFlare DNS console).
Once that was done, it was actually redirecting to the right place, but I had made a serious boo-boo with the certificate settings. The aws.802101.com cert did not have an alternate name for aws-cdn.802101.com, and the website looked shit.
I created a new certificate and set that in the CloudFront settings. Once it had updated and a browser refresh later, I got the intended result:
The images are being served from the CloudFront distribution, with our SSL certificate.
What effect has this had on the YSlow report? Well, here is the first one taken (using CloudFlare):
Here is the latest one:
Not too far off, but the loading time has actually doubled. Where I am losing points is:
- Add expires headers
W3TC is currently un-tuned. So, I did some tuning. which after a while seemed to sort things out. Things are looking (a little) better:
There are still a few improvements to make, but I know it’ll never be a perfect score.
Interestingly, it seems that the more recent versions of W3TC can get you hit with a pretty hefty AWS bill for invalidations:
I switched mine to be a generic mirror to be on the safe side.
**Edit 2: being on the safe side seems to have stopped the CDN functionality… Back to the drawing board! **
I removed W3 Total Cache and installed WP Rocket instead. I use it over on www.802101.com and it worked well there. It is much easier to set up, and my score went up to this: