S3 static hosting - path without index.html [dupli

2020-07-08 06:44发布

问题:

We have multiple Angular projects which we like to quickly upload to s3 for QA & testing. We upload all of them to the same bucket, in different subfolders. So the s3 bucket structure is as following:

 -- tests-bucket
    -- project1
       -- index.html
    -- project2
       -- index.html

We then have a cloud front distribution and route53 setup e.g. tests.domain.com.

When accessing the projects via the full path everything works:

tests.domain.com/project1/index.html
tests.domain.com/project2/index.html

However, when we try accessing the project without index.html (tests.domain.com/project1 or tests.domain.com/project1/) we get the following error:

<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>index.html</Key>
<RequestId></RequestId>
<HostId></HostId>
</Error>

This makes it hard for us to test, since after the initial page load, the index.html is automatically removed and any additional reload will lead to a 404 error.

The bucket is set to serve website static hosting and both index and error documents point to index.html.

The CloudFront distribution is also set to have a 404 error path redirect to index.html.

It seems as this setup only works for the root path of the bucket tests.domain.com/index.html but does not support subdirectories.

This AWS article makes it seems possible, but in our case, it does not work with an SPA/Angular application.

From a quick research into this, I found this tutorial which resolves this issue using a Lamda Edge redirect, but the setup seems a bit overkill, plus only seems to support the US East distribution.

Is there any simple configuration that can resolve this, using only s3/cloudfront/route53 which does not involve lambda functions?

回答1:

Yes, you can configure this using the "index-document" property when you're enabling website hosting in your bucket. Check out the CLI documentation here: https://docs.aws.amazon.com/cli/latest/reference/s3/website.html

When you enable this functionality, it will be enabled on every path that doesn't end in a file. So requesting "/project1/" would return "/project1/index.html" if you set your index-document property to "index.html"

More documentation:

https://docs.aws.amazon.com/AmazonS3/latest/dev/IndexDocumentSupport.html

https://docs.aws.amazon.com/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html

EDIT:

When using Cloudfront, the default root object behavior in cloudfront will override the index-document usage from S3. To get around this behavior, don't use a S3 origin, and instead use a custom origin and pass through your S3 bucket URL as the origin domain name.

Documentation:

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html (specifically, "However, if you define a default root object, an end-user request for a subdirectory of your distribution does not return the default root object. For example, suppose index.html is your default root object and that CloudFront receives an end-user request for the install directory under your CloudFront distribution")