For a project, we are using AWS CloudFront to host and serve static files like images and CSS. These assets are deployed to CloudFront through AWS Codepipeline. But, Cloudfront caches these assets to serve them faster through their Edge locations. The cache refreshes once every 24 hours and that means the newly deployed assets aren't immediately available.
Solution
Overview
To address this problem, we'll set a Lambda function that creates Cloudfront invalidations and hook that lambda to CodePipeline so that whenever a new deployment occurs, the Cloudfront cache get's flushed and the new changes are immediately available.
Lambda function
To make this work, we'll set up a Lambda function that uses Boto3 to create the CloudFront invalidation. Here's a very basic Python code that consists of two parts:
- creates the CloudFront invalidation for the given distribution;
- indicates to CodePipeline that the execution was successful.
import boto3
import time
cf = boto3.client('cloudfront')
pipeline = boto3.client('codepipeline')
DISTRIBUTION_ID = "XXXX"
def create_invalidation(event, context):
# create the invalidation
res = cf.create_invalidation(
DistributionId=DISTRIBUTION_ID,
InvalidationBatch={
'Paths': {
'Quantity': 1,
'Items': [
'/*'
]
},
'CallerReference': str(time.time()).replace(".", "")
}
)
# declares the Codepipeline job as successfully executed
response = pipeline.put_job_success_result(
jobId=event['CodePipeline.job']['id']
)
return response
You can copy-paste the below code directly into AWS Lambda while keeping in mind the following:
+ assign your distribution id to the DISTRIBUTIONID variable;
+ make sure to rename your Lambda handler to `createinvalidation` (or rename it within the code);
+ make sure your Lambda role has access to CodePipeline PutJobSuccess action.
CodePipeline
Once you have your Lambda ready, you need to create an action within your pipeline so that it's triggered upon deployment. To do that, you go to your pipeline > >
Add Action > select AWS Lambda under Action Provider, select your lambda, and fill in the rest (artifacts don't matter for this action). Once you have that set, your lambda function will be triggered upon deployment and a new invalidation will be created for you. Job done!