brief introduction
This article is for users who want to use Amazon CloudFront Functions to improve Amazon CloudFront's edge computing capabilities, and aims to help you better develop, debug, test, and deploy CloudFront Functions.
First, we will give a brief introduction to CloudFront Function, and then tell you how to create a test environment with CloudFront Function processing capabilities in seven steps, and carry out some related debugging work.
Step 1: Prepare the overall architecture based on the deployment guide (2)
Step 2: Create a CloudFront Function
Step 3: Publish the function and associate the CloudFront distribution
Step 4: CloudFront log output and query
Step 5: Use Response Header to complete quick debugging
Step 6: View CloudFront Functions calculation utilization
Step 7: Apply CFF in CloudFront Extension
Through this guide, you will learn how to use CloudFront to quickly build a content distribution network and demonstrate the distribution effect.
CloudFront Functions and
A brief introduction to Amazon Lambda@Edge
With Amazon CloudFront, you write your own code to handle HTTP requests and responses. Code runs close to your users to minimize latency, and you don't have to manage servers or other infrastructure. You can write code to manipulate requests and responses flowing through CloudFront, perform basic authentication and authorization, generate HTTP responses at the edge, and more. The code that you write and attach to your CloudFront distribution is called an edge function. CloudFront currently offers two methods for authoring and managing edge functions:
CloudFront Functions – With CloudFront Functions, you can write lightweight functions in JavaScript for large-scale, latency-sensitive CDN custom processing. The CloudFront Functions runtime environment provides sub-millisecond startup times, scales instantly to handle millions of requests per second, and is highly secure. CloudFront Functions are native to CloudFront, which means you can build, test, and deploy your code entirely within CloudFront.
Lambda@Edge – Lambda@Edge is an extension of Amazon Lambda that provides powerful and flexible computing for complex functions and complete application logic, closer to your viewers, and highly secure. Lambda@Edge functions run in js or Python runtime environment. You publish them to a single Amazon region, but when you associate a function with a CloudFront distribution, Lambda@Edge automatically replicates your code globally.
For the differences and choices between CloudFront Functions and Lambda@Edge, please refer to the CloudFront documentation:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions.html。
This article will be dedicated to introducing CloudFront Functions, and Lambda@Edge will be explained in depth in the follow-up series of CloudFront deployment guides.
How to start CloudFront Functions development
CloudFront Functions currently only supports JavaScript as a development language. The runtime environment complies with ECMAScript (ES) version 5.1, and supports some functions of ES versions 6 to 9, and also provides some non-standard methods that do not belong to the ES specification. For details, please refer to JavaScript runtime features for CloudFront Functions. For this reason, it is recommended that you use the Amazon CloudFront Functions console for CloudFront Function development and testing.
You can quickly create a CloudFront Function by simply defining the function name and description.
After the creation is complete, you will get a CloudFront Function with sample code, where you can develop, test, and release the code. On the build page, you can edit the code (development), and you can also see the latest code currently deployed online (real-time tags).
CloudFront Function is event-driven, and the CloudFront Function code we write can be associated with CloudFront's viewer event or response event. For example, when associated with a CloudFront viewer event, every web request delivered to a CloudFront distribution point that matches the associated CFF specific behavior will trigger the CloudFront Function code in the running environment of the Cloud Front Pop node, and modify the request according to the code. Such as modifying the visited uri to provide a webpage that adapts to the screen of the device according to different devices. Or verify the legitimacy of the request and other lightweight computing work. Offload these computing jobs to hundreds or thousands of servers in PoPs around the world. It can greatly improve the web page access speed of end users. Reduce the computing pressure on the origin site.
Here, each web request event provides an Event data structure to CloudFront Function (the Event data structure is presented in json format during debugging). The CloudFront Function modifies the Event data structure and returns the data structure. That is, the work of customizing and modifying the Web request is completed.
Next, we set out to build a minimal CloudFront Function environment:
step one:
Prepare a demonstration of the deployment process based on the overall architecture of the deployment guide (2)
First, let's build a CloudFront environment that accelerates dynamic and static websites based on the CloudFront deployment guide (2) . In this article, we will mainly use the part of the dynamic website in this environment to complete the debugging.
During the debugging process, we will mainly use /api, the Behavior path that disables caching, for debugging. Use Echo-Sever to observe changes in Web requests brought by CloudFront Function.
Step two:
Create a CloudFront Function
We do this with CloudFront Functions as a requirement to add Cross-Origin Resource Sharing (CORS) headers to responses.
The following is a code example for adding CORS Header to support cross-domain access. If the Access-Control-Allow-Origin CORS Header does not exist, add this value.
function handler(event) {
var response = event.response;
var headers = response.headers;
// If Access-Control-Allow-Origin CORS header is missing, add it.
// Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation.
if (!headers['access-control-allow-origin']) {
headers['access-control-allow-origin'] = {value: "*"};
console.log("Access-Control-Allow-Origin was missing, adding it now.");
}
return response;
}
Swipe left to see more
Save the changes after copying the above code snippet into the console edit window.
During the development process, you can debug the code through the test page. The code will affect the response header in the viewer response phase. Select viewer response as the event type, select Development in the test phase, and then execute the test. The test results are as follows:
The test function supports simulating request and response headers, cookies, query string. We add header information under Response – Response Headers for testing:
The obtained test results are as follows. It can be seen that if the response already contains the access-control-allow-origin response header, the value will not be added repeatedly.
So far, we have completed the full coverage test of the sample code.
Step three:
Publish function and associate CloudFront distribution
Click Add Association in Publishing, select the CloudFront distribution that needs to be associated, select Viewer Response for the event type, select /api/* for cache behavior, and click Add Association. After the association is added, you can click the Publish Function button above to distribute the code to the associated CloudFront distribution.
After the release is complete, you can test it with the curl command, and we can see that the CORS header information has been included in the response header.
curl -i http://xxxx.cloudfront.net/api/test
Swipe left to see more
Step four:
CloudFront log output and query
The above code performs log output through Console.log, and these logs will be automatically sent to CloudWatch Logs in the production environment. It's important to note that CloudFront Functions always creates log streams in the US East (N. Virginia) Region ( us-east-1 ), regardless of which edge location the function is run at. The format of the log group name is
/aws/cloudfront/function/FunctionName ,
where FunctionName is the name you gave the function when you created it.
Enter the CloudWatch console, switch the Region to the US East (Northern Virginia) region ( us-east-1 ), search for FunctionName to find the corresponding log group, and select the log stream corresponding to the time to view the log information.
Note: When publishing to a production environment, it is recommended to delete unnecessary log output to save costs.
Step five:
Use Response Header to complete quick debugging
In some scenarios, we need to publish the CloudFront Function and debug it together with the source. Clicking the release function will not be applied to all edge nodes immediately, and it will take a while to complete the deployment. We can determine which version of the code the current request is using by adding a version header to the Response Header. Every time we update the code, we only need to change the version number.
When debugging in CloudFront, we need to go to CloudWatch frequently to view logs, but there will be a certain delay in sending the logs to CloudWatch, and we need to refresh in CloudWatch continuously to check whether the logs are updated. At this point, we can assist debugging by outputting information in the Response Header. For complex code logic, we can put key information in the Response Header while console.log().
For example, in the following code, we want to view the Host header in the request header and the cache-control settings returned by the source. We can print it through console.log() and put it in the Response Header for output.
function handler(event) {
var response = event.response;
var headers = response.headers;
// check host value in request
var host = event.request.headers.host;
if (host) {
console.log("print host value in request header: " + host.value)
headers['log-host'] = { value: host.value }
}
// Print the cache-control header
var originalCacheControl = headers['cache-control']
if (originalCacheControl) {
console.log("print original cache contorl value: " + originalCacheControl.value)
headers['log-old-cache-control'] = { value: originalCacheControl.value }
} else {
headers['log-old-cache-control'] = { value: "undefined" }
}
// Set the cache-control header
headers['cache-control'] = {value: 'public, max-age=63072000'};
// If Access-Control-Allow-Origin CORS header is missing, add it.
// Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation.
if (!headers['access-control-allow-origin']) {
headers['access-control-allow-origin'] = {value: "*"};
console.log("Access-Control-Allow-Origin was missing, adding it now.");
}
headers['function-version'] = { value: 'V04' }
return response;
}
Swipe left to see more
The results of using curl to access are as follows. In the response header, we can determine the version of the currently executing code through the function-version header, and obtain the printed log information through req-host, which avoids the process of continuously refreshing and waiting for the log in CloudWatch, greatly improving efficiency. Remember to comment or delete the log-related code after debugging.
When using the response header output information for debugging, you need to follow the response header specification, the value must be of string type, and you can see the relevant information only when the CloudFront Function executes normally and returns the response completely to the client. If the code execution is abnormal or interrupted, a normal response cannot be obtained. At this time, the debugging information cannot be viewed through the response header. In this case, console.log() can print out the logs before the abnormal interruption. We can use it in conjunction with actual development and testing.
Step six:
View CloudFront Functions Compute Utilization
Compute utilization is the percentage of time a function spends running as a percentage of the maximum allowed time. For example, a value of 35 means that the function completed in 35% of the maximum allowed time. CloudFront throttles a function if it persists for longer than the maximum allowed time.
We can look at compute utilization in tests, and we can use CloudWatch to see the execution of our published functions. Go to CloudWatch – Metrics – All metrics in turn, confirm that the region has been switched to the N. Virginia region, search for CloudFront, select Per-Function Metrics, select the FunctionComputeUtilization indicator corresponding to the function, and view it.
Step seven:
CFF application in CloudFront Extension
The above uses CORS as a case to introduce the whole process of CloudFront Functions development and debugging. There are also many code cases in the CloudFront Extension project maintained by Amazon Solutions Team (CSDC), which can be used for your reference and study. The Github link for the CloudFront Extension is here:
https://github.com/awslabs/aws-cloudfront-extensions。
Summarize
With this article, you should have a hands-on understanding of CloudFront Functions. You now have a small and practical CloudFront Function debugging environment. You can use CloudFront Function code in this environment to modify web requests according to your needs. And observe their operation through Echo-Server, CloudWatch metrics and logs. You can also know the running status of the program in real time through the log written in the Response Header.
Amazon Cloud Technology CloudFront
Deployment mini-guide series
Amazon CloudFront Deployment Guide (1) - Quickly build CDN content distribution:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-one/
Amazon CloudFront Deployment Guide (2) - Advanced Deployment:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-two/
Amazon CloudFront Deployment Guide (3) - Continuous Deployment:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-three/
Amazon CloudFront Deployment Guide (5) - Using Amazon Edge Technology to Optimize In-Game Resources Update release:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-five/
Amazon CloudFront Deployment Guide (6) - Lambda@Edge Basics and Diagnosis:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/
The author of this article
Zhu Jinsong
Amazon cloud technology solution architect, responsible for solution consulting and design based on Amazon cloud platform, has more than 10 years of working experience in the IT industry, has served as system architect, big data director, CTO and other positions, in edge computing, serverless, big data Has rich practical experience.
Cui Junjie
Senior Product Solution Architect of Amazon Cloud Technology, responsible for cloud edge security related service products of Amazon Cloud Technology. Provide Amazon cloud users with product consultation related to DDoS defense/website front-end security defense/domain name security. Have an in-depth understanding of Cloudfront, Shield, WAF, Route53, Global Accelerator and other cloud edge security related products. Years of working experience in computer security, data centers and networking.
I heard, click the 4 buttons below
You will not encounter bugs!