Should I handle this at CloudFront or S3 level?
There are currently no global settings for adding custom HTTP headers to either Cloudfront or S3. To add http headers to objects, they must be set in S3 separately for 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.
As a rule, it is easiest to set headers when adding an object to a bucket - the exact mechanism for this depends on which client application you are using, or sdk.
eg. with the aws cli command, you use the --cache-control
option:
aws s3 cp test.txt s3:
To modify existing objects, the s3cmd
utility has a modify
parameter, as described in this SO answer: fooobar.com/questions/144234 / ...
Or you can use the aws s3 command to copy objects back to yourself by changing metadata as described in this SO answer: fooobar.com/questions/83951 / .... for example, replace metadata with 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 be invalidated
This is a pretty strict requirement - you cannot prevent the cloud cloud cache from becoming invalid. That is, there is no installation that will prevent Cloudfront from being created if the user creating it has sufficient permissions. Thus, in a workaround, you can prevent invalidation by not allowing users, roles, or groups to have permission to create invalidation in the distribution using cloudfront:CreateInvalidation
IAM permission may not be practical.
However, there are several reasons why Cloudfront may choose to invalidate the cache in violation of the backend management cache โ for example, if the Maximum TTL parameter is set and is less than the maximum.