AWS cloudfront or Amazon cloudfront is a content delivery network(CDN) service. It deliver data into end users up on request through secure, low latency, high speed network. The AWS CDN physical servers, are integrated to AWS global infrastructure and with other AWS services like Amazon EC2, Amazon S3, Load Balancing etc.

Benefits

  • Amazon CloudFront is globally distributed with highly-resilient Amazon backbone network.
  • We don’t have to pay for any data transferred between AWS other services and with CloudFront.
  • Highly programmable using Lambda@Edge functions and can run our custom codes.
  • Amazon CloudFront supports API calls, WebSocket traffic. Also supports proxy methods like POST, PUT, OPTIONS, DELETE and PATCH.
  • CloudFront has the option of modifying the original Headers from client.

Normal Work Flow of AWS CloudFront.

  • An End User access a website and request and image object to download through browser.
  • DNS service route the end user request to the nearest CloudFront edge location.
  • CloudFront edge location server checks its cache for the requested files and return the results to the end user.

The pricing

The Amazon CloudFront charges are mainly based on below areas. The details can be found from the AWS website and using AWS monthly calculator. There will be a slight change in price according to the Region.

DATA TRANSFER OUT (INTERNET/ORIGIN)
HTTP/HTTPS REQUESTS
INVALIDATION REQUESTS
FIELD LEVEL ENCRYPTION REQUESTS
DEDICATED IP CUSTOM SSL CERTIFICATES ASSOCIATED WITH A CLOUDFRONT DISTRIBUTION

Currently the aws cloudfront has 216 Points of Presence or edge locations available or called by the name amazon CDN locations. Each edge locations are inter connected and sync our data automatically. The updated list can be found from the Amazon website itself.

Benefits of Using cloudfront In WordPress

  • WordPress holds 28% of the web market share but there is room for improvement. Here comes the picture of cloudfront in WordPress.
  • Cloundfront increase the performance of our website by reducing server load.
  • It reduces the cost of operating your WordPress infrastructure by reducing Resource Allocation.
  • Reduces the traffic towers to the origin server by serving cached results to the end users.
  • The DNS server will hit the CloudFront CDN first and serve a copy of the content to the end users from cache and from the closet aws cloudfront edge locations related to the end user Geo location. The Cloudfront will pull content from the behind application servers or any other integrated service as it becomes new or something changed.
  • We will have option for cloudfront gzip which can reduce the size of the data send to end users by 70 percent.
  • Have the option named cloudfront http2 which will also support http2 versions.

Some CloudFront definitions.

  • Distribution: an DNS endpoint name we can use to send traffic. Normally we point our domain name to the distribution via DNS.
  • Origin: This is where our applications hosted. An origin can be either an Amazon S3 bucket or an HTTP server.
  • Behavior: A URL pattern and its associated caching behavior.

In our case we create multiple behaviors for the various WordPress URL requests and all that using single Origin and Distribution. Example Behavior are like WordPress admin pages should never be cached and other pages can be cached for a period of time.

In the case of WordPress, we have the following files/folders to think about

  • /wp-content/* and /wp-includes/* Most of the static assets and theme files will likely be here
  • /wp-admin/* and /wp-login.php* The admin pages
  • /wp-json/*  The root URL for the REST API
  • /contact/ (Replace this url with your own contact form url)
  • /wp-signup.php Used for visitor signups if your site supports it
  • /wp-trackback.php Blog post trackback functionality
  • /xmlrpc.php The WordPress API
  • /wp-cron.php WordPress scheduled task functionality
  • /.well-known/* (this is a required route for Let’s Encrypt postbacks)
  • Everything else Homepage, sub pages, blog posts, etc.

By default CloudFront caches all requests to the origin specified by Origin definition. Means behaves as full page cache and we also have the option to implement custom origin-pull patterns. So lets get started.

  • Log into the AWS management panel and go to the “CloudFront service” section.
  • Under Distribution click on “Create Distribution”

  • Now choose CloudFront Web distribution because we are using CloudFront for our WordPress website.

  • In the “Origin Domain Name” field use our Public DNS hostname of EC2 instance where our WordPress Website Hosted.
  • Leave “Origin Path” as blank. the “Origin ID” field will be auto filled. Leave it as it is.

  • Choose “Minimum Origin SSL Protocol” as “TLSv1” even though Amazon suggest to use the latest supported one by the server. But the problem with that, is some time the end user having older version of browser will have an issue with loading our website over https.
  • Choose the “Origin Protocol Policy” as “HTTPS Only”. This is how CloudFront communicates with our Origin WordPress EC2 instance server.
  • Change the value for ” Keep-alive timeouts” into “60” if you website is having low traffic other wise leave it with the default value “5”.
  • Leave other timeout related settings as it is. Basically this time out settings deals with how CloudFront will handle requests to our origin server.
  • Leave the filed “Origin Custom Headers” as blank. By using this filed we can modify the header send by the end user and can insert our desired value.

  • Choose “Viewer Protocol Policy” as ” Redirect HTTP to HTTPS “. This controls how our end users connect to Cloudfront.
  • Choose ” Allowed HTTP Methods ” as ” GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE ” because, WordPress use POST methods.
  • Leave “Field-level Encryption Config” as blank.
  • Cached HTTP methods, leave it as it is.
  • Choose “cache and origin request settings” as “Use a cache policy and origin request policy”
  • In “Cache Policy” click “Create a New policy” . A new browser window will open and from there create new policy with below settings.

Minimum TTL 1

Maximum TTL 31536000

Default TTL 86400

Whitelist the headers “Host,origin and Referer”

Allow “All” for Cookies and Query Strings.

  • Give a Name for Policy we create, Like “Custom-Managed-Cache-Policy”. Save the settings.
  • After that click the refresh/reload button next to “Cache Policy” and our newly created Cache policy will appear from the drop down menu. Choose it.

  • In the “Origin Request Policy” click on “Create a New policy” , A new browser window will open.
  • Give a name like “Custom-headers-passed” and whitelist the headers “Host,origin, Referer and User-Agent”
  • WordPress makes extensive use of cookies, and we need forward at least below cookies based on a whitelist.comment_author_*
    comment_author_email_*
    comment_author_url_*
    wordpress_logged_in_*
    wordpress_test_cookie
    wp-settings-*
    PHPSESSID
    wordpress_*
    wordpress_sec_*
  • There are lots of places where WordPress will use query strings in the URL, so we need to instruct CloudFront how to handle those as well. So Choose “All”
  • Save it and go back to the Create new distribution page. Click “Refresh” button next to “Origin Request Policy” and choose our newly created policy from the drop down menu.

By Doing this we define selected Headers pass to or forward to origin from Cloudfront. Choose only minimum Host headers we need to pass. If we choose all, CloudFront will not cache objects but will instead send all requests to your Origin for processing and if choose “None” then CloudFront could serve the wrong content in certain circumstances, such as when you host content for multiple websites on the same server.

  • Choose ” Compress Objects Automatically” as “Yes”. CloudFront will compress certain files when the requesting viewer or browser includes the header: “Accept-Encoding: gzip”. Delivering compressed objects will improve performance for your users.
  • Choose “Smooth Streaming” and “Restrict Viewer Access(Use Signed URLs or Signed Cookies) as “No”
  • Leave “Lambda Function Associations” as it is.

  • In “Price Class” Choose ” Use All Edge Locations”
  • AWS WAF Web ACL = None
  • Alternate Domain Names (CNAMEs) == our domain names, like example.com and www.example.com
  • SSL Certificate Choose the default SSL certificate provided by CloudFront
  • Supported HTTP Versions == “HTTP/2, HTTP/1.1, HTTP/1.0”
  • Default Root Object , leave as blank, only needed when our website is hosted in S3 bucked
  • Logging = Off
  • Enable IPv6 = yes
  • Distribution State = Enabled

Finally verify the setting again and Click Create Distribution. But we will get  below error.

Copy to Clipboard

The error basically means that, in order to use our domain names in CNAME filed, we need to Issue SSL certificate for our domains using “AWS Certificate Manager” by clicking on ” Request or Import a a certificate with ACM”. This will open a “AWS Certificate Manager” console and from their purchase SSL. The SSL issues through ACM is free of cost. Once the certificate is issued ( Normally it will be issued with in 15Min).

For more details about how to purchase SSL with “AWS Certificate Manager”, refer our below blog article.

  • After that Go back to cloudfront “Distribution Settings” section and  choose “SSL Certificate” as ” Custom SSL certificate”
  • Choose our certificate from the box.
  • “Custom  SSL Client support” as “Clients that Support Server Name Indication(SNI)”
  • Security Policy as ” TLS1.2_2019″
  • Leave other settings as it is and click on “Create Distribution” again.

Initially we can see the cloudfront in progress status and after few minutes we can see the status as “Deployed” and ready to use. Now we want to alter our distributions behaviour for different paths.

  • For that click on CloudFront Distributions
  • Select the created cloudfront distribution >> Click “Distribution settings”

  • Click “Behaviour” tab >> Click create New behaviour and we need to disable cache for below wordpress urls.

/wp-login.php
/wp-admin/*
/wp-json/*
/contact/ (Replace this url with your own contact form url)
/.well-known/*
/wp-cron.php
/xmlrpc.php
/wp-trackback.php
/wp-signup.php

  • We need to create  new behaviour for each of above listed wordpress urls from the “create behaviour” window.
  • Path pattern = Give our url like /wp-login.php
  • Origin or Origin Group = Choose our EC2 instance name available.
  • Viewer Protocol Policy = Redirect HTTP to HTTPS
  • Allowed HTTP Methods = GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
  • Leave “Field-level Encryption Config” as blank.
  • Cached HTTP methods Choose “Options” too
  • Choose “Cache and Origin Request Settings” as “Use a cache policy and origin request policy”
  • Choose Cache Policy as “Custom-managed-Cache-Policy”, this is the one we created at the time of Default Distribution creation time.
  • Now for the “origin Request Policy” click on “Create a new policy”
  • A new window will appear, from there create a new policy named ” Custom-header-Passed-NoCache”
  • Select “All headers” from header field
  • Select “All” from “Cookies” and “Query String”
  • Save the policy and go back to the “create behaviour” windows and click  refresh button next to the “origin Request policy”
  • Choose our newly created policy.
  • Choose “Smooth Streaming” and “Restrict Viewer Access(Use Signed URLs or Signed Cookies) as “No”
  • Choose ” Compress Objects Automatically” as “Yes”.
  • Leave other settings as it is and Save it.

  • Repeat the above steps for each url path pattern. Once completed, the behaviour tab will look like below.

By doing that we exclude above WordPress related urls from cached by cloudfront. We don’t need our wp-admin area and other links mentioned above to be cached by cloudfront because caching above url patterns will cause issues to the proper working of a WordPress website.

Finally, once we done the cloudfront setup,go to our DNS section and create a CNAME pointing www.example.com or example.com at your CloudFront Distribution DNS endpoint. Also don’t forget to delete the existing DNS A records from making conflicts.

If you are using Route53 as your DNS zone manager. If try to change the record type as CNAME for existing DNS A record type and input the CloudFront Distribution DNS endpoint name. We will get below error.

Copy to Clipboard

In order to fix this, We need to choose the Record Type as ” Alias to Cloud Distribution” and then gave the CloudFront Distribution DNS endpoint name. The CloudFront Distribution Domain name is the one we need to use at CNAME record. Usually it will look like d67t9bane84567qtqu.cloudfront.net.

Wait for completing the DNS propagation and if we test the domain using curl, we can see “Server: CloudFront”.

Copy to Clipboard

Use WordPress Cache Plugin

Now lets proceed with the Use of a Cache Plugin that support CloudFront. When we use WordPress plugin related to CloudFront for site acceleration, the plugin uses a subdomain, also known as an alternate domain name or CNAME, to send your website’s traffic through CloudFront.

Without this plugin, all the traffic of your website’s viewers goes to the server that hosts your WordPress website. So lets get started. Lets use a Plugin named W3TC.

Setting Up W3TC

  • Log in to the WordPress administration panel.
  • Browse to the “Plugins” menu page and ensure that the “W3 Total Cache” plugin is installed. If not install it.
  • Activate the plugin by clicking the “Activate” link.
  • Browse to the “Performance -> General Settings” page.
  • In the “CDN” section, enable “CDN” and set the “CDN Type” field to “Generic Mirron”. Click the “Save Settings and Purge Caches” button.
  • Browse to the “Performance -> CDN” page.
  • In the “Configuration: Objects” section
  • In the “Replace Sites Hostname” filed with your own domain name. Click On “Test Mirror” Button and Make sure we get Passed message. Save the settings.

This Concludes the Setup of CloudFront with a WordPress Website. Leave your thoughts at at below comment box.