I have been hosting my static Hugo generated website on Amazon S3 and serving it using Amazon CDN CloudFront. It works flawlessly except one aspect of CloudFront where it will cause a problem if you enable S3 Bucket Restriction on.
CloudFront only allows you to specify a default root object (index.html), but it only works on the root of the website such as nish.com -> nish.com/index.html. It does not work on any subdirectory such as nish.com/about/. If you were to attempt to request this URL through CloudFront, It would do an S3 GetObject API call against a key that does not exist.
This happens when you enable S3 Bucket Restriction on CloudFront. This will make CloudFront the only user allowed to access the S3 bucket. It will force the user to access the web content only via CloudFront CDN and not directly via S3. This is a neat feature which will stop any DDoS attacks on S3 requests.
The problem is that CloudFront only likes one index.html file. If you have nish.com/index.html then it is fine. The problem happens is when you have .nish.com/blog/how-to-deploy-hugo/index.html.
There are three solutions to fix this problem.
- Turn off CloudFront S3 Bucket Restriction under Origins.
- Enable Default Directory Indexing using Lambda@Edge - More info about this can be found here.
- Turn on uglyurl on Hugo.
The third solution seems to be an ideal one since it involves less work and doesn’t have to involve Lambda@Edge. The only trade-off on using option 3 will enable you to have a page with .html at the end of the URL.