在本教程中,您将创建并配置 Lambda 函数,用于调整添加到 Amazon Simple Storage Service(Amazon S3)存储桶的图像大小。当您向存储桶添加图像文件时,Amazon S3 会调用您的 Lambda 函数。然后,该函数会创建图像的缩略图版本,并将其输出到不同的 Amazon S3 存储桶。

要完成本教程,请执行以下步骤:
-
创建源和目标 Amazon S3 存储桶并上传示例图片。
-
创建一个 Lambda 函数,用于调整图像大小并将缩略图输出到 Amazon S3 存储桶。
-
配置一个 Lambda 触发器,该触发器将在对象上传到源存储桶时调用函数。
-
若要测试您的函数,先使用虚拟事件,然后将图像上传到源存储桶。
完成这些步骤后,您将了解如何使用 Lambda 对添加到 Amazon S3 存储桶的对象执行文件处理任务。您可以使用 AWS Command Line Interface 或 AWS CLI (AWS Management Console) 完成此教程。
如果您相同通过更简单的示例来了解如何为 Lambda 配置 Amazon S3 触发器,则可以参阅教程:使用 Amazon S3 触发器调用 Lambda 函数。
主题
先决条件
如果您想使用 AWS CLI 来完成教程,请安装最新版本的 AWS Command Line Interface。
对于 Lambda 函数代码,您可以使用 Python 或 Node.js。为您要使用的语言安装语言支持工具和软件包管理器。
如果您尚未安装 AWS Command Line Interface,请按照安装或更新最新版本的 AWS CLI 中的步骤进行安装。
本教程需要命令行终端或 Shell 来运行命令。在 Linux 和 macOS 中,可使用您首选的 Shell 和程序包管理器。
注意
在 Windows 中,操作系统的内置终端不支持您经常与 Lambda 一起使用的某些 Bash CLI 命令(例如 zip
)。安装 Windows Subsystem for Linux
创建两个 Amazon S3 存储桶

先创建两个 Amazon S3 存储桶。第一个存储桶是您要向其上传图像的源存储桶。第二个存储桶是 Lambda 用来保存调用函数时调整大小后的缩略图。
创建 Amazon S3 存储桶(控制台)
-
打开 Amazon S3 控制台
并选择通用存储桶页面。 -
选择最接近您地理位置的 AWS 区域。您可以使用屏幕顶部的下拉列表更改区域。在本教程的后面部分,您必须在同个区域中创建 Lambda 函数。
-
选择 Create bucket(创建存储桶)。
-
在 General configuration(常规配置)下,执行以下操作:
-
对于存储桶类型,确保选中通用型。
-
对于存储桶名称,输入符合 Amazon S3 存储桶命名规则的全局唯一名称。存储桶名称只能由小写字母、数字、句点(.)和连字符(-)组成。
-
-
将所有其他选项设置为默认值并选择创建存储桶。
-
重复步骤 1 到 5 以创建自己的目标存储桶。在存储桶名称中输入
,其中amzn-s3-demo-source-bucket-resized
是您刚刚创建的源存储桶的名称。amzn-s3-demo-source-bucket
将测试图片上传到源存储桶

在本教程的后面部分,您将使用 AWS CLI 或 Lambda 控制台调用 Lambda 函数以对其进行测试。要确认函数是否正常运行,您的源存储桶需要包含测试图片。此图像可以是您选择的任何 JPG 或 PNG 文件。
将测试图片上传到源存储桶(控制台)
-
打开 Amazon S3 控制台的存储桶
页面。 -
选择您在上一步中创建的源存储桶。
-
选择上传。
-
选择添加文件,然后使用文件选择器选择要上传的对象。
-
选择打开,然后选择上传。
创建权限策略

创建 Lambda 函数的第一步是创建权限策略。此策略为函数提供访问其他 AWS 资源所需的权限。在本教程中,此策略授予了 Lambda 对 Amazon S3 存储桶的读取和写入权限,并允许其写入 Amazon CloudWatch Logs。
创建策略(控制台)
-
打开 AWS Identity and Access Management IAM 控制台的 Policies(策略)页面
。 -
选择 创建策略。
-
选择 JSON 选项卡,然后将以下自定义策略粘贴到 JSON 编辑器中。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:PutLogEvents", "logs:CreateLogGroup", "logs:CreateLogStream" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::*/*" }, { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::*/*" } ] }
-
选择下一步。
-
在策略详细信息下,为策略名称输入
。LambdaS3Policy
-
选择 创建策略。
创建执行角色

执行角色是一个 IAM 角色,用于向 Lambda 函数授予访问 AWS 服务 和资源的权限。要授予函数读取和写入 Amazon S3 存储桶的权限,您需要附加上一步中创建的权限策略。
创建执行角色并附加权限策略(控制台)
-
打开(IAM)控制台的角色
页面。 -
选择 Create role(创建角色)。
-
在可信实体类型中选择 AWS 服务,在使用案例中选择 Lambda。
-
选择下一步。
-
执行以下操作添加您在上一步中创建的权限策略:
-
在策略搜索框中,输入
。LambdaS3Policy
-
在搜索结果中,选中
LambdaS3Policy
的复选框。 -
选择下一步。
-
-
在角色详细信息下的角色名称中输入
。LambdaS3Role
-
选择 Create role(创建角色)。
创建函数部署包

要创建函数,您需要创建包含函数代码和所有依赖项的部署包。对于此 CreateThumbnail
函数,您的函数代码使用单独的库来调整图像大小。按照所选语言的说明创建包含所需库的部署包。
创建部署包(Node.js)
-
为您的函数代码和依赖项创建一个名为
lambda-s3
的目录并导航到此目录。mkdir lambda-s3 cd lambda-s3
-
使用
npm
创建新的 Node.js 项目。要在交互式体验中接受提供的默认选项,请按Enter
。npm init
-
将以下函数代码保存在名为
index.mjs
的文件中。请务必将us-east-1
替换您创建源存储桶和目标存储桶时所在的 AWS 区域。// dependencies import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'; import { Readable } from 'stream'; import sharp from 'sharp'; import util from 'util'; // create S3 client const s3 = new S3Client({region:
'us-east-1'
}); // define the handler function export const handler = async (event, context) => { // Read options from the event parameter and get the source bucket console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); const srcBucket = event.Records[0].s3.bucket.name; // Object key may have spaces or unicode non-ASCII characters const srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")); const dstBucket = srcBucket + "-resized"; const dstKey = "resized-" + srcKey; // Infer the image type from the file suffix const typeMatch = srcKey.match(/\.([^.]*)$/); if (!typeMatch) { console.log("Could not determine the image type."); return; } // Check that the image type is supported const imageType = typeMatch[1].toLowerCase(); if (imageType != "jpg" && imageType != "png") { console.log(`Unsupported image type: ${imageType}`); return; } // Get the image from the source bucket. GetObjectCommand returns a stream. try { const params = { Bucket: srcBucket, Key: srcKey }; var response = await s3.send(new GetObjectCommand(params)); var stream = response.Body; // Convert stream to buffer to pass to sharp resize function. if (stream instanceof Readable) { var content_buffer = Buffer.concat(await stream.toArray()); } else { throw new Error('Unknown object stream type'); } } catch (error) { console.log(error); return; } // set thumbnail width. Resize will set the height automatically to maintain aspect ratio. const width = 200; // Use the sharp module to resize the image and save in a buffer. try { var output_buffer = await sharp(content_buffer).resize(width).toBuffer(); } catch (error) { console.log(error); return; } // Upload the thumbnail image to the destination bucket try { const destparams = { Bucket: dstBucket, Key: dstKey, Body: output_buffer, ContentType: "image" }; const putResult = await s3.send(new PutObjectCommand(destparams)); } catch (error) { console.log(error); return; } console.log('Successfully resized ' + srcBucket + '/' + srcKey + ' and uploaded to ' + dstBucket + '/' + dstKey); }; -
在
lambda-s3
目录中,使用 npm 安装 sharp 库。请注意,最新版本的 sharp(0.33)与 Lambda 不兼容。安装版本 0.32.6 以完成本教程。npm install sharp@0.32.6
npm
install
命令会为模块创建node_modules
目录。完成此步骤后,目录结构应如下所示:lambda-s3 |- index.mjs |- node_modules | |- base64js | |- bl | |- buffer ... |- package-lock.json |- package.json
-
创建一个包含函数代码和依赖项的部署包。在 MacOS 或 Linux 中,运行以下命令。
zip -r function.zip .
在 Windows 中,使用您首选的 ZIP 实用工具来创建 .zip 文件。确保您的
index.mjs
、package.json
、和package-lock.json
文件以及您的node_modules
目录都在.zip 文件的根目录中。
创建 Lambda 函数

您也可以使用 AWS CLI 或 Lambda 控制台创建 Lambda 函数。按照所选语言的说明创建函数。
创建函数(控制台)
要使用控制台创建 Lambda 函数,首先要创建包含一些“Hello world”代码的基本函数。然后,通过上传在上一步中创建的 .zip 或 JAR 文件,将此代码替换为自己的函数代码。
-
打开 Lamba 控制台的函数页面
。 -
确保您在创建 Amazon S3 存储桶所在的同一 AWS 区域 内操作。您可以使用屏幕顶部的下拉列表更改区域。
-
选择 Create function (创建函数)。
-
选择从头开始创作。
-
在基本信息中,执行以下操作:
-
对于 Function name(函数名称),请输入
。CreateThumbnail
-
对于运行时,根据您为函数选择的语言,选择 Node.js 22.x 或 Python 3.12。
-
对于架构,选择 x86_64。
-
-
在更改默认执行角色选项卡中,执行以下操作:
-
展开选项卡,然后选择使用现有角色。
-
选择您之前创建的
LambdaS3Role
。
-
-
选择 Create function (创建函数)。
上传函数代码(控制台)
-
在代码源窗格中,选择上传自。
-
选择 .zip 文件。
-
选择上传。
-
在文件选择器中,选择 .zip 文件,然后选择打开。
-
选择保存。
配置 Amazon S3 来调用函数

要在将图像上传到源存储桶时运行 Lambda 函数,您需要为函数配置触发器。您可以使用控制台或 AWS CLI 配置 Amazon S3 触发器。
重要
此程序将 Amazon S3 存储桶配置为每次在此存储桶中创建对象时调用您的函数。请确保仅在源存储桶上配置。如果您的 Lambda 函数在调用此函数的同一个存储桶中创建对象,则可以在循环中持续调用
配置 Amazon S3 触发器(控制台)
-
打开 Lambda 控制台的函数页面
,然后选择函数 ( CreateThumbnail
)。 -
选择添加触发器。
-
选择 S3。
-
在存储桶下,选择自己的源存储桶。
-
在事件类型下,选择所有对象创建事件。
-
在递归调用下,选中复选框以确认知晓不建议使用相同的 Amazon S3 存储桶用于输入和输出。您可以阅读 Serverless Land 中的 Recursive patterns that cause run-away Lambda functions
,进一步了解 Lambda 中的递归调用模式。 -
选择 添加。
在您使用 Lambda 控制台创建触发器时,Lambda 会自动创建基于资源的策略,授予您选择的服务调用函数的权限。
使用虚拟事件测试 Lambda 函数

在通过向 Amazon S3 源存储桶添加图像文件来测试整个设置之前,您可以通过使用虚拟事件调用 Lambda 函数来测试此函数是否正常运行。Lambda 中的事件是 JSON 格式的文档,其中包含要处理的函数数据。Amazon S3 调用您的函数时,发送到函数的事件包含存储桶名称、存储桶 ARN 和对象键等信息。
使用虚拟事件测试 Lambda 函数(控制台)
-
打开 Lambda 控制台的函数页面
,然后选择函数 ( CreateThumbnail
)。 -
选择测试选项卡。
-
要创建测试事件,在测试事件窗格中,执行以下操作:
-
在测试事件操作下,选择创建新事件。
-
对于事件名称,输入
myTestEvent
。 -
在模板中,选择 S3 Put。
-
将以下参数的值替换为您自己的值。
-
对于
awsRegion
,将us-east-1
替换为在其中创建 Amazon S3 存储桶的 AWS 区域。 -
对于
name
,将amzn-s3-demo-bucket
替换为您自己的 Amazon S3 源存储桶的名称。 -
对于
key
,将test%2Fkey
替换为您在步骤 将测试图片上传到源存储桶 中上传到源存储桶的测试对象的文件名。
{ "Records": [ { "eventVersion": "2.0", "eventSource": "aws:s3", "awsRegion":
"us-east-1"
, "eventTime": "1970-01-01T00:00:00.000Z", "eventName": "ObjectCreated:Put", "userIdentity": { "principalId": "EXAMPLE" }, "requestParameters": { "sourceIPAddress": "127.0.0.1" }, "responseElements": { "x-amz-request-id": "EXAMPLE123456789", "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH" }, "s3": { "s3SchemaVersion": "1.0", "configurationId": "testConfigRule", "bucket": { "name":"amzn-s3-demo-bucket"
, "ownerIdentity": { "principalId": "EXAMPLE" }, "arn": "arn:aws:s3:::amzn-s3-demo-bucket" }, "object": { "key":"test%2Fkey"
, "size": 1024, "eTag": "0123456789abcdef0123456789abcdef", "sequencer": "0A1B2C3D4E5F678901" } } } ] } -
-
选择保存。
-
-
在测试事件窗格中,选择测试。
-
要检查您的函数是否已创建图像的调整大小版本并将其存储在目标 Amazon S3 存储桶中,请执行以下操作:
-
打开 Amazon S3 控制台的存储桶页面
。 -
选择目标存储桶并确认调整大小的文件已在对象窗格中列出。
-
使用 Amazon S3 触发器测试函数

此时,您已确认 Lambda 函数运行正常,您可以通过向 Amazon S3 源存储桶添加图像文件来测试完整设置。将图像添加到源存储桶时,应自动调用 Lambda 函数。函数会创建文件已调整大小的版本并将其存储在目标存储桶中。
使用 Amazon S3 触发器测试 Lambda 函数(控制台)
清除资源
除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 AWS 资源,可防止您的 AWS 账户 产生不必要的费用。
删除 Lambda 函数
-
打开 Lamba 控制台的 Functions(函数)页面
。 -
选择您创建的函数。
-
依次选择操作和删除。
-
在文本输入字段中键入
confirm
,然后选择 Delete(删除)。
删除您创建的策略
-
打开 IAM 控制台的 Policies(策略)页面
。 -
选择您创建的策略 (AWSLambdaS3Policy)。
-
选择 Policy actions(策略操作)、Delete(删除)。
-
选择 Delete(删除)。
删除执行角色
-
打开 IAM 控制台的角色页面
。 -
选择您创建的执行角色。
-
选择删除。
-
在文本输入字段中输入角色名称,然后选择 Delete(删除)。
删除 S3 存储桶
-
打开 Amazon S3 控制台
。 -
选择您创建的存储桶。
-
选择删除。
-
在文本输入字段中输入存储桶的名称。
-
选择删除存储桶。