Is it possible to use CloudFront Functions with CloudFormation, and have the source code in an external file?


As the title. It looks from like FunctionCode must be inline in AWS::CloudFront::Function which … isn’t ideal for anything non trivial. Maybe just something missing in the docs though?

4 Answers

The short answer to your question is that you cannot reference a CF2 as an external file. It needs to be inlined. As Franky mentioned, you can consider using Lambda@Edge instead. However, if you do want to use CF2, here are a few ways that I have accomplished what you are looking for.

  1. Consider using CDK to dynamically generate your CloudFormation template. This won't allow you to reference your CF2 js code externally in the template, but it will allow you to package your js code into a template at the time of template creation with CDK.
  2. My preferred option is to use CodePipeline + Lambda to insert the updated CF2 js code directly into the CloudFormation template. Using this approach you would setup your repo as a source in CodePipeline, so that any time you commit changes the pipeline invokes. The second stage is a Lambda that looks at the changed files in the commit, and if it includes a CF2 js file change, then take the entire contents of the js file, and replace the FunctionCode block in the CloudFormation template with the updated js file. It is a lot of work, and a little clunky, but if you have a pipeline running anyways then this can fit in nicely. Tbh, you don't even need to use CodePipeline, you could write your own scripts to manually do the same thing. CodePipeline just automates it.
profile pictureAWS
answered a year ago

Thanks Franky and Jeremy.

The situation here is that I was using a L@E function, but wanted to switch to CFF because (a) it's a little easier in the CloudFormation / tighter integration with CloudFront and (b) I have no idea what's going on with L@E longer term - CFF is the new hotness!

The function itself is operationally very lightweight - it's just a redirect function based on the original path. But the source code is about 100 lines long (about 2/3 of which is a map of redirect locations) . So in this case being able to edit the code as an actual .js file would be much more convenient, AND I'd be able to unit test it. But I can't do that with inline code.

Your option #2 Jeremy is ... ummm ... clever? But as you say a lot of work! :) For me this is just a one-js-file function, with a 2-resource CloudFormation template (the distribution, and the CFF function) . I really don't want to do anything to deploy other than sam deploy or aws cloudformation deploy.

This is a situation where I don't want to use CDK because it's a piece of infrastructure that doesn't change very often, and IMO CDK apps require more "tending" over the long term than a vanilla CloudFormation / SAM app (see more on my thoughts on CDK here if you're interested:

Can this become a feature request for CloudFront, in which case does anyone know how I request that?


answered a year ago
  • Mike, see my other answer. I tried to leave a comment so you get a notification, but the comments are limited to 600 chars.



CloudFront functions should be small and light.
If you got a large piece of code, please consider using Lambda@Edge which does support other sources of code.

Comparison between CloudFront functions and Lambda function is available in this blog post:

Please see if this documents helps:

Thank you.


answered a year ago

Hi Mike, thanks for the context! Posting a new answer since the comment option limited my response to 600 characters.

I agree, the ideal option is to support an operation similar to how Lambda@Edge is packaged using sam package/deploy. It might be possible to do this with aws cloudformation package, but I am not sure if it supports AWS::CloudFront::Function as a supported resource type. To my knowledge it does not, but I would be happy to be wrong in this instance!

Re-thinking my option 2 above, I use that workflow as part of a much larger CodePipeline deploy workflow, but in this use-case it is un-neccessarily complex. I would instead just create a simple node app that performs some simple logic. Something like:

node cf2packager --viewerReq viewer-req-function.js --viewerResp viewer-resp-function.js --template cf-distro-template.json

This would take the viewerReq and viewerResp js files which can be edited and version controlled independently, and then replaces the appropriate FunctionCode block(s) in the CloudFormation template and spits out a new template file. Then you can just run your aws cloudformation deploy.

profile pictureAWS
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions