本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
教程:将 Amazon Lambda 与 Amazon Simple Notification Service 结合使用
在本教程中,您将使用某个 Amazon Web Services 账户 中的 Lambda 函数,订阅独立 Amazon Web Services 账户 中的 Amazon Simple Notification Service(Amazon SNS)主题。当您向 Amazon SNS 主题发布消息时,您的 Lambda 函数会读取消息内容并将其输出到亚马逊日志。 CloudWatch 要完成此教程,需要使用 Amazon Command Line Interface(Amazon CLI)。
要完成本教程,请执行以下步骤:
-
在账户 A 中,创建 Amazon SNS 主题。
-
在账户 B 中,创建可从该主题读取消息的 Lambda 函数。
-
在账户 B 中,创建该主题的订阅。
-
向账户 A 中的 Amazon SNS 主题发布消息,并确认账户 B 中的 Lambda 函数将其输出到日志。 CloudWatch
通过完成这些步骤,您将了解如何配置 Amazon SNS 主题以调用 Lambda 函数。您还将了解如何创建 Amazon Identity and Access Management(IAM)策略,向其他 Amazon Web Services 账户 中的资源授予调用 Lambda 的权限。
在本教程中,您将使用两个独立的 Amazon Web Services 账户。Amazon CLI 命令通过以下方式对此进行说明:使用两个名为 accountA
和 accountB
的命名配置文件,每个文件配置为用于不同的 Amazon Web Services 账户。要了解如何配置 Amazon CLI 以使用不同的配置文件,请参阅《Amazon Command Line Interface User Guide for Version 2》中的 Configuration and credential file settings。确保为两个配置文件配置相同的默认值 Amazon Web Services 区域。
如果您为两个 Amazon Web Services 账户 创建的 Amazon CLI 配置文件使用不同名称,或者使用默认配置文件和一个命名配置文件,请根据需要按照以下步骤修改 Amazon CLI 命令。
先决条件
如果您还没有 Amazon Web Services 账户,请完成以下步骤来创建一个。
注册 Amazon Web Services 账户
按照屏幕上的说明进行操作。
在注册时,将接到一通电话,要求使用电话键盘输入一个验证码。
当您注册 Amazon Web Services 账户时,系统将会创建一个 Amazon Web Services 账户根用户。根用户有权访问该账户中的所有 Amazon Web Services 和资源。作为安全最佳实践,请为管理用户分配管理访问权限,并且只使用根用户执行 需要根用户访问权限的任务。
注册过程完成后,Amazon 会向您发送一封确认电子邮件。在任何时候,您都可以通过转至 https://aws.amazon.com/
注册 Amazon Web Services 账户 后,启用多重身份验证 (MFA) 保护您的管理用户。有关说明,请参阅《IAM 用户指南》中的为为 IAM 用户(控制台)启用虚拟 MFA 设备。
要授予其他用户访问您的 Amazon Web Services 账户资源的权限,请创建 IAM 用户。为了保护您的 IAM 用户,请启用 MFA 并仅向 IAM 用户授予执行任务所需的权限。
有关创建和保护 IAM 用户的更多信息,请参阅《IAM 用户指南》中的以下主题:
如果您尚未安装 Amazon Command Line Interface,请按照安装或更新最新版本的 Amazon CLI 中的步骤进行安装。
本教程需要命令行终端或 Shell 来运行命令。在 Linux 和 macOS 中,可使用您首选的 Shell 和程序包管理器。
注意
在 Windows 中,操作系统的内置终端不支持您经常与 Lambda 一起使用的某些 Bash CLI 命令(例如 zip
)。安装 Windows Subsystem for Linux
创建 Amazon SNS 主题(账户 A)
创建 主题
-
在账户 A 中,使用以下 Amazon CLI 命令创建 Amazon SNS 标准主题。
aws sns create-topic --name sns-topic-for-lambda --profile accountA
您应该可以看到类似于如下所示的输出内容。
{ "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda" }
记下主题的 Amazon 资源名称(ARN)。稍后在本教程中向 Lambda 函数添加权限以订阅主题时,将需要使用此 ARN。
创建函数执行角色(账户 B)
执行角色是一个 IAM 角色,用于向 Lambda 函数授予访问 Amazon 服务和资源的权限。在账户 B 中创建函数之前,您需要创建一个角色,该角色向该函数授予将日志写入日志的基本权限。 CloudWatch 我们将在后续步骤中添加读取 Amazon SNS 主题的权限。
创建执行角色
-
在账户 B 中,打开 IAM 控制台中的角色页面
。 -
选择创建角色。
-
在可信实体类型中选择 Amazon 服务。
-
在使用案例中选择 Lambda。
-
选择下一步。
-
通过执行以下操作,向角色添加基本权限策略:
-
在权限策略搜索框中输入
AWSLambdaBasicExecutionRole
。 -
选择下一步。
-
-
通过执行以下操作,完成角色创建:
-
在角色详细信息下的角色名称中输入
lambda-sns-role
。 -
选择创建角色。
-
创建 Lambda 函数(账户 B)
创建一个处理您的 Amazon SNS 消息的 Lambda 函数。函数代码将每条记录的消息内容记录到 Amazon CloudWatch Logs 中。
本教程使用 Node.js 18.x 运行时系统,但我们还提供了其他运行时系统语言的示例代码。您可以选择以下框中的选项卡,查看适用于您感兴趣的运行时系统的代码。您将在此步骤中使用的 JavaScript 代码位于JavaScript选项卡中显示的第一个示例中。
创建函数
-
为项目创建一个目录,然后切换到该目录。
mkdir sns-tutorial cd sns-tutorial
-
将示例 JavaScript 代码复制到名为的新文件中
index.js
。 -
使用以下
zip
命令创建部署包。zip function.zip index.js
-
运行以下 Amazon CLI 命令,在账户 B 中创建 Lambda 函数。
aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \ --role arn:aws:iam::
<AccountB_ID>
:role/lambda-sns-role \ --timeout 60 --profile accountB您应该可以看到类似于如下所示的输出内容。
{ "FunctionName": "Function-With-SNS", "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS", "Runtime": "nodejs18.x", "Role": "arn:aws:iam::123456789012:role/lambda_basic_role", "Handler": "index.handler", ... "RuntimeVersionConfig": { "RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206" } }
-
记下函数的 Amazon 资源名称(ARN)。稍后在本教程中添加权限以允许 Amazon SNS 调用函数时,将需要使用此 ARN。
向函数添加权限(账户 B)
要让 Amazon SNS 调用函数,您需要在基于资源的策略语句中向其授予权限。您可以使用 Amazon CLI add-permission
命令添加此语句。
授予 Amazon SNS 调用函数的权限
-
在账户 B 中,使用之前记下的 Amazon SNS 主题的 ARN 运行以下 Amazon CLI 命令。
aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:
us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --statement-id function-with-sns --action "lambda:InvokeFunction" \ --principal sns.amazonaws.com --profile accountB您应该可以看到类似于如下所示的输出内容。
{ "Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\": \"arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns\"}" }
注意
如果在选择加入型 Amazon Web Services 区域 中托管具有 Amazon SNS 主题的账户,则需要在主体中指定区域。例如,假设您正在亚太地区(香港)区域使用一个 Amazon SNS 主题,则需要为主体指定 sns.ap-east-1.amazonaws.com
,而不是 sns.amazonaws.com
。
授予 Amazon SNS 订阅的跨账户权限(账户 A)
要让账户 B 中的 Lambda 函数订阅您在账户 A 中创建的 Amazon SNS 主题,您需要向账户 B 授予订阅主题的权限。您可以使用 Amazon CLI add-permission
命令授予此权限。
授予账户 B 订阅主题的权限
-
在账户 A 中,运行以下 Amazon CLI 命令。使用之前记下的 Amazon SNS 主题的 ARN。
aws sns add-permission --label lambda-access --aws-account-id
<AccountB_ID>
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA
创建订阅(账户 B)
在账户 B 中,您现在将 Lambda 函数订阅到教程开始时您在账户 A 中创建的 Amazon SNS 主题。当消息发送到该主题 (sns-topic-for-lambda
) 后,Amazon SNS 会调用账户 B 中的 Lambda 函数 Function-With-SNS
。
创建订阅
-
在账户 B 中,运行以下 Amazon CLI 命令。使用您在其中创建主题的默认区域以及主题和 Lambda 函数的 ARN。
aws sns subscribe --protocol lambda \ --region
us-east-1
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>
:function:Function-With-SNS \ --profile accountB您应该可以看到类似于如下所示的输出内容。
{ "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }
将消息发布到主题(账户 A 和账户 B)
账户 B 中的 Lambda 函数现已订阅账户 A 中的 Amazon SNS 主题,现在可以通过将消息发布到主题来测试设置了。要确认 Amazon SNS 是否已调用您的 Lambda 函数,您可以使用 CloudWatch 日志来查看函数的输出。
将消息发布到主题并查看函数的输出
-
在文本文件中输入
Hello World
,并将其另存为message.txt
。 -
在保存文本文件的同一目录中,在账户 A 中运行以下 Amazon CLI 命令。将 ARN 用于您自己的主题。
aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:
us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --profile accountA这将返回一个具有唯一标识符的消息 ID,表明 Amazon SNS 服务已接受该消息。然后,Amazon SNS 则尝试将消息传输给主题订阅用户。要确认 Amazon SNS 是否已调用您的 Lambda 函数,请使用 CloudWatch 日志查看您的函数的输出:
-
在账户 B 中,打开 Amazon CloudWatch 控制台的日志组
页面。 -
选择函数 (
/aws/lambda/Function-With-SNS
) 的日志组。 -
选择最新的日志流。
-
如果函数已正确调用,您将看到类似于以下内容的输出,其中会显示发布到主题的消息内容。
2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World 2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done
清除资源
除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 Amazon 资源,可防止您的 Amazon 账户产生不必要的费用。
在账户 A 中,清理您的 Amazon SNS 主题。
删除 Amazon SNS 主题
-
打开 Amazon SNS 控制台中的 Topics(主题)页面
。 -
选择您已创建的主题。
-
选择 Delete(删除)。
-
在文本输入字段中输入
delete me
。 -
选择删除。
在账户 B 中,清理您的执行角色、Lambda 函数和 Amazon SNS 订阅。
删除执行角色
-
打开 IAM 控制台的角色页面
。 -
选择您创建的执行角色。
-
选择删除。
-
在文本输入字段中输入角色名称,然后选择 Delete(删除)。
删除 Lambda 函数
-
打开 Lamba 控制台的 Functions(函数)页面
。 -
选择您创建的函数。
-
依次选择操作和删除。
-
在文本输入字段中键入
delete
,然后选择 Delete(删除)。
删除 Amazon SNS 订阅
-
在 Amazon SNS 控制台中打开 Subscription(订阅)页面
。 -
选择您已创建的订阅。
-
选择 Delete(删除),Delete(删除)。