Invalidating Cache For a Static Website With S3 and Cloudfront

I am using CloudFront to serve as an edge cache for my static blog, and an issue I faced with that approach is cache invalidation. Whenever I write a new blog post, my statically generated index and tag pages are updated as well, but since CloudFront had already cached them, the new content doesn’t show up till the said cache has expired. This post is about invalidating the CloudFront cache automatically when I upload new content to my S3 bucket. Read my first post on how I set up my statically generated blog.

For my solution, I used AWS Lambdas. I found a python script to call Cloudfront and request invalidations for all the objects that were updated.

from __future__ import print_function

import boto3
import time
import os

def lambda_handler(event, context):
    path = []
    for items in event["Records"]:
        if items["s3"]["object"]["key"] == "index.html":
            path.append("/")
        else:
            path.append("/" + items["s3"]["object"]["key"])
    print(path)
    client = boto3.client('cloudfront')
    invalidation = client.create_invalidation(DistributionId='<some_distribution_id>',
        InvalidationBatch={
            'Paths': {
                'Quantity': 1,
                'Items': path
        },
        'CallerReference': str(time.time())
    })

With that, I created a new Lambda and added S3 as the trigger. Since I wanted it to trigger every time an object was created or updated in my S3 bucket, I chose ObjectCreatedas the event.

And this is how my Lambda interacts with my S3 bucket, CloudFront and CloudWatch.

Now, whenever I upload new objects to my S3 bucket, this Lambda function fires and invalidates the cache of the changed objects. Please note that invalidating CloudFront caches cost money, so this solution might not be super scalable.