亚马逊AWS官方博客
利用Amazon API Gateway和AWS Lambda处理Cloudfront的内容请求
概述
国内Amazon Cloudfront目前不支持Lambda@edge功能,不能实现基于CDN的A/B测试、rewrite、redirect、token认证和产生response等功能,本文介绍如何利用API Gateway和Lambda实现Lambda@edge的功能。下面实验介绍通过request header参数值,实现redirect和rewrite的测试场景,根据header(test_version)参数值,回源到指定目录的文件,根据header(redirect)参数值,返回302重定向地址。
整体实验的架构图如下:
架构图说明:
- Cloudfront是Amazon的CDN服务,可以设置源站域名,回源header,缓存策略等。
- API Gateway有两种类型可以支持rewrite和redirect测试场景,实验中采用HTTP API,考虑到成本更低,同时不需要Rest API的高级功能。
- Lambda实现了rewrite和redirect的测试代码,支持验证security header。支持多种主流语言,实验中采用Python3.9语言实现。
- S3保存测试的html和png文件。
详细步骤说明
1.新建S3 Bucket
比如:bucket name:lambda-api-2022
上传文件列表:
index.html – 欢迎页
v1/test.html – A测试页
v1/test.png – A测试图片
v2/test.html – B测试页
v2/test.png – B测试图片
2.新建Lambda程序
1)新建IAM Role,执行Lambda程序,比如Role name:RoleForLambda
需要的权限如下:
2)创建Lambda程序
采用下列的参数和配置:
Function name:lambdaapi
Runtime:Python 3.9
Execution role:RoleForLambda(上一步创建的)
修改Configuration的配置:
添加Environment variables
添加Key=bucket,Value=lambda-api-2022
添加Key=lambda_auth,Value=lambdaapi_test
添加Key=redirect_path,Value=https://xxx.cloudfront.net,value来自下面创建的Cloudfront distribution
General configuration
修改Timeout为20秒
Lambda Source Code:
Lambda Source Code说明:
在Cloudfront回源时,添加lambda_auth header,用于Lambda认证请求,当认证失败时,返回403错误。
当请求根目录时,返回index.html
当request header包含test_version时,转向到指定目录下的文件。
将返回的body通过base64编码,以支持binary对象。
当request header包含redirect=true时,返回302重定向信息。
3.新建API Gateway
在API Gateway中,新建HTTP API,比如API Name:lambdaapi
新建Lambda integration,选择上一步创建的Lambda(lambdaapi)
在Configure routes时,Resource path设置为“/{proxy+}”
在Deploy Stages中,找到$default stage的Invoke URL,如https://xxx.execute-api.xxx.amazonaws.com,此为API Gateway的请求地址。
测试API gateway:
- 测试security header
测试命令:curl https://xxx.execute-api.xxx.amazonaws.com
返回结果:request is forbidden
- 测试访问根路径,传入lambda_auth header
测试命令:curl -v -H “lambda_auth:lambdaapi_test” https://xxx.execute-api.xxx.amazonaws.com
返回结果:statusCode=200
- 访问B测试页,传入lambda_auth header和test_version header
测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” https://xxx.execute-api.xxx.amazonaws.com/test.html
返回v2/test.html的内容
- 访问B测试图片,传入lambda_auth header和test_version header
测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” https://xxx.execute-api.xxx.amazonaws.com/test.png > test.png
将response保存为test.png图片。
- 测试redirect,传入redirect header
测试命令:curl -v -H “lambda_auth:lambdaapi_test” -H “test_version:v1” -H “redirect:true” https://xxx.execute-api.xxx.amazonaws.com/test.html
返回302重定向信息
4.配置Cloudfront
1)创建Origin request policy,Amazon Cloud Global支持该功能
在Cloudfront Policies中,新建origin request policy,例如Name:lambdaapi
配置如下:
Headers:选择 Include the following headers,并手工添加header:test_version和redirect
Query strings: All
Cookies:All
2)创建Cloudfront Distribution
在Cloudfront中,新建Distribution,例如Description:lambdaapi
配置如下:
Origin domain:xxx.execute-api.xxx.amazonaws.com,上面创建的HTTP API域名
Protocol:HTTPS only
Add custom header:
Header name = lambda_auth,Value = lambdaapi_test
在Amazon Cloud Global,支持Cache policy and origin request policy (recommended),配置下面两个参数:
Cache policy:CachingDisabled
Origin request policy:Custom lambdaapi
或者在Amazon Cloud China,支持Legacy cache settings,配置下面3个参数:
Headers:选择 Include the following headers,并手工添加header:test_version和redirect。
Query strings: All
Cookies:All
如果不需要Cloudfront缓存内容时,需要设置Object caching为Customize,同时将Minimum TTL、Maximum TTL和Default TTL都设为0.
注:需新建origin和behavior,配合redirect后Cloudfront地址。
5.测试Cloudfront
1.在Cloudfront Distributions (Lambdaapi)的General Details中,找到Distribution domain name,例如cloudfront.net
2.访问A测试页,传入test_version header
测试命令:curl -H “test_version:v1” https://xxx.cloudfront.net/test.html
返回v1/test.html的内容
3.测试redirect,传入test_version和redirect header
测试命令:curl -I -H “test_version:v1” -H “redirect:true” https://xxx.cloudfront.net/test.html
返回302重定向的内容
结论
在这篇文章中,介绍了如何利用API Gateway和Lambda处理Cloudfront的内容请求,实现Lambda@edge的功能,在实验中,介绍了Amazon S3、Lambda、API Gateway和Cloudfront的配置方法,实现了rewrite和redirect的测试场景。
参考资料
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html
- https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html
- https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html
- https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html
- https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html