Automate CloudFront Catch Invalidation Using CodePipeline and Lambda

Every time I start a new coding project, I like to set up my CI/CD(Continues Integration and Continues Delivery) to easily deploy my code to my two environments(DEV and PROD). However, every time I forget to set an extra step on my CodePipeline to invalidate the catch on my CloudFront distribution, for this reason, I decided to write this post. This is a reminder for me to not forget this step and also the how-to implementation.
Since I am going to be talking about how to automate the invalidation process only, I would assume you already have your CodePipeline and your CloudFront distribution in place.
Step 1: Create a lambda function.
Click on create a function.

Lambda function basic configuration.
Function name: angular-todo-app-catch-invalidation-dev
Runtime: Python 3.7
I like to stick to this name on convention.
stack-app-name-action-environment.
For the runtime, we will be using Python 3.7.

Step 2 Give our lambda function the necessary permissions
Click on configuration.

Click on Edit under Execution role.

Right at the bottom, there would be a link with the role name, click on it.

Here we need to change our permissions policies by clicking on the policy name link in blue.

Here we click on the Edit policy button and paste this JSON object.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:*"
],
"Effect": "Allow",
"Resource": "arn:aws:logs:*:*:*"
},
{
"Action": [
"codepipeline:AcknowledgeJob",
"codepipeline:GetJobDetails",
"codepipeline:PollForJobs",
"codepipeline:PutJobFailureResult",
"codepipeline:PutJobSuccessResult"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetDistribution"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
This JSON policy will give read and write permissions to our Lambda function for CodePipeline and CloudFront.
We can check that under Resource summary.

Step 3 Write Lambda function
import boto3import timedef lambda_handler(event, context): allFiles = ['/*'] client = boto3.client('cloudfront') invalidation = client.create_invalidation( DistributionId = 'CloudFront ID', InvalidationBatch={ 'Paths': { 'Quantity': 1, 'Items': allFiles },
'CallerReference': str(time.time()) }) pipeline = boto3.client('codepipeline') job_id = event['CodePipeline.job']['id'] return pipeline.put_job_success_result(jobId = job_id)
Since the code is very self-explanatory, I won’t go over it. Just make sure to get your CloudDistribution ID and replace it on the code. You can get your ID by going to CloudFront. It is in blue under the ID column.

Go over the code tab

Select the lambda_function.py file and paste the code. Also, click on deploy.

Step 4 Add a step on our CodePipline that triggers this function after the code has been depoloyed
Go CodePipeline and select the pipeline you wish to add the invalidation step.
Now click on the edit button

You need to add this step after the deploy step so let’s click on the Edit stage button for this step.

Now click on Add action group

Give it a name in my case is “CloudFront-Invalidation”
Action provider: AWS Lambda
Region: US East (Ohio) or the region where you create your function.
Function name: angular-todo-app-catch-invalidation or the name you gave to your function.
Finally, click on Done

After that scroll up to the top of the page and click on the Save button.

Conclusion
I hope you like this tutorial on how to automate your CloudFront catch invalidation using CodePipeline and Lambda.