

# 使用 CloudFormation 模板自动进行 S3 对象 Lambda 设置
<a name="olap-using-cfn-template"></a>

**注意**  
自 2025 年 11 月 7 日起，S3 对象 Lambda 仅可供当前在使用该服务的现有客户以及部分 Amazon 合作伙伴网络（APN）合作伙伴使用。要了解与 S3 对象 Lambda 类似的功能，请在此处了解更多信息：[Amazon S3 Object Lambda availability change](https://docs.amazonaws.cn/AmazonS3/latest/userguide/amazons3-ol-change.html)。

您可以使用 Amazon CloudFormation 模板快速创建 Amazon S3 对象 Lambda 接入点。CloudFormation 模板会自动创建相关资源、配置 Amazon Identity and Access Management（IAM）角色并设置 Amazon Lambda 函数，该函数可通过对象 Lambda 接入点自动处理请求。使用 CloudFormation 模板，您可以实施最佳实践、改善安全状况并减少手动流程导致的错误。

此 [GitHub 存储库](https://github.com/aws-samples/amazon-s3-object-lambda-default-configuration)包含 CloudFormation 模板和 Lambda 函数源代码。有关如何使用模板的说明，请参阅[创建对象 Lambda 接入点](olap-create.md)。

模板中提供的 Lambda 函数未运行任何转换。相反，它按原样从底层数据来源返回对象。您可以克隆函数并添加自己的转换代码，以便在数据返回到应用程序时修改和处理数据。有关修改函数的更多信息，请参阅[修改 Lambda 函数](#modifying-lambda-function)和[为 S3 对象 Lambda 接入点编写 Lambda 函数](olap-writing-lambda.md)。

## 修改模板。
<a name="modifying-cfn-template"></a>

**创建新的支持接入点**  
S3 对象 Lambda 使用两个接入点，一个对象 Lambda 接入点和一个标准 S3 接入点（称为*支持接入点*）。当您向对象 Lambda 接入点发出请求时，S3 会代表您调用 Lambda，或将请求委派给支持接入点，具体取决于 S3 对象 Lambda 配置。在部署模板时，您可以通过将以下参数作为 `aws cloudformation deploy` 命令的一部分来创建一个新的支持接入点。

```
CreateNewSupportingAccessPoint=true
```

**配置函数有效负载**  
在部署模板时，可以通过将以下参数作为 `aws cloudformation deploy` 命令的一部分传递，配置有效负载为 Lambda 函数提供补充数据。

```
LambdaFunctionPayload="format=json"
```

**启用 Amazon CloudWatch 监控**  
您可以在部署模板时通过将以下参数作为 `aws cloudformation deploy` 命令的一部分来启用 CloudWatch 监视。

```
EnableCloudWatchMonitoring=true
```

此参数将为 Amazon S3 请求指标启用对象 Lambda 接入点，并创建两个 CloudWatch 告警来监控客户端和服务器端错误。

**注意**  
Amazon CloudWatch 的使用将产生额外费用。有关 Amazon S3 请求指标的更多信息，请参阅[监控和记录接入点](access-points-monitoring-logging.md)。  
有关定价详细信息，请参阅 [CloudWatch 定价](https://www.amazonaws.cn/cloudwatch/pricing/)。

**配置预配置并发**  
要减少延迟，您可以通过编辑模板以在 `Resources` 之下包含以下各行，从而为支持对象 Lambda 接入点的 Lambda 函数配置预调配并发。

```
LambdaFunctionVersion:
      Type: AWS::Lambda::Version
      Properties:
        FunctionName: !Ref LambdaFunction
        ProvisionedConcurrencyConfig:
            ProvisionedConcurrentExecutions: Integer
```

**注意**  
配置并发将产生额外费用。有关预调配并发的更多信息，请参阅《Amazon Lambda 开发人员指南》**中的[管理 Lambda 预调配并发](https://docs.amazonaws.cn/lambda/latest/dg/provisioned-concurrency.html)。  
有关定价的详细信息，请参阅 [Amazon Lambda 定价](https://www.amazonaws.cn/lambda/pricing/)。

## 修改 Lambda 函数
<a name="modifying-lambda-function"></a>

**更改 `GetObject` 请求的标头值**  
默认情况下，Lambda 函数会将所有标头（`Content-Length` 和 `ETag` 除外）从预签名 URL 请求转发到 `GetObject` 客户端。根据 Lambda 函数中的转换代码，您可以选择向 `GetObject` 客户端发送新的标头值。

您可以更新 Lambda 函数，以通过在 `WriteGetObjectResponse` API 操作中传递来发送新的标头值。

例如，如果 Lambda 函数将 Amazon S3 对象中的文本转换为另一种语言，则可以在 `Content-Language` 标头中传递一个新值。您可以通过修改 `writeResponse` 函数来实现，如下所示：

```
async function writeResponse (s3Client: S3, requestContext: GetObjectContext, transformedObject: Buffer,
  headers: Headers): Promise<PromiseResult<{}, AWSError>> {
  const { algorithm, digest } = getChecksum(transformedObject);

  return s3Client.writeGetObjectResponse({
    RequestRoute: requestContext.outputRoute,
    RequestToken: requestContext.outputToken,
    Body: transformedObject,
    Metadata: {
      'body-checksum-algorithm': algorithm,
      'body-checksum-digest': digest
    },
    ...headers,
    ContentLanguage: 'my-new-language'
  }).promise();
}
```

有关受支持标头的完整列表，请参阅 *Amazon Simple Storage Service API 参考*中的 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax](https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax)。

**返回元数据标头**  
您可以更新 Lambda 函数，以通过在 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax](https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax) API 操作请求中传递来发送新的标头值。

```
async function writeResponse (s3Client: S3, requestContext: GetObjectContext, transformedObject: Buffer,
  headers: Headers): Promise<PromiseResult<{}, AWSError>> {
  const { algorithm, digest } = getChecksum(transformedObject);

  return s3Client.writeGetObjectResponse({
    RequestRoute: requestContext.outputRoute,
    RequestToken: requestContext.outputToken,
    Body: transformedObject,
    Metadata: {
      'body-checksum-algorithm': algorithm,
      'body-checksum-digest': digest,
      'my-new-header': 'my-new-value' 
    },
    ...headers
  }).promise();
}
```

**返回新状态码**  
您可以通过在 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax](https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax) API 操作请求中进行传递来将自定义状态代码返回至 `GetObject` 客户端。

```
async function writeResponse (s3Client: S3, requestContext: GetObjectContext, transformedObject: Buffer,
  headers: Headers): Promise<PromiseResult<{}, AWSError>> {
  const { algorithm, digest } = getChecksum(transformedObject);

  return s3Client.writeGetObjectResponse({
    RequestRoute: requestContext.outputRoute,
    RequestToken: requestContext.outputToken,
    Body: transformedObject,
    Metadata: {
      'body-checksum-algorithm': algorithm,
      'body-checksum-digest': digest
    },
    ...headers,
    StatusCode: Integer
  }).promise();
}
```

有关受支持的状态代码的完整列表，请参阅 *Amazon Simple Storage Service API 参考*中的 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax](https://docs.amazonaws.cn/AmazonS3/latest/API/API_WriteGetObjectResponse.html#API_WriteGetObjectResponse_RequestSyntax)。

**将 `Range` 和 `partNumber` 参数应用于源对象**  
默认情况下，由 CloudFormation 模板创建的对象 Lambda 接入点可以处理 `Range` 和 `partNumber` 参数。Lambda 函数将请求的范围或段编号应用于转换后的对象。为此，此函数必须下载整个对象并运行转换。在某些情况下，转换后的对象范围可能会精确映射到源对象范围。这意味着，在源对象上请求字节范围 A-B 并运行转换，可能会产生与请求整个对象、运行转换以及在转换后的对象上返回字节范围 A-B 相同的结果。

在这种情况下，您可以更改 Lambda 函数实现，以便将范围或段编号直接应用于源对象。这种方法减少了所需的总体函数延迟和内存。有关更多信息，请参阅 [使用 Range 和 partNumber 标头](range-get-olap.md)。

**禁用 `Range` 和 `partNumber` 处理**  
默认情况下，由 CloudFormation 模板创建的对象 Lambda 接入点可以处理 `Range` 和 `partNumber` 参数。如果不需要此行为，可以通过从模板中移除以下各行来禁用它。

```
AllowedFeatures:
  - GetObject-Range
  - GetObject-PartNumber
  - HeadObject-Range 
  - HeadObject-PartNumber
```

**转换大型对象**  
默认情况下，Lambda 函数会处理内存中的整个对象，然后才能开始将响应流式传输到 S3 对象 Lambda。您可以在执行转换时修改函数以流式传输响应。这样做有助于减少转换延迟和 Lambda 函数内存大小。有关实施示例，请参阅 [Stream compressed content example](olap-writing-lambda.md#olap-getobject-response)（流式压缩内容示例）。