A few weeks ago Amazon announced a new feature for Amazon CloudFront to run code in Edge Locations. But where is the difference between Lambda@Edge and CloudFront Functions?
CloudFront Functions are running in Edge locations whereas Lambda@Edge functions are executed in a regional edge cache (eg.: the AWS region closest to the CloudFront edge location reached by the client). Therefore CloudFront Functions are even closer to the client and are at the same time approximately 1/6th the price of Lambda@Edge.
Use Cases
- Authorization: Implement authorization for the content delivered through CloudFront using Basic Authentication or by creating and validating user-generated tokens.
- Redirects: Redirect users to a different URL - eg.: If you change to a new website structure you can redirect the user to the new URL.
- Header Manipulation: Add, modify, or delete any of the request/response headers - eg.: foward the IP of the client using the Header to your origin.
CloudFront Functions versus Lambda@Edge
Features
Most important differences - if you need more information check this docs: Choosing between CloudFront Functions and Lambda@Edge.
CloudFront Functions | Lambda@Edge | |
---|---|---|
Execution location | CloudFront Edge Locations | CloudFront Regional Edge Caches |
Programming languages | JavaScript (ECMAScript 5.1 compliant) | Python, Nodejs |
Event sources | Viewer request Viewer response | Viewer request Viewer response Origin request Origin response |
Memory | 2 MB | 128 MB (viewer triggers) – 10 GB (origin triggers) |
Max size of Function | 10 KB | 1 MB (viewer request / response) 50 MB (origin request / response) |
Max execution time | 1 ms | 5 seconds (viewer request / response) 30 seconds (origin request / response) |
Access to geolocation and device data | ✅ | ❌ (viewer request) ✅ (viewer response) ✅ (origin request) ✅ (origin response) |
Access to the request body | ❌ | ✅ |
Pricing example
Service | Price per Invocation | Price per Duration (for every GB-second) | Invocations | Duration | Allocated Memory | Total Cost |
---|---|---|---|---|---|---|
CloudFront Function | $0.1 | - | 2 Million | 1ms | - | $2.0 |
Lambda@Edge | $0.6 | $0,00005001 | 2 Million | 10ms | 128MB | $12.26 |
- The prices were checked on 30.05.2021 from Lambda@Edge pricing and CloudFront Function pricing
Example template for Basic Auth with CloudFront Functions
Following you will find a CloudFront Function for Basic Auth - I am using it as a second layer of security for private CloudFront origins. For example I am generating exports of Jira content to S3 using a Lambda as a Backup. In Front of CloudFront I have a WAF to restrict to spefic IPs plus these CloudFront functions.
AWSTemplateFormatVersion: 2010-09-09
Description: Creates a Base CloudFront Function for Authentification
Metadata:
Author:
Description: David Krohn
Parameters:
CloudFrountUsername:
Description: Username CloudFront
Type: String
CloudFrountPassword:
Description: Password CloudFront
Type: String
NoEcho: true
Ressources:
CloudFrontFunctionBasicAuth:
Type: AWS::CloudFront::Function
Properties:
AutoPublish: true
FunctionCode: !Sub |
var USERS = {
Website: [{
username: '${CloudFrountUsername}',
password: '${CloudFrountPassword}',
}],
};
//Response when auth is not valid.
var response401 = {
statusCode: 401,
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': {
value: 'Basic'
},
},
};
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function btoa(input) {
input = String(input);
var bitmap, a, b, c,
result = "",
i = 0,
rest = input.length % 3; // To determine the final padding
for (; i < input.length;) {
if ((a = input.charCodeAt(i++)) > 255 ||
(b = input.charCodeAt(i++)) > 255 ||
(c = input.charCodeAt(i++)) > 255)
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
bitmap = (a << 16) | (b << 8) | c;
result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) +
b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
}
// If there's need of padding, replace the last 'A's with equal signs
return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
}
function handler(event) {
var request = event.request;
var headers = request.headers;
var auth = request.headers.authorization && request.headers.authorization.value;
var users = USERS['Website'];
if (users) {
if (!auth || !auth.startsWith('Basic ')) {
return response401;
}
if(!users.find(function(user) {
// Construct the Basic Auth string
var authString = 'Basic ' + btoa(user.username + ':' + user.password);
return authString === auth;
})) {
return response401;
}
}
return request;
}
FunctionConfig:
Comment: !Sub 'Basic Auth for S3 Bucket ${MyWebsiteBucket}'
Runtime: cloudfront-js-1.0
More samples can be found here: Amazon CloudFront Functions Samples.
Top comments (0)