2022 AWS CLI V2 Method
The simplest way to achieve this is to use AWS CLI (S3). This can also be automated entirely for free using a tool like GitHub actions.
A static site should not have the cache-control
set to a long-lived value on HTML
files because the users will not see the updated version until the browser cache expires or manually busts their cache.
Due to AWS CLI
restrictions, you have to do the following to set the cache for the whole bucket.
Generic Example
Upload the content and --delete
old S3 content, and set cache-control
on all content.
aws s3 sync [YOUR_LOCAL_SOURCE_CODE_PATH] s3://[BUCKET_NAME] --delete --cache-control max-age=31536000
Recursively remove cache-control
headers from all HTML
files and set the file back to type HTML.
aws s3 cp s3://[BUCKET_NAME] s3://[TO_BUCKET_NAME] --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html
Notes
- TO_BUCKET_NAME is almost always the same as BUCKET_NAME
- If you modify an
HTML
file's metadata in AWS S3, you must also set the content-type
, or it will automatically be set to a generic type causing the browser to download the file instead of rendering it in the browser.
Example
// delete old files and upload files from the local directory to the s3 bucket, and set the cache-control header on every file.
aws s3 sync ./out s3://www.test.com --delete --cache-control max-age=31536000
// copy all files and remove cache control header from only HTML files and set back to html content type
aws s3 cp s3://www.test.com s3://www.test.com --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html
// bonus - if using CloudFront - small site can invalidate all cache (/*)
aws cloudfront create-invalidation --distribution-id=123ABCDEFG --paths "/*"