Posted on 2 August 2021
If you're using a static site generator, you may encounter issues when serving your S3 static site in combination with CloudFront (access denied, 404s where you don't expect them, etc.). An example of what we were seeing on this very site, when a URL didn't end in "/" (denoting that it was a directory) S3 would return a 403 to Cloudfront:
Returns 403:
/post/2021-07-31/1-how-to-deploy-to-multiple-aws-regions-in-laravel-vapor
Returns expected content (200):
/post/2021-07-31/1-how-to-deploy-to-multiple-aws-regions-in-laravel-vapor/
We fixed this by utilising Lambda@Edge, a feature of CloudFront that allows us to modify the behaviour of CloudFront.
In the AWS console, navigate to Cloudfront and choose "Functions" from the sidebar menu.
Click "Create function". Give the function a name (e.g. static-website) and click "Create function" again.
Replace the code in the "Development" tab with the following:
function handler(event) {
var request = event.request;
if (request.uri.match(/\.[0-9a-z]+$/i)) {
// The uri is for a file e.g. *.png, *.css, etc.
return request;
}
if (request.uri.endsWith('/')) {
// The uri ends in '/' - add 'index.html'.
request.uri = `\${request.uri}index.html`;
} else {
// The uri ends doesn't end with '/' - add '/index.html'
request.uri = `\${request.uri}/index.html`;
}
return request;
}
Don't forget to save your changes! Click "Save changes".
Switch to the "Publish" tab and click "Publish function". You should now see a new area below the button just clicked called "Associated distributions".
Click "Add association". A modal popup should appear, in the fields that appear enter the following:
Complete the set up by clicking "Add association". This should take effect quite quickly, around 5 minutes at the most.