Skip to content

Gareth Evans - Principal Consultant

CloudFront Functions released for general availability

AWS have just released CloudFront Functions - what do we know so far and how do they compare to Lambda@Edge?

Introduction

Today Amazon Web Services have announced the general availability of CloudFront Functions and have a corresponding blog post describing their usage. CloudFront Functions is a serverless platform to run your code on the CloudFront edge locations with low latency cheaply but with some important caveats. This blog post takes a dive into the hairy details, consolidating information about CloudFormation support, the runtime, billing and monitoring.

tl;dr

For the impatient here are the bullet points that the remainder of this post will elaborate on:

  • Lighter weight Lambda@Edge for simple request/response manipulations.
  • Support for CloudFormation on release! 馃帀
  • There is a PR for CDK support being worked on.
  • The runtime is pure JavaScript (including crypto and querystring modules).
  • Maximum running time of 1ms with 2MB memory.
  • Runs at the CloudFront edge locations (currently 218+).
  • Priced per invocation at US$0.10 for 1 million requests with a free tier.
  • All logs go to CloudWatch Logs in the us-east-1 region.
  • Several CloudWatch metrics are available.
  • CloudFormation hints at possible other runtimes in the future.
  • No environment variables or secrets support.

Runtime

The runtime for Functions is pure JavaScript to the ECMAScript 5.1 specification with some features of later specifications included. It does not include some of the JS niceties that we've come to love over the years including:

  • let and const.
  • await/async syntax.
  • The spread operator.

The following major features have been made available from later specifications:

  • Arrow functions (() => {...}).
  • Template strings (`Hello ${name}!`).
  • Promises.
  • Object methods assign, entries, values and keys.
  • String methods startsWith, padStart, trimStart and their counterparts.

In addition some features have been deliberately restricted:

  • eval() and Function.
  • Network or filesystem access.
  • Timers such as setTimeout().
  • Strict mode is enforced by default (use strict).

All code must be specified in a single file or string and the only modules made available are crypto and querystring.

Your code gets a maximum of 1 millisecond to run in 2MB of memory. I have not yet seen how the available compute compares.

The Functions are deployed to every CloudFront Edge location, which is currently at 218+, providing the lowest possible latency.

No environment variables or secrets management is available, requiring any secrets (such as JWT secret keys) to be baked into the code at build/deploy time.

CloudFormation support

Good news! CloudFormation support is available on release! 馃帀 Whilst at the time of writing the documentation has yet to be published, if you examine the specification you can expect it to look something like this:

{
  "ExampleFunction": {
    "Type": "AWS::CloudFront::Function",
    "Properties": {
      "Name": "",
      "Stage": "",
      "AutoPublish": true,
      "FunctionCode": "",
      "FunctionConfig": {
        "Comment": "",
        "Runtime": ""
      }
    }
  }
}

Interestingly it includes a Runtime parameter hinting that additional runtimes may be made available in the future, although this may never eventuate (array properties that must include exactly one element anyone?... 馃槥).

Additionaly it looks like the CDK team has a PR in the works to include L2 construct support so that we can enjoy it's higher level abstractions in addition to L1 constructs reflecting pure CloudFormation resources.

Monitoring

The monitoring available on release is as you'd expect with several CloudWatch metrics being published:

  • FunctionInvocations - The number of invocations.
  • FunctionValidationErrors - The number of badly formed responses from the Function.
  • FunctionExecutionErrors - The number of runtime execution failures.
  • ComputeUtilization - A percentage of the maximum runtime consumed.

All output from console.log(...) entries will be sent to CloudWatch Logs in the us-east-1 region regardless of where the Function executed.

Billing

In exchange for the greatly constrained runtime environment CloudFront Functions offers greatly reduced pricing that also only has a single per-invocation dimension. There are no considerations in which region the invocations occur in and pricing is, at this time, US$0.10 per 1 million requests. In addition there is also a free tier available for new customers with 2,000,000 invocations per month for the first year.

Lambda@Edge

In short CloudFront Functions are intended for much simpler use cases such as token validation and request/response manipulation. In exchange for a restricted runtime you gain lower pricing and lower latency.

Compared to Lambda@Edge, CloudFront Functions are:

  • Intended for simpler use cases.
  • Cheaper, at US$0.10/1 million v.s. US$0.60/1 million requests + $0.00000625125/128MB-second.
  • Restricted to limited JavaScript v.s. your choice of a Node.js or Python environment.
  • Restricted to 1ms running time v.s. 5 or 30 seconds (depending on trigger).
  • Restricted to 2MB memory v.s. 128MB or 10GB (depending on trigger).
  • Run at the CloudFront edge locations (218+) v.s. regional edge locations (13).
  • Logged to us-east-1 v.s. the region of execution.

Conclusion

In all, the runtime, whilst bespoke, seems capable of fulfilling it's intended purpose of request/response manipulation. It is understandable that the runtime is somewhat limited given the execution environment although it will be interesting to see if it becomes a target for transpilers given the available features are quite selective. This would also make local testing more viable, reducing the need to deploy each iteration. Perhaps the runtime will be made available?

I know I'm going to be cutting tickets to update this very site to use CloudFront Functions.

Thanks for reading! 馃檹

More from Insights