Photo by JJ Ying on Unsplash

AWS: Creating a CloudFront Invalidation in CodePipeline using Lambda Actions

Jacob Unna
FullStackAI
Published in
4 min readJul 7, 2021

--

A simple way to host a website consisting of static files on AWS is to put the files in an S3 bucket and distribute them using CloudFront. When a user visits the website, a given file will be served by CloudFront if it is cached; otherwise it will be served from S3.

One model for pushing changes to a website with this setup is to use CodePipeline. The steps are:

  • The developer makes a change and pushes it to the source code management platform (SCM);
  • CodePipeline detects the change and imports the data from the SCM;
  • Optionally, CodePipeline can use CodeBuild to compile the code, which would be necessary for, say, a React app;
  • CodePipeline puts the files into the S3 bucket.

There is a problem, however. The user is retrieving artifacts from CloudFront, not S3. At best this means that the user will not see your changes until some time after you deploy them. At worst, they will be served artifacts from different releases that are mutually incompatible.

Lambda actions

Lambda actions invoke a lambda function as part of a stage in CodePipeline. Using a lambda action, we can add an extra stage to CodePipeline that creates a CloudFront invalidation.

What follows is a step by step guide for adding such a lambda action to a pipeline.

Step 1: Create the lambda function

We will use Python as the lambda function runtime. Create a lambda function with the following settings and click “Create function”.

Step 2: Add code

The following code uses the AWS Python SDK, boto3, to:

  • Create a CloudFront invalidation;
  • Catch any exceptions and inform CodePipeline that the job failed;
  • Otherwise, inform CodePipeline that the job succeeded.

Paste this code into lambda_function.py in the newly created lambda function and click “Deploy”.

Step 3: Assign permissions

Under “Configuration” and then “Permissions”, click on the lambda function execution role name.

Click on the policy assigned to this role.

Click “Edit policy”.

Choose the “JSON” tab and add the following statement:

{
"Effect": "Allow",
"Action": [
"codepipeline:PutJobFailureResult",
"codepipeline:PutJobSuccessResult",
"cloudfront:CreateInvalidation"
],
"Resource": "*"
}

Click “Review policy”.

Click “Save changes”.

Step 4: Add a new stage

Add a stage to the pipeline.

Call it, say, “Invalidate” and click “Add stage”.

Step 5: Add an action to the stage

Click “Add action group”. Specify the action name as “Invalidate” and the provider as “AWS Lambda”. Under “Function name”, choose the function you created in Step 1.

We also need to pass something in the “User parameters” field. These parameters specify which CloudFront distribution to invalidate and which paths to invalidate within the distribution. To invalidate everything, specify "/*". This value should be JSON encoded, and will look something like:

{"distributionId": "string", "objectPaths": ["/*"]}

Once you’ve finished, click “Done”.

Step 6: Save changes

Click “Done” for the “Invalidate” stage and then click “Save” for the pipeline.

Discussion

Lambda actions are a powerful tool for adding arbitrary logic to CodePipeline. Creating a CloudFront invalidation is one useful application of lambda action. Of course, there is an endless list of other things they could be used for.

The downside of lambda actions is that you must maintain the lambda function code yourself rather than relying on AWS to manage it. It also potentially increases the severity of an attacker gaining access to your source code management platform. Nevertheless, these downsides will often be outweighed by the benefits of increased automation.

Notice that, even with this setup, any requests made between files being copied to S3 and the CloudFront invalidation completing may fail. For a low to medium traffic website this probably isn’t an issue, but it may be a consideration for high traffic or mission-critical products.

Summary

In this article, we have seen how CloudFront invalidations can be created from CodePipeline.

--

--

Jacob Unna
FullStackAI

Software Engineer @ Deloitte Analytics & Cognitive