Using CloudFront to Accelerate Dynamic Content

Our goal today is simple, accelerate your entire website, and improve the user experience in one fell swoop.

Just a quick note: while I'm using EC2 resources in this article, you can use origins from on on premise location or from another cloud provider.

Create a CloudFront Distribution

Creating a distribution is pretty straightforward, there's just a lot of questions, questions that need answering. Essentially what we're doing is setting the distribution up to forward all HTTP methods and query strings, while setting the default TTL to 0. The full process:

  1. Open the AWS CloudFront console.
  2. Click "Create Distribution".
  3. Select a "Web" distribution type.
  4. Add your ELB or EC2 instance name to the "Origin" domain name field.
  5. Accept the default cache behavior settings for now.
  6. For the viewer protocols, enable both HTTP and HTTPS. Note: If you don't have a certificate, you can request one for verified domains at no cost from Amazon. See my post on the certificate manager.
  7. Make sure that you've enabled all of the allowed HTTP methods. This is needed for your dynamic web application to function normally.
  8. Under object caching, click customize and set the minimum TTL to 0.
  9. Set forward cookies to all. This is likely needed by your dynamic web application to function normally and set cookies to customize content.
  10. Set forward query strings to enabled. You'll need this if you're using request paths like "?var=value".
  11. Leave the restrict viewer access setting to its default of "no".
  12. Leave the price class to the default for best worldwide performance. Otherwise tinker as you'd like.
  13. If you want to use multiple domain names (cnames) for your website, add them to the alternate domain name list.
  14. Set the SSL certificate if you have one (and there's no reason you shouldn't use one, the certificate manager console makes this dead easy).
  15. Leave the default root object alone, unless you know what you're doing and want index.php or index.html as the default root object to avoid your distribution becoming a web directory listing.
  16. Enable logging if desired. You're probably safe to leave it disabled for now. Same with cookie logging.
  17. Set the distribution to enabled.
  18. Create!

It's about a 15 minute wait for the distribution to propagate to all endpoints. #teatime

Make Performance Tweaks to your Distribution

So in the previous step, we created additional endpoints for your web application that can send traffic down optimized Amazon pipes to your origin. This should already increase the speed of your application. But since we set a TTL of 0 all of our static assets are also being pulled each time.

Better plan: cache the static assets so that our origin rarely gets the requests for the static assets.

  1. Select your distribution.
  2. Click the behaviors tab, and then click create behavior.
  3. For the path pattern, give it .css or .js or .jpg, or all of them eventually.
  4. Select the same origin as the one we created that points to our ELB or EC2 instance.
  5. Customize the object caching, and set the minimum ttl to 3600 for an hour of caching, 86400 for a day of caching, 604800 for a week of caching. Prefer shorter so that you don't need to invalidate the cache manually.
  6. Review your settings and click create when ready.

It'll take a few minutes to update globally.

Error handling

In the meantime - do you want to customize the error pages your web application displays? You can do that or set up a failover process for when issues arise.

For this example, I'm going to assume that you have an S3 bucket with static html pages for different errors.

  1. In your distribution, select the origins tab.
  2. Create a new origin.
  3. Select your S3 bucket.
  4. Enable restrict bucket access.
  5. Click create to finalize the origin.
  6. Now we need to create a behavior, go to the behaviors tab, and click create.
  7. In the path pattern, type the path in the S3 bucket to the html file.
  8. For the origin, select the S3 bucket origin we just created.
  9. If you want, tweak the other settings. But you're probably fine with the defaults.
  10. Click create.
  11. Now we need to set the error page configuration so that our distribution knows that you want it to display a custom error.
  12. Click on the error page tab. Click create.
  13. From the HTTP error codes available pick the one you want to customize.
  14. Switch customize error response to yes.
  15. Add the S3 error page path.
  16. Set the HTTP response code. Typically you should keep it the same as the original error code.
  17. Review and customize your settings. Then click create!

And now you have a custom error page for your web application. This is a quick way to override the default wordpress / joomla / drupal / insertyourcmshere's error pages.

Hooking up Route53

This is super easy (assuming you're using Route53 for hosting your domain names). Pull up the Route53 web console, click into the list of hosted zones, select your desired hosted zone, click create record set, change the type to alias, and find your CloudFront distribution.

Bonus points if you set the routing policy to failover and create a secondary record for failure scenarios pointed at S3, with a health check to trigger the failover.