亚马逊AWS官方博客

宣布推出 AWS Lambda 函数 URL:用于单功能微服务的内置 HTTPS 端点

企业正在使用 AWS Lambda 以采用微服务架构来构建弹性和可扩展的应用程序。这些应用程序由实现业务逻辑的多个无服务器函数组成。每个函数都使用 Amazon API Gateway Application Load Balancer 等服务映射到 API 端点、方法和资源。

但是有时候,您只需要在函数前配置 HTTPS 端点的一种简单方法,不需要学习、配置和操作 Lambda 之外的其他服务。例如,您可能需要执行 Webhook 处理程序或在单个 Lambda 函数中运行的简单表单验证器。

今天,我很高兴地宣布 Lambda 函数 URL 正式发布,这是一项新功能,可让您将 HTTPS 端点添加到任何 Lambda 函数,并可以选择配置跨源资源共享 (CORS) 标头

这样,在我们负责配置和监控高度可用、可扩展且安全的 HTTPS 服务的同时,您可以专注于更重要的事务。

Lambda 函数 URL 的工作原理
创建一个新函数 URL 并将其映射到任何函数。每个函数 URL 都是全局唯一的,可以与函数的别名或函数的非限定 ARN 关联,后者会隐式调用 $LATEST 版本

例如,如果您将函数 URL 映射到您的 $LATEST 版本,则每次代码更新都将立即通过函数 URL 提供。另一方面,我建议将函数 URL 映射到别名,这样您就可以安全地部署新版本,执行一些集成测试,然后在准备就绪时更新别名。这也使您能够实施加权流量转移安全部署

Lambda API 本身支持函数 URL,您可以通过 AWS 管理控制台AWS 软件开发工具包以及基础设施即代码 (IaC) 工具(例如 AWS CloudFormationAWS SAMAWS Cloud Development Kit (AWS CDK))开始使用该功能。

Lambda 函数 URL 实际操作
您可以为新函数或现有函数配置函数 URL。让我们看看如何执行一个新函数来处理 Webhook。

创建新函数时,我选中了 Advanced Settings(高级设置)中的 Enable function URL(启用函数 URL)。

在这里,我选择身份验证类型:AWS_IAM。我的 Webhook 将使用基于 HTTP 标头中提供的签名的自定义授权逻辑。因此,我将选择 AuthType 为 None(无),这意味着 Lambda 在调用我的函数之前不会检查任何 AWS IAM Sigv4 签名。相反,我将在函数处理程序中提取并验证自定义标头以进行授权。

AWS Lambda URL — 创建函数

请注意,在 AuthType 使用 None(无)时,我的函数的基于资源的策略仍必须明确允许公开访问。否则,未经身份验证的请求将被拒绝。您可以使用 AddPermission API 以编程方式添加权限。在这种情况下,Lambda 控制台会自动为我添加必要的策略,因为我使用的 IAM 角色已得到授权,可以在我的账户中调用 AddPermission API。

只需单击一下,我还可以启用 CORS。默认的 CORS 配置将允许所有来源。然后,我将在创建函数后添加更精细的控件。如果您不熟悉 CORS,它是浏览器实现的基于标题的安全机制,用于确保只允许特定主机加载资源和调用 API。如果允许网站使用您的 API,则需要包含一些 CORS 标头,以声明允许哪些来源、方法和自定义标头。新的函数 URL 会为您处理这些事宜,因此您不必在 Lambda 处理程序中实现所有这些操作。

函数 URL 几秒钟后可用。我也可以在 Lambda 控制台中轻松找到并复制它。

AWS Lambda URL — 控制台 URL

在 Node.js 中处理我的 Webhook 的函数代码如下所示:

exports.handler = async (event) => {
    
    // (optional) fetch method and querystring
    const method = event.requestContext.http.method;
    const queryParam = event.queryStringParameters.myCustomParameter;
    console.log(`Received ${method} request with ${queryParam}`)
    
    // retrieve signature and payload
    const webhookSignature = event.headers.SignatureHeader;
    const webhookPayload = JSON.parse(event.body);
    
    try {
        validateSignature(webhookSignature); // throws if invalid signature
        handleEvent(webhookPayload); // throws if processing error
    } catch (error) {
        console.error(error)
        return {
            statusCode: 400,
            body: `Cannot process event: ${error}`,
        }
    }

    return {
        statusCode: 200, // default value
        body: JSON.stringify({
            received: true,
        }),
    };
};

该代码将从请求标头、查询字符串和正文中提取一些参数。如果您已经熟悉 API Gateway 或 Application Load Balancer 提供的事件结构,那么这看上去应该非常熟悉。

更新代码后,我决定使用 HTTP 客户端测试函数 URL。

例如,以下是我用 curl 执行操作的方法:

$ curl "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/?myCustomParameter=squirrel"
    -X POST
    -H "SignatureHeader: XYZ"
    -H "Content-type: application/json"
    -d '{"type": "payment-succeeded"}'

或者使用 Python 脚本:

import json
import requests

url = "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/"
headers = {'SignatureHeader': 'XYZ', 'Content-type': 'application/json'}
payload = json.dumps({'type': 'payment-succeeded'})
querystring = {'myCustomParameter': 'squirrel'}

r = requests.post(url=url, params=querystring, data=payload, headers=headers)
print(r.json())

别忘了在测试中将请求的 Content-type 设置为 application/jsontext/*,否则原定设置情况下正文将进行 base64 编码,您需要在 Lambda 处理程序中对其进行解码。

当然,在本例中我们谈论的是 Webhook,因此这个函数将直接从我正在集成的外部系统接收请求。我只需要向他们提供公共函数 URL 然后开始接收事件即可。

对于这个特定的使用案例,我不需要任何 CORS 配置。在其他从浏览器调用函数 URL 的案例中,我需要再配置一些 CORS 参数,例如 Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Expose-Headers。我可以在 Lambda 控制台或 IaC 模板中轻松查看和编辑这些 CORS 参数。以下是其在控制台中的样子:

AWS Lambda URLs — CORS

另外,请记住,每个函数 URL 都是唯一的,并映射到特定的别名或函数的 $LATEST 版本。这让您可为同一个函数定义多个 URL。例如,您可以定义一个 URL 用于在开发过程中测试 $LATEST 版本,另一个 URL 用于每个阶段或别名,例如暂存生产等。

支持基础设施即代码 (IaC)
您可以立即使用 AWS CloudFormation、AWS SAM 和 AWS Cloud Development Kit (AWS CDK) 在 IaC 模板中直接开始配置 Lambda 函数 URL。

例如,以下是如何使用 AWS SAM 定义 Lambda 函数及其公开 URL 的方法,其中包括别名映射:

WebhookFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: webhook/
      Handler: index.handler
      Runtime: nodejs14.x
      AutoPublishAlias: live
      FunctionUrlConfig:
        AuthType: NONE
        Cors:
            AllowOrigins:
                - "https://example.com"

如果您的 IaC 模板中有现有的 Lambda 函数,则可以用几行代码定义一个新的函数 URL。

函数 URL 定价
函数 URL 包含在 Lambda 的请求和持续时间定价中。例如,假设您部署了一个具有 128 MB 内存且平均调用时间为 50 毫秒的 Lambda 函数。该函数每月接收 500 万个请求,因此请求的费用为 1.00 美元,持续时间的费用为 0.53 美元。在美国东部(弗吉尼亚北部)区域,每月总额为 1.53 美元。

何时使用函数 URL 与Amazon API Gateway
函数 URL 非常适合必须使用不需要 API Gateway 高级功能(例如请求验证、节流、自定义授权方、自定义域名、使用计划或缓存)的公共端点实现单功能微服务的所有使用案例。例如,在您实现 Webhook 处理程序、表单验证程序、移动支付处理、广告投放、机器学习推理时等。这也是在研发过程中调用 Lambda 函数的最简单方法,无需离开 Lambda 控制台或集成其他服务。

Amazon API Gateway 是一项完全托管的服务,可让您更轻松地创建、发布、维护、监控任何规模的 API 并保护其安全。使用 API Gateway 可以利用 JWT/ 自定义授权方、请求/响应验证和转换、使用计划、内置 AWS WAF 支持等功能。

现已正式推出
函数 URL 现已在除 AWS 中国区域外提供 Lambda 的所有 AWS 区域中正式推出。您还可以通过许多 AWS Lambda 合作伙伴获得支持,例如 Datadog、Lumigo、Pulumi、Serverless Framework、Thundra 和 Dynatrace。

我期待听到您在使用这项新功能来简化您的无服务器架构,尤其是出于简化事物和优化成本目的而采用单功能使用案例时的感受。

查看新的 Lambda 函数 URL 文档

Alex