利用 Amazon API Gateway 和 Amazon 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/controlling-origin-requests.html
本篇作者
薛召兵
Amazon 解决方案架构师,负责帮助客户进行上云架构的设计和咨询。同时致力于 Amazon 容器服务、媒体服务和机器学习服务在国内和全球商业客户的应用和推广,推进企业服务迁移上云进程。有 10 年以上的软件开发、售前技术支持、系统架构设计等经验。
评论