I'm having some difficulties setting up static website hosting using Amazon S3 and Cloudfront.
We have many websites that we would like to serve as static websites using Amazon S3 + Cloudfront and we would prefer to host them all in a single S3 bucket.
Initial setup is pretty straight forward but we are having issues with sub-folder redirects if omitting trailing slash in the URL.
example, setting up a single website from the bucket:
bucket contents for website1:
I have enabled static website hosting for this bucket with default document set to 'index.html'
I have created a Cloudfront web distribution to serve this single website, default root object is set to 'index.html'.
The distribution has a custom origin pointing to the static website url 'bucket-name.s3-website-us-east-1.amazonaws.com' with Origin Path set to '/websites/website1'
When navigating to the distribution url 'http://example.cloudfront.net' it correctly serves the 'index.html' document from 's3://bucket-name/websites/website1/index.html'
When navigating to 'http://example.cloudfront.net/about/' it also correctly serves the 'index.html' document from 's3://bucket-name/websites/website1/about/index.html'
But, if I omit the trailing slash like 'http://example.cloudfront.net/about' S3 redirects me to 'http://example.cloudfront.net/websites/website1/about/', since I have Origin Path set to '/websites/website1' Cloudfront will request index.html from 's3://bucket-name/websites/website1/about/websites/website1/about/index.html' which does not exist.
Am I missing something here? Is this an impossible setup using only Cloudfront and S3?
I ended up solving it by using routing rules for the S3 bucket
the problem is the redirect caused by omitting a trailing slash results in the Orgigin Path being appended to the full S3 bucket path ("example.cloudfront.net/about" redirects to "example.cloudfront.net/websites/website1/websites/website1/about/" that fails because the path is invalid)
The below routing rule solves this by triggering on the faulty path pattern prefix and redirecting back to the Cloudfront distribution with the prefix stripped from the request, i.e ("example.cloudfront.net/about" redirects to "example.cloudfront.net/websites/website1/websites/website1/about/" that redirects to "example.cloudfront.net/about/")
The downside is that you need to remember to modify the routing rules when adding new distributions
<RoutingRules> <RoutingRule> <Condition> <KeyPrefixEquals>websites/website1/websites/website1/</KeyPrefixEquals> </Condition> <Redirect> <HostName>example.cloudfront.net</HostName> <ReplaceKeyPrefixWith></ReplaceKeyPrefixWith> </Redirect> </RoutingRule> </RoutingRules>