Whenever I make a change to my S3 bucket my CloudFront doesn't update to the new content. I have to create an invalidation every time in order to see the new content. Is there another way to make CloudFront load the new content whenever I push content to my S3 bucket?
Let me answer your questions inline.
Whenever I make a change to my S3 bucket my CloudFront doesn't update
to the new content. I have to create an invalidation every time in
order to see the new content.
Yes, this is the default behavior in CloudFront unless you have defined the TTL values to be zero (0).
Is there another way to make CloudFront load the new content whenever
I push content to my S3 bucket?
You can automate the invalidation using AWS Lambda. To do this;
Create an S3 event trigger to invoke a lambda function when you upload any new content to S3.
Inside the Lambda function, write the code to invalidate the CloudFront distribution using AWS CloudFront SDK createInvalidation method.
Note: Make sure the Lambda function has an IAM Role with policy permission to trigger an invalidation in CloudFront.
You have created the S3 origin with cache settings or you have added cache headers to your S3 bucket policy.
If you check your browser request you can check on the cache headers and why it is getting cached.
You can find a list of http cache headers and how they are used here
Hope it helps.
Cloudfront keeps cache at edge points for minimum of one hour.
What you can do, as suggested by the docs, you can use versioned files.
BUT :
New versions of the files for the most popular pages might not be served for up to 24 hours because CloudFront might have retrieved the files for those pages just before you replaced the files with new versions
So I guess your best bet is invalidation.
EDIT: you can prevent the caching behaviour of versioned files if you change their names.
Related
I stumbled upon this AWS blog while doing some research about adding HTML headers to S3 objects served via CF:
https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/
Apparently, we can create lambda#edge to update headers of all objects before it reaches CF cache. But, I have been doing something similar where I update S3 object metadata with headers, something like:
aws s3 cp --content-type 'text/html' --cache-control 'no-cache' s3://my_bucket/index.html s3://my_bucket/index.html --metadata-directive REPLACE
This basically copy and paste the same object to add HTTP headers to my specified objects without using lambda to modify in-flight.
So is there any difference between hardcoding headers to S3 objects and using lambda#edge to modify origin response?
It is just easier to use the Lambda #Edge to have one central place where you can maintain the headers. For example you can set your caching headers as well as your security headers in the Lambda #Edge and if you have to add or change it you just need to update the Lambda, give it a new version and deploy it to Cloud Front.
Is it possible to protect data embedded on my website via Amazon CloudFront from hotlinking or other downloads? I am mainly interested in protecting webfonts from being downloaded.
Amazon CloudFront is connected to a S3 Bucket
S3 Bucket Policy controls allowed domains for files via CloudFront
You think that could work?
Since you have cloudfront setup connected to your s3 bucket, you can use Cloudfront Signed Urls to prevent download by anyone from the public.
You can put your fonts in a folder called fonts for example, and setup a separate behaviour in cloudfront for any path that contains /fonts/ and in there you can activate Restrict Viewer Access.
In your website, you will need to add some way to generate the presigned url for this only when your webpage is loaded and you can put a short expiry time for this URL.
I am using Amazon CloudFront with the files coming from Amazon S3. I wasn't originally setting the Amazon S3 Metadata to send a Cache-Control header, but I changed it a few weeks ago. Most of the images are showing with the new header. However, I have some that still do not.
For example if I hit this
https://s3.us-east-2.amazonaws.com/channelnet-useast-prod/Themes/Default/Images/phone.png, I see
Cache-Control:max-age=86400
But if I go to the CloudFront URL that points to that S3 image
http://dfb8oqhjho7zs.cloudfront.net/Themes/Default/Images/phone.png, I do not.
As a test, I made a copy of the image, uploaded it to S3, set the Cache-Control header, and verified the header is set when I access it via S3
https://s3.us-east-2.amazonaws.com/channelnet-useast-prod/Themes/Default/Images/phone-matttest.png
or CloudFront
http://dfb8oqhjho7zs.cloudfront.net/Themes/Default/Images/phone-matttest.png
How do I get CloudFront to refresh whatever Amazon-side caching is going on here?
You need to clear/invalidate the CloudFront cache so that it will check your origin for updates.
We are porting a website to a AWS cloudfront backed infrastructure which serves static resource from an S3 bucket.
We access the resource like this
http://example.com/static/foo.css?hash=1
Our CMS generates a new hash when the files changed (cachebusting).
So we upload the file foo.css to the S3 bucket and access
http://example.com/static/foo.css?hash=2
But still the old contents are displayed. It seems to be cached in cloudfront?
Can this be avoided?
Or does the cms need to be modified?
You have to configure your CloudFront distribution to forward query parameters and use them as part of the cache key. Documented here.
I have a S3 bucket on top of which there is CloudFront CDN.
This S3 bucket is "immutable", which means that once I upload a file there, I never delete it or update it. It is then safe that all clients cache the files coming from S3/CloudFront very aggressively.
Currently, Etags are working great, and clients hit 304 responses most of the time. But getting a 304 response still involve a roundtrip that could be avoided by more aggressive caching.
So I'd like this behavior:
CloudFront CDN cache should never get invalidated, because S3 cache never changes. CloudFront does not need to ask again S3 for a file more than once. I think I've successfully configured that using CloudFront distribution settings.
CloudFront should serve all files with header Cache-Control: max-age=365000000, immutable (immutable is a new, partially supported value as of 2016)
I don't understand how can I achieve the desired result. Should I handle that at CloudFront or S3 level? I've read some stuff about configuring appropriate header for each S3 file. Isn't there a global setting to serve all files with a custom http header that I could use?
Should I handle that at CloudFront or S3 level?
There is currently no global setting for adding custom http headers either in Cloudfront or in S3. To add http headers to objects, they must be set in S3, individually on each object in the bucket. They are stored in the object' metadata - and can be found in the Metadata section for each object in the AWS S3 Console.
Typically, it's easiest to set the headers when adding the object to the bucket - the exact mechanism for doing so depends on which client app you're using, or sdk.
e.g. with the aws cli command you use the --cache-control option:
aws s3 cp test.txt s3://mybucket/test2.txt \
--cache-control max-age=365000000,immutable
To modify existing objects, the s3cmd utility has a modify option as described in this SO answer: https://stackoverflow.com/a/22522942/6720449
Or you can use the aws s3 command to copy objects back onto themselves modifying the metadata, as explained in this SO answer: https://stackoverflow.com/a/29280730/6720449. e.g. to replace metadata on all objects in a bucket:
aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
--cache-control max-age=365000000,immutable
CloudFront CDN cache should never get invalidated
This is quite a stringent requirement - you can't prevent a cloudfront cache from ever getting invalidated. That is, there is no setting that will prevent a Cloudfront invalidation from being created, if the user creating it has sufficient permissions. So, in a roundabout way, you can prevent invalidations by ensuring no users, roles, or groups have permissions to create an invalidation in the distribution using the cloudfront:CreateInvalidation IAM permission - this is possibly not practical.
However, there are a few reasons Cloudfront might choose to invalidate a cache in contravention of the backend's Cache-Control - e.g. if the Maximum TTL setting is set and it is less than the max-age.