Search code examples
amazon-web-servicesamazon-s3amazon-cloudfronthttp-status-code-403

Access Denied (403) with ordered cache in Cloudfront s3 distribution


I am trying to add multiorigin setup with cloudfront with ordered cache behaviour. Here is what i want to achieve(given my baseurl is https://example.com/

  1. https://example.com/ shows index.html from root bucket.(root_app)
  2. https://example.com/app2 shows index.html from another bucket (app2)

For this, I created a CF s3 distribution with two origins (root, app2) pointing to two different buckets. In the cache behavior, I have created ordered cache behavior to route all traffic with path "app2*" to app2 origin.

With this setup https://example.com/ is landing me to root_app but https://example.com/app2 is throwing below error

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>E1C4FA78C620F166</RequestId>
<HostId>nwVnR036HRHWVwiQoEoJQaj9A/Mf975SUYOoiYrgX8JasQCEWRrEeNTvBM5y327gZzcfCLksCDY=</HostId>
</Error>

I see below http response headers in the browser for above request

content-type: application/xml
date: Sun, 06 Sep 2020 06:34:06 GMT
server: AmazonS3
status: 403
via: 1.1 45645ff3269a2b885ffa1653e827d0f7.cloudfront.net (CloudFront)
x-amz-cf-id: vVTtxpNxuilWppQ2mskMvN-p7fbNBM8DqHvVYQMYV8-kH-4GVtRHNw==
x-amz-cf-pop: SFO20-C1
x-cache: Error from cloudfront

Any idea what's wrong with this flow?


Solution

  • The problem is how CloudFront routing works. When there is a request to example.com/app2, then it forwards the request to <bucket2>/app2 instead of <bucket2>. You see this error because it's not the index.html you'd expect.

    You can move the files in bucket2 into an app2 folder and then change the path pattern to /app2/*. This way the request to example.com/app2/ will go to <bucket2>/app2/ which is where your files are.

    Alternatively, you can use Lambda@Edge to rewrite the origin request path for every request going to bucket2. I wrote an article how to solve a similar case.