1

I have a website that I would like the www-prefixed version to redirect to the bare domain.

After searching for different solutions, I found this closed topic here with this answer that seems to work great: https://stackoverflow.com/a/42869783/8406990

However, I have a problem where if I update the root object "index/html" in my S3 bucket, it can take over a day before Cloudfront serves the new version. I have even manually invalidated the file, and while that updates the "index.html" file correctly, Cloudfront still serves the old one.

To better explain, if I type in: http://mywebsite.com/index.html, it will serve the new version. But if I type in http://mywebsite.com/, it serves the old index.html.

I went ahead and added "index.html" in the Default Root Object Property of my Cloudfront distribution (for the bare domain), and it immediately worked as I wanted. Typing in just the domain (without adding /index.html) returned the new version.

However, this is in contrast with the answer in the thread I just linked to, which explicitly states NOT to set a "default root object" when using two distributions to do the redirect. I was hoping to gain a better understanding of this "Default Root Object", and whether there is a better way to make sure the root object updates the cached version correctly?

Thank you.

oneleaf
  • 33
  • 4

1 Answers1

0

If you really put index.html/ as the default root object and your CloudFront distribution is pointing to the web site hosting endpoint of the bucket and it worked, then you were almost certainly serving up an object in your bucket called index.html/ which would appear in your bucket as a folder, or an object named index.html inside a folder named index.html. The trailing slash doesn't belong new there. This might explain the strange behavior. But that also might be a typo in your question.

Importantly... one purpose of CloudFront is to minimize requests to the back-end and keep copies cached in locations that are geographically near where they are frequently requested. Updating an object in S3 isn't designed to update what CloudFront serves right away, unless you have configured it to do so. One way of doing this is to set (for example) Cache-Control: public, max-age=600 on the object metadata when you save it to S3. This would tell CloudFront never to serve up a cached copy of the object that it obtained from S3 longer than 600 seconds (10 minutes) ago. If you don't set this, CloudFront will not check back for 24 hours, by default (the "Default TTL").

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

This only works in one direction -- it tells CloudFront how long it is permitted to retain a cached copy without checking for updates. It doesn't tell CloudFront that it must wait that long before checking. Objects that are requested infrequently might be released by CloudFront before their max-age expires. The next request fetches a fresh copy from S3.

If you need to wipe an object from CloudFront's cache right away, that's called a cache invalidation. These are billed $0.005 for each path (not each file) that you request be invalidated, but the first 1,000 per month per AWS account are billed at $0.00. You can invalidate all your files by requesting an invalidation for /*. This leaves S3 untouched but CloudFront discards anything it cached before the invalidation request.

The default root object is a legacy feature that is no longer generally needed since S3 introduced static web site hosting buckets. Before that -- and still, if you point CloudFront to the REST endpoint for the bucket -- someone hitting the root of your web site would see a listing of all your objects. Obviously, that's almost always undesirable, so the default root object allowed you to substitute a different page at the root of the site.

With static hosting in S3, you have index documents, which work in any "directory" on your site, making the CloudFront option -- which only works at the root of the site, not anywhere an index document is available. So it's relatively uncommon to use this feature, now.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • Thanks for the response. I actually did make a typo. In my Cloudfront settings, I put in "index.html" without the trailing slash. I still wonder why my invalidation did not work though. Despite doing an invalidation on index.html, I was unable to get it to load the new index.html file even after 12 hours. Unless I explicitly typed in index.html into the url. So weirdly enough, putting in the default root object actually solved my problem. – oneleaf Aug 03 '17 at 03:58
  • @oneleaf Oh I see the problem, then... you needed to invalidate `/`, not `/index.html` (the console silently adds a leading slash when sending the invalidation, if it isn't included, so that would be the same as invalidating `index.html`). Invalidation is against what the browser requested, not what may have been actually served, in cases where they differ. – Michael - sqlbot Aug 03 '17 at 11:59
  • thanks so much! That worked. I just removed the Default Root Object setting on my distribution. Did an update. Created an invalidation at /, and it instantly reflected the change. So glad to get this mystery sorted out! – oneleaf Aug 03 '17 at 17:34