11

I'm trying to do something that should be relatively straight-forward - I want to setup a few domains and subdomains to redirect to the core domain for our site, but I want to put the redirects out on Cloudfront. Everything works except redirecting the root path - that gets me an XML file partly-describing the S3 bucket.

Background

S3

S3 allows you to setup an all-redirect bucket, like:

S3 with Redirect all requests setup

Testing this, the web endpoint (brass9-com.s3-website-us-west-1.amazonaws.com) does what it should - it redirects to brass9.com. Good.

Cloudfront

Cloudfront lets you point at an S3 bucket, but the way it suggests you do so is wrong - instead of pointing at the bucket by its name, like brass9-com.s3.amazonaws.com, you need to use the Web Endpoint above. Other than that you can leave everything at its defaults and get good redirect behavior. So, a path like www.brass9.com/portfolio properly redirects to where it should. Also good.

The problem - the root domain redirect

The one thing that then fails to work is redirecting from plain www.brass9.com. Instead of getting you a redirect it gets you this odd result:

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>brass9-com</Name><Prefix></Prefix>
<Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated>
</ListBucketResult>

OK... . So this is not completely unexpected - because there's no Default Root Object. But what Default Root Object would I possibly specify to prevent this behavior? What is the name of the S3 redirect object, if any, that I need to point to? Or is there some other proper config, or is this just a bug in how Cloudfront and S3 interact that Amazon needs to fix?

Known Not-Working Solution: Default Root Object

It is possible to specify a Default Root Object of index.html, but it doesn't help any - it just changes the problem. The Cloudfront url instead redirects to /index.html on the main site, which is a 404 (we don't use an index.html file, it's a server-side framework driven site). I could put an index.html on the server, but that defeats the small speed gain of using Cloudfront in the first place.

Similar questions

One question asks something similar but gets back a blank, 0-byte response for some reason instead of what I'm seeing, an XML response. It doesn't include a question about that problem or a resolution.

Related articles

One article proposes you just serve the entire site out on both the bare and www domain. This screws with any user's bookmarks, your search ranking, etc, etc. You should not do this.

Several discuss hosting a static website on S3 and Cloudfront rather than a redirect scheme, and so are unrelated.

So, how do I do this properly?

Screenshot of Cloudfront Configuration - no Default Root Object, pointing at S3 origin. Ignore the InProgress - I had just toggled Default Root Object on and off to test.

Cloudfront Distribution with no Default Root Object pointing at S3

And the Origin config for that Distribution:

Origin - points to S3, defaults

Chris Moschini
  • 469
  • 1
  • 8
  • 16
  • 1
    Any request to a web site end point configured to redirect everything "should" do exactly that, including the root. Do you have a bucket policy on that redirecting bucket? It sounds as though you might, but you shouldn't. Also sounds a bit like you could have been seeing a cached response from Cloudfront for `GET /` from before you corrected your config to use the web endpoint. – Michael - sqlbot Jul 08 '14 at 10:23
  • 1
    It was in fact a cached ListBucket response still lingering in S3, even though I had invalidated and changed CF's config multiple times. It just takes an hour or 4 to clear out. @Michael-sqlbot If you post your comment as an Answer I can mark it as Accepted. – Chris Moschini Jul 11 '14 at 05:23

3 Answers3

7

If you have this issue, check first when you configure the s3 bucket origin for the cloudfront, the autocomplete returns the s3 REST endpoint domain.amazonaws.com which return this ListBucketResult response.

You have to write down manually the website endpoint domain.s3-website-region.amazonaws.com

Important: If you have wrongly configured cloudfront with the REST endpoint you have to invalidate the cache through Invalidations or it will keep returning the REST response

lapinkoira
  • 171
  • 2
  • 7
  • 1
    The note about cache invalidation finally helped me solve a problem I've chased for several days. Thank you! – Nate Oct 27 '18 at 19:09
  • 1
    Thanks a lot! For Terraform users, in the `origin` block of the distribution, use `aws_s3_bucket.BUCKET.website_endpoint` in the `domain_name` (not `bucket_regional_name`) and add the `custom_origin_config` block. – dusan Jan 15 '19 at 16:01
  • You are a lifesaver! We've been struggling with this problem for the last day, kept getting ListBucketResult XML back even though we were changing the distribution settings. Finally after deleting the distribution and creating a new one pointing to domain.s3-website-region.amazonaws.com the redirect worked for us! – Dale Zak Nov 25 '19 at 23:22
  • thanks, very helpful! – Walter Silva Jun 22 '21 at 11:34
2

Solution: Setup the Redirect as stated in the question then wait out the S3 and CloudFront cache times. They can be 4 hours or more, so you just have to set it all up then wait and hope for the best.

(This is Michael's solution from the Comments, but it's now been years and this really deserved to be marked as Answered).

Chris Moschini
  • 469
  • 1
  • 8
  • 16
0

Writing as answer since I can't comment - from the documentation at http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/DistributionConfigDatatype.html#DistributionConfigDatatype_Elements it seems you can have a blank default root object:

If you don't want to specify a default root object when you create a distribution, include an empty DefaultRootObject element.

Dani_l
  • 498
  • 2
  • 8
  • You can (although some API libs forbid it) - but using a blank Default Root Object gets me the ridiculous ListBucketResult XML response you see in my Question. – Chris Moschini Jul 08 '14 at 06:29