Setting up CloudFront in front of WordPress 5 and Gutenberg

Published

This article discusses how I set up a CloudFront Distribution in front of my WordPress 5 instance. Special steps were taken to enable the Gutenberg Editor as well. At a high setting up CloudFront included:

  1. Creating a new CloudFront distribution
  2. Configuring my WordPress Instance as the Default Origin inside in CloudFront
  3. Configuring a DNS CNAME entry to point to the new CloudFront distribution

Displays a flow diagram of the HTTP request in my CloudFront WordPress caching setup. The request will be forwarded from my Website Front Door (taylor.callsen.me) to CloudFront via a DNS CNAME. If the requested content exists in CloudFront, it will be returned to the user. Otherwise CloudFront will request the information from its configured Origin server, which is my WordPress WebServer at cdn_internal_blog.gritto.net).

Creating the CloudFront Distribution and Default Origin

First I created a new distribution inside of the AWS CloudFront Console. I used the default settings for the majority of the configurations. My WordPress instance was configured to listen to cdn_internal_blog.gritto.net, which I entered as the “Origin Domain Name” (a.k.a. the Default Origin).

Creating a Custom Origin in CloudFront

I then added the URL that my WordPress instance would respond to (taylor.callsen.me) to the “Additional Domain Names” section. This is important because CloudFront will deny any request whos HOST header does not match a domain listed here.

After configuring these two specifics, I was able to accept the rest of the defaults and create the Distribution.

DNS Configuration

While the Distribution was spinning up, I took a second to confirm my DNS settings. I needed to configure my front-door domain (taylor.callsen.me) to point to CloudFront. Inside the DNS Zone Management, I added a CNAME entry that pointed to the new CloudFront Distribution.

Retrieving my CloudFront Domain Name

Creating the corresponding CNAME entry in GoDaddy, pointing to my CloudFront Distribution

At this point, it also made sense to confirm that the DNS for my back-door entry-point was configured correctly. Remember this is the cdn_internal_blog.gritto.net DNS address that CloudFront uses to retrieve content from my actual WordPress instance (which is not accessed directly by users). I opened up the DNS Zone Configuration for gritto.net and confirmed that a CNAME existed for cdn_internal_blog, and that it was pointing directly to my WordPress instance.

Enabling WP-Admin and Gutenberg Editor Passthrough on CloudFront

Since the default CloudFront behavior only supports GET and HEAD request, I needed to define five additional “Behaviors” in the AWS CloudFront Console to support WordPress authoring functionality:

  1. wp-admin/*
  2. wp-login.php
  3. /wp-json/wp/v2/posts/* (used by WordPress 5 / Gutenberg editor)
  4. /wp-json/wp/v2/pages/* (used by WordPress 5 / Gutenberg editor)
  5. /wp-json/wp/v2/tags* (used by WordPress 5 / Gutenberg editor)

Note: if using RSS feed capabilities, additional behaviors may be needed based on the URL scheme.

Inside of my distribution, I created a new Behavior for each of these path patterns. The behaviors were configured to passthrough all types of HTTP requests, cookies, headers, and query strings. The configuration I used for these Behaviors was (with pass-through options highlighted in red):

Screen capture of the CloudFront Behavior creation wizard with all required options enabled to allow passthrough of cookies, query strings, headers, and all types of HTTP requests.Here is a screen capture of the Behaviors tab once all five behaviors had been created:

WordPress Site Configuration

By now the CloudFront Distribution was spun up, and my DNS settings had been confirmed. Next I needed to take a look at my WordPress configuration. The Home URL and Site URL were still set to my staging/development domain, and needed to be updated. This can be done easily in the WordPress Admin on the Settings > General Page, or directly in the database (the wp_options table has these settings at option_id 1 and 2).

Disabling Canonical URL Redirection

After making these updates, I noticed a strange 302 redirect issue when accessing the homepage through my front-door domain and CloudFront. While users were accessing to site through taylor.callsen.me, CloudFront was retrieving the content from WordPress via cdn_internal_blog.gritto.net. Since I just updated WordPress’s Home and Site URLs to taylor.callsen.me, WordPress was trying to redirect the user (the user actually being the CloudFront distribution) to taylor.callsen.me. This was causing an endless 302 redirect loop.

I needed to disable a feature in WordPress called the “Canonical URL Redirection”, which essentially makes sure that regardless of how a user reached the site, they were redirected so that the URL in the address bar of their browser matched the site’s canonical URL (determined by WordPress’s Site URL option).

Canonical URL Redirection was easy enough to disable, done by simply adding the following to my theme’s functions.php:

// disable WordPress's Canonical URL Redirect feature
remove_filter('template_redirect','redirect_canonical');

Cache Invalidation

One of my favorite quotes is: “there only two hard problems in Computer Science: recursion, cache invalidation, and off-by-one errors”.

To handle cache invaldation on my WordPress site, I use the CloudFront Cache Controller plugin, which automatically sends Cache Invalidations whenever an existing post is updated.

Wrap-up and Other Considerations

Once I performed these steps, I was able to view my WordPress blog through my front door domain (taylor.callsen.me) and see the “Hit from CloudFront” header present. Load times were sped up on my simple site by around half a second, and I expect them to continue to improve as my content gets richer and includes more types of media.

I realized that there are some resources served with my site that should not be cached. One in particular was the sitemap.xml – special precautions had to be taken here to ensure I was always serving the latest sitemap.xml for my website. I could have perhaps defined a special Behavior in CloudFront, or explicitly placed Cache-Control headers on that resource. Luckily as it turns out, the WordPress plugin used for generating the sitemap.xml was taking care of this for me.

Subscribe by Email

Enter your email address below to be notified about updates and new posts.


Comments

Loading comments..

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *