Apache APISIX aws-lambda 插件实战指南:将 AWS Lambda 与 API Gateway 接入为动态上游
2026/9/15 13:21:03 网站建设 项目流程

Apache APISIX aws-lambda 插件实战指南:将 AWS Lambda 与 API Gateway 接入为动态上游

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

aws-lambda是 Apache APISIX 中用于将 AWS Lambda 函数与 Amazon API Gateway 作为动态上游接入网关的核心插件:它拦截访问指定 URI 的请求,代表客户端向 AWS 发起携带授权信息的代理请求,并将响应原样返回。本文基于仓库中 aws-lambda 官方文档 展开,结合 插件源码、通用无服务器上游框架 与 测试用例,系统讲解插件属性、两种授权方案(API Key 与 IAM SigV4 签名)、HTTP/2 调用、路径转发与删除插件的完整实战流程。

插件概述与工作原理

根据 docs/zh/latest/plugins/aws-lambda.md 的定义,aws-lambda插件将 AWS Lambda 与 Amazon API Gateway 作为动态上游集成至 APISIX,用于把访问指定 URI 的请求代理到 AWS 云。

其工作流程可以概括为三步:

  1. 终止原始请求:当请求命中配置了该插件的路由时,插件终止对已配置 URI 的请求处理。
  2. 代表客户端发起新请求:插件基于配置中的function_uri,向 AWS Lambda Gateway URI 发起一个新的 HTTP 请求。该新请求携带配置好的授权信息(API Key 或 IAM 签名)、请求头、请求体与参数,其中请求头、请求体和参数均从原始请求透传。
  3. 回传响应:插件将 AWS 返回的响应头、状态码和响应体返回给最初通过 APISIX 发起请求的客户端。

在实现层面,aws-lambda插件并非独立实现全部逻辑,而是复用了一个通用的"无服务器动态上游"框架。插件源码 apisix/plugins/aws-lambda.lua 的末尾直接调用了该框架的工厂函数:

local serverless_obj = require("apisix.plugins.serverless.generic-upstream") return serverless_obj(plugin_name, plugin_version, priority, request_processor, aws_authz_schema)

从该调用可以推断,整个插件由两部分组成:

  • 通用框架(apisix/plugins/serverless/generic-upstream.lua):负责声明插件 Schema、读取请求头/请求体/查询参数、拼接目标 URI、发起resty.http请求、处理 HTTP/2 响应头兼容并回写响应;
  • 专属处理器request_processor):负责 AWS 特有的授权逻辑,包括注入x-api-key头以及实现 AWS Signature Version 4 请求签名。

插件的元信息同样定义在 apisix/plugins/aws-lambda.lua:插件名为aws-lambda,版本号0.1,执行优先级-1899(在 access 阶段中属于较后执行、靠近上游调用的插件)。

属性详解

下表完整列出了插件支持的配置属性(对应 官方文档 中的"属性"一节,并与 generic-upstream.lua 中的 Schema 相互印证):

名称类型必选项默认值有效值描述
function_uristring触发 lambda serverless 函数的 AWS API Gateway 端点。
authorizationobject访问云函数的授权凭证。
authorization.apikeystring生成的 API 密钥,用于授权对 AWS Gateway 端点的请求。
authorization.iamobject用于通过 AWS v4 请求签名执行的基于 AWS IAM 角色的授权,详见下文"IAM 授权方案"小节。
authorization.iam.accesskeystring从 AWS IAM 控制台生成的访问密钥 ID。
authorization.iam.secretkeystring从 AWS IAM 控制台生成的访问密钥。
authorization.iam.aws_regionstring"us-east-1"发出请求的 AWS 区域(如us-east-1ap-southeast-1)。
authorization.iam.servicestring"execute-api"接收该请求的服务。使用 Amazon API Gateway 时设置为execute-api;直接调用 Lambda 函数时设置为lambda
timeoutinteger3000[100,...]代理请求超时(毫秒)。
ssl_verifybooleantruetrue/falsetrue时执行 SSL 验证。
keepalivebooleantruetrue/falsetrue时保持连接活动以便复用。
keepalive_poolinteger5[1,...]关闭连接前,该连接上最多可发送的请求数。
keepalive_timeoutinteger60000[1000,...]连接空闲时保持活动状态的时间(毫秒)。

几点需要注意的细节:

  • function_uri是唯一必填项,且必须为完整的 AWS API Gateway 端点 URL;authorization整体为可选,但一旦配置了iam子对象,则accesskeysecretkey均为必填。这一约束在源码中体现为 aws_authz_schema 中的required = {"accesskey", "secretkey"},并有测试用例专门验证缺失字段时报错。
  • timeoutkeepalive_poolkeepalive_timeout的最小值约束(分别为 100ms、1、1000ms)同样来自 generic-upstream.lua 的 Schema,配置低于下限会被 Schema 校验直接拒绝。
  • 通过 conf/config.yaml.example 可以确认 APISIX 默认 HTTP 监听端口为9080,Admin API 默认端口为9180(见 config.yaml.example 中 9180 端口配置)。

启用插件:API Key 授权方式

启用插件需要调用 Admin API 修改路由配置。在发起请求前,可以先从 conf/config.yaml 中取出admin_key并存入环境变量:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

说明:Admin API 的密钥在 conf/config.yaml 的deployment.admin.admin_key字段下配置,默认角色为admin。生产环境请务必替换为自定义密钥。

以下命令在路由/aws上启用aws-lambda插件,使用 AWS 控制台生成的 API Key 进行授权:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "plugins": { "aws-lambda": { "function_uri": "https://x9w6z07gb9.execute-api.us-east-1.amazonaws.com/default/test-apisix", "authorization": { "apikey": "<Generated API Key from aws console>" }, "ssl_verify":false } }, "uri": "/aws" }'

配置完成后,任何对/awsURI 的请求(无论是HTTP/1.1HTTPS还是HTTP/2)都会调用配置的 AWS 函数 URI,并将响应返回给客户端。假设 AWS Lambda 函数从查询参数中获取name并返回"Hello $name"消息,可以这样验证:

curl -i -XGET localhost:9080/aws\?name=APISIX

正常返回结果:

HTTP/1.1 200 OK Content-Type: application/json ... "Hello, APISIX!"

从源码看,API Key 授权的实现非常直接:在 request_processor 中,若客户端请求头中尚未携带x-api-key,插件会将其设置为配置中的apikey值;反之若客户端已显式设置x-api-key,插件遵循"不覆盖授权键"的原则,保留客户端传入的值。

通过 HTTP/2 与 APISIX 通信

客户端同样可以通过 HTTP/2 协议与 APISIX 通信并调用 AWS Lambda。由于 HTTP/2 默认处于禁用状态,需要先在 conf/config.yaml(或 conf/config.yaml.example 中取消对应注释)的apisix.node_listen下新增一个启用 HTTP/2 的监听端口,例如:

apisix: node_listen: # 支持监听多个端口 - 9080 - port: 9081 enable_http2: true # 该字段如果不设置,默认值为 `false`

配置后使用curl的 HTTP/2 模式测试:

curl -i -XGET --http2 --http2-prior-knowledge localhost:9081/aws\?name=APISIX

正常返回结果:

HTTP/2 200 content-type: application/json ... "Hello, APISIX!"

值得说明的是,HTTP/2 场景并非只是协议层面的简单切换。在 generic-upstream.lua 的 access 阶段 中,插件在转发 AWS 响应时会检查ngx.var.http2,若为 HTTP/2 请求,则根据 RFC 7540 第 8.1.2.2 节的要求,移除ConnectionKeep-AliveProxy-ConnectionUpgradeTransfer-Encoding等连接专用响应头,从而保证 HTTP/2 响应的协议合规性。

IAM 授权方案(AWS Signature Version 4 签名)

除了 API Key,插件还支持通过 AWS IAM 凭证进行授权,此时会在 HTTP 调用中自动完成AWS Signature Version 4(SigV4)请求签名。以下示例展示了通过 IAM 访问密钥配置授权:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "plugins": { "aws-lambda": { "function_uri": "https://ajycz5e0v9.execute-api.us-east-1.amazonaws.com/default/test-apisix", "authorization": { "iam": { "accesskey": "<access key>", "secretkey": "<access key secret>" } }, "ssl_verify": false } }, "uri": "/aws" }'

注意:使用该方式前,需要确保你已拥有一个启用了程序化访问的 IAM 用户,并具备访问端点的必要权限(例如AmazonAPIGatewayInvokeFullAccess)。aws_regionservice均为可选参数,默认分别为"us-east-1""execute-api";若直接调用 Lambda 函数,应将service显式设置为"lambda"

签名过程的源码级拆解

从 aws-lambda.lua 的 request_processor 后半段 可以完整还原 SigV4 签名的实现步骤,这有助于理解插件行为与排障:

  1. 生成时间戳:通过ngx.time()os.date生成X-Amz-Date请求头(格式%Y%m%dT%H%M%SZ)以及用于凭证范围的日期戳(%Y%m%d)。
  2. 构造 Canonical URI:对转发路径做规范化(pl.path.normpath),统一处理首尾/
  3. 构造 Canonical Query String:遍历查询参数,先unescape再拼接为k=v,并按字典序排序(对应 aws-lambda.lua#L124-L132)。
  4. 构造 Canonical Headers 与 SignedHeaders:所有请求头小写化、剔除connection头、去除首尾与多余空格、排序后拼装,并生成分号分隔的SignedHeaders列表(对应 aws-lambda.lua#L136-L154)。
  5. 构造 Canonical Request 与 StringToSign:按AWS4-HMAC-SHA256算法组织签名串(对应 aws-lambda.lua#L157-L171)。
  6. 派生签名密钥并计算签名get_signature_key依次对AWS4+secretkey、日期戳、区域、服务名做 HMAC-SHA256 派生,最终生成authorization请求头,形如AWS4-HMAC-SHA256 Credential=..., SignedHeaders=..., Signature=...(对应 aws-lambda.lua#L46-L52 与 L174-L181)。

上述行为在测试 t/plugin/aws-lambda.t 的 TEST 6 中得到了验证:测试断言上游收到的Authorization头以AWS4-HMAC-SHA256开头、X-Amz-Date头符合数字T数字Z的时间格式。

配置路径转发

aws-lambda插件在代理请求到 AWS 上游时还支持URL 路径转发:基本请求路径的扩展部分会被追加到插件配置的function_uri上。

重要:由于 APISIX 路由是严格匹配的,要使路径转发正常工作,路由上配置的uri字段必须以*结尾。*表示该 URI 的任何子路径都会匹配到同一条路由。

以下示例展示了路径转发的配置方式,function_uri只填写 API Gateway 的基础域名,具体路径由请求动态拼接:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "plugins": { "aws-lambda": { "function_uri": "https://x9w6z07gb9.execute-api.us-east-1.amazonaws.com", "authorization": { "apikey": "<Generate API key>" }, "ssl_verify":false } }, "uri": "/aws/*" }'

配置完成后,任何访问aws/default/test-apisix的请求都会调用 AWS Lambda 函数,并转发附加的路径与参数:

curl -i -XGET http://127.0.0.1:9080/aws/default/test-apisix\?name\=APISIX

正常返回结果:

HTTP/1.1 200 OK Content-Type: application/json ... "Hello, APISIX!"

路径拼接的底层实现位于 generic-upstream.lua 的 access 阶段:插件解析function_uri得到基础路径,再通过ctx.curr_req_matched[":ext"]取出路由通配符*匹配到的扩展路径,拼接到基础路径之后(必要时自动补充/分隔符),从而实现"路由子路径即 AWS 函数路径"的动态转发。

删除插件

当需要删除该插件时,只需将路由中的插件配置置空即可,APISIX 会自动重新加载相关配置,无需重启服务:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "uri": "/aws", "plugins": {}, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }'

执行后,路由/aws不再经过 AWS 代理,而是按新配置的upstream转发到本地127.0.0.1:1980

测试用例对插件行为的验证

仓库中的 t/plugin/aws-lambda.t 为插件提供了完整的 Test::Nginx 测试套件,可用于理解插件各行为的预期结果:

测试验证点
TEST 1合法 IAM 配置(accesskey+secretkey)通过 Schema 校验
TEST 2IAM 配置缺失accesskey时返回明确的校验错误
TEST 3通过 Admin API 创建启用aws-lambda的路由
TEST 4请求/aws后成功代理到模拟上游并返回 "aws lambda invoked"
TEST 5配置apikey后,上游收到的请求头包含x-api-key: test_key
TEST 6配置 IAM 后,上游收到AWS4-HMAC-SHA256签名的Authorization头与格式正确的X-Amz-Date

这些用例与本文介绍的两种授权方式一一对应,是排查授权类问题(如签名不匹配、缺少凭证)时的直接参考。

总结

aws-lambda插件以"通用无服务器上游框架 + AWS 专属授权处理器"的组合方式,为 APISIX 提供了将 AWS Lambda / API Gateway 作为动态上游的完整能力。本文覆盖了它的全部配置属性、API Key 与 IAM SigV4 两种授权方式、HTTP/2 通信、路径转发和插件下线流程。若需进一步深入,可查阅:英文版插件文档、插件源码、通用上游框架 与 插件测试,并结合 conf/config.yaml.example 核对监听端口与 HTTP/2 的默认配置。

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询