Firstly, the point of Cloudfront is to serve cached content - if you try to serve uncached content from Cloudfront it is slower than serving it directly from S3, in almost all cases (something like streaming content would be the exception). Consider for a moment what needs to happen to serve content from Cloudfront - it needs to be retrieved from the origin server to a location that is geographically close to the user - which means that for a request where Cloudfront has to retrieve content from the origin server, you add extra latency into the request, and the user receives content slower. It is only once the content is available at the edge location that subsequent requests are faster.
The best approach to this problem is to change your filenames when you update a page - this will force Cloudfront to retrieve the new content. Again, keep in mind that Cloudfront is typically used for media files (including images) and style/javascript - and not so much for html.
Esssentially, you would have your HTML on S3, and your images on Cloudfront - with any changes you make, you can change the name of the file on Cloudfront (e.g. file-v1.jpg, file-v2.jpg, etc). Another common way is including a query string with version information.
Also, keep in mind that Cloudfront does not serve gzipped content - which may result in a slower response than from a regular server (although, in your case, S3 doesn't identify gzip capable browsers either).
Finally, if you want to, you can use invalidation to force Cloudfront to discard its existing copy and fetch a new one from the origin server. Note, however, that Cloudfront gives you only 1000 free invalidations per month, after which the cost is $0.005/invalidation.
The lowest time Cloudfront will keep content is 1hr, although, the default is 24hr. I'd therefore try to set the max-age to at least 3600. Consider also an s-maxage header (for shared - i.e. proxied content). Amazon recommends this caching tutorial.
There was a recent problem with this, rectified a few days ago
I ran into this problem recently and I found a workaround that seemed to work.
I created a Cloudfront distribution with a custom origin pointing to the S3 static website hostname instead of the bucket hostname. In the OP's case, the desired origin would be.
mysite.s3-website-us-east-1.amazonaws.com
Hitting a Cloudfront distribution just using the bucket as the origin does not work because the bucket does not actually serve redirects. It only serves files and stores metadata.
Hope that helps.
Best Answer
Change your Origin Domain Name from
example-bucket.s3.amazonaws.com
toexample-bucket.s3-website.${region}.amazonaws.com
(substituting your bucket's actual region) so that the S3 redirect rules will work. The default bucket choices in CloudFront are for the REST endpoints of your buckets, which won't process redirect rules.Change the
<Redirect>
block in your redirect rule, so that theLocation
header generated by the S3 redirect sends you to the right hostname (otherwise it would tend to redirect the browser directly to the bucket's website hosting endpoint). Here,www.example.com
is the hostname pointing to your CloudFront distribution.Remove the custom error settings.
Create a CloudFront invalidation for
/*
.Wait for everything to propagate, and retest.