2

I have an AWS S3 bucket; let's call it example.com. I have the bucket configured for static web site hosting; the bucket static site URL for example might be http://example.com.s3-website-us-west-1.amazonaws.com. I also have a CloudFront distribution with an AWS-managed certificate, so that when I access https://example.com/ for example it serves content out of the S3 bucket http://example.com.s3-website-us-west-1.amazonaws.com/. That all works like a dream.

On my site I have a file https://example.com/foo.html that has been renamed to https://example.com/bar.html. Some other pages on the web may link to foo.html, so in my S3 bucket configuration I set up a redirect for the foo.html object, like this:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>foo.html</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith>bar.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

When I try to browse to http://example.com.s3-website-us-west-1.amazonaws.com/foo.html, it sends an HTTP 301 permanent redirect to bar.html, so I wind up at http://example.com.s3-website-us-west-1.amazonaws.com/bar.html, just like I expect.

So now I deploy the S3 bucket to a CloudFront distribution as explained above. After the CloudFront status shows "Deployed", I browse to https://example.com/foo.html, expecting to be redirected to https://example.com/bar.html. Oh, no; I am directed to http://example.com.s3-website-us-west-1.amazonaws.com/foo.html insetad!

Why is the CloudFront distribution redirecting me back to the literal S3 bucket URL? Why doesn't the object redirect to a relative object in the same bucket being correctly deployed to CloudFront?

Note that I am aware of the other question AWS Cloudfront redirecting to S3 bucket, but that does not appear to be a duplicate question of this one, as the other question is referring to the entire CloudFront site temporarily redirecting to the entire S3 bucket, not the failure of an individual S3 object redirect to be deployed to CloudFront.

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

1 Answers1

3

First of all, CloudFront doesn't follow redirection from origin and it received the response from S3 and it served it to the client as it is. S3 is sending this response because in S3 redirect rules, you also need to specify the HOST value.

e.g:

<HostName>...</HostName>

You can define hostname as the name example.com ot https://example.com, The hostname to be used in the Location header that is returned in the response.

https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html

Note: Remember to clear the cache before you make changes and test again, cloudfront also caches 3xx response.

James Dean
  • 4,033
  • 1
  • 9
  • 18
  • 1
    This seems to work, thank you! At least the bucket is now redirecting to the CloudFront distribution. I'll have to wait for CloudFront to propagate to see if it works when from CloudFront itself. I had seen `HostName` in the documentation but it had said it was optional, so I thought if I left it out things would "just work". Speaking of "just working", I know that an S3 bucket static web site will redirect from `foo` to `foo/` for a collection (directory) URL, and this works from the bucket and from CloudFront without mixing the two. Why can't routing rules work the same way? – Garret Wilson Oct 27 '19 at 16:04
  • James Dean, using `` seemed to work But I just now noticed: if I browse to `https://example/com/foo.html`, CloudFront first redirects to the _insecure_ `http://example/com/bar.html`, which then redirects to `https://example/com/bar.html` using HTTPS. Have you seen the same behavior, and do you have any idea on how to make the redirect go directly to the HTTPS version? – Garret Wilson May 09 '20 at 23:22