教程:将 Amazon Lambda 与 Amazon Simple Notification Service 结合使用 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

教程:将 Amazon Lambda 与 Amazon Simple Notification Service 结合使用

您可以在一个Amazon账户中使用 Lambda 函数以实现在另一Amazon账户中订阅 Amazon SNS 主题。在本教程中,您使用 Amazon Command Line Interface 执行 Amazon Lambda 操作,例如,创建 Lambda 函数,创建 Amazon SNS 主题以及授予权限以允许这两类资源相互访问。

先决条件

本教程假设您对 Lambda 基本操作和 Lambda 控制台有一定了解。如果您还没有了解,请按照 使用控制台创建 Lambda 函数 中的说明创建您的第一个 Lambda 函数。

要完成以下步骤,您需要命令行终端或 Shell,以便运行命令。在单独的数据块中列出了命令和预期输出:

aws --version

您应看到以下输出:

aws-cli/2.0.57 Python/3.7.4 Darwin/19.6.0 exe/x86_64

对于长命令,使用转义字符 (\) 将命令拆分为多行。

在 Linux 和 macOS 中,可使用您首选的外壳程序和程序包管理器。在 Windows 10 中,您可以 安装 Windows Subsystem for Linux,获取 Ubuntu 和 Bash 与 Windows 集成的版本。

在本教程中,您将使用两个账户。Amazon CLI 命令通过以下方式对此进行说明:使用两个已命名配置文件,每个配置为用于不同的账户。如果您使用具有不同名称的配置文件,或者使用默认配置文件和一个命名配置文件,请根据需要修改命令。

创建 Amazon SNS 主题(账户 A)

账户 A 中,创建源 Amazon SNS 主题。

aws sns create-topic --name sns-topic-for-lambda --profile accountA

创建该主题后,记录其 Amazon Resource Name(ARN)。以后向 Lambda 函数添加权限以订阅主题时,将需要使用此 ARN。

创建执行角色(账户 B)

账户 B 中,创建将向函数授予访问 Amazon 资源的权限的执行角色

创建执行角色

  1. 在 IAM 控制台中,打开 Roles(角色)页面

  2. 选择 Create role(创建角色)。

  3. 创建具有以下属性的角色。

    • Trusted entity(可信任的实体)– Amazon Lambda

    • Permissions(权限)– AWSLambdaBasicExecutionRole

    • Role name(角色名称)– lambda-sns-role

AWSLambdaBasicExecutionRole 策略具有函数将日志写入 CloudWatch Logs 所需的权限。

创建 Lambda 函数(账户 B)

账户 B 中,创建将用来处理 Amazon SNS 中事件的函数。以下示例代码接收 Amazon SNS 事件输入并对其所包含的消息进行处理。为了展示这个过程,代码会将一些传入的事件数据写入 CloudWatch Logs。

注意

有关使用其他语言的示例代码,请参阅 示例 函数代码

例 index.js

console.log('Loading function'); exports.handler = function(event, context, callback) { // console.log('Received event:', JSON.stringify(event, null, 4)); var message = event.Records[0].Sns.Message; console.log('Message received from SNS:', message); callback(null, "Success"); };

创建函数

  1. 将示例代码复制到名为 index.js 的文件中。

  2. 创建部署程序包。

    zip function.zip index.js
  3. 使用 create-function 命令创建 Lambda 函数。

    aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --role arn:aws:iam::<AccountB_ID>:role/service-role/lambda-sns-execution-role \ --timeout 60 --profile accountB

创建该函数后,记录其函数 ARN。以后在添加权限以允许 Amazon SNS 调用该函数时,将需要使用此 ARN。

设置跨账户权限(账户 A 和 B 账户)

账户 A 中,授予账户 B 订阅该主题的权限:

aws sns add-permission --label lambda-access --aws-account-id <AccountB_ID> \ --topic-arn arn:aws:sns:us-east-2:<AccountA_ID>:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA

账户 B 中,添加允许从 Amazon SNS 进行调用的 Lambda 权限。

aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:us-east-2:<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-2:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-2:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns1\"}" }

在添加策略时,请不要使用 --source-account 参数将源账户添加到 Lambda 策略。Amazon SNS 事件源不支持源账户,并且将导致访问被拒绝。

注意

如果在选择加入型区域中托管具有 SNS 主题的账户,则需要在主体中指定区域。例如,假设您正在亚太地区(香港)区域使用一个 SNS 主题,则需要为主体指定 sns.ap-east-1.amazonaws.com,而不是 sns.amazonaws.com

创建订阅(账户 B)

账户 B 中,将该 Lambda 函数订阅到该主题。在将消息发送到账户 A 中的 sns-topic-for-lambda 主题时,Amazon SNS 将调用账户 B 中的 Function-With-SNS 函数。

aws sns subscribe --protocol lambda \ --topic-arn arn:aws:sns:us-east-2:<AccountA_ID>:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-2:<AccountB_ID>:function:Function-With-SNS \ --profile accountB

您应看到以下输出:

{ "SubscriptionArn": "arn:aws:sns:us-east-2:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }

输出包含主题订阅的 ARN。

测试订阅(账户 A)

账户 A 中测试订阅。在一个文本文件中键入 Hello World,并将该文本文件另存为 message.txt。然后运行以下命令:

aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:us-east-2:<AccountA_ID>:sns-topic-for-lambda \ --profile accountA

这将返回一个具有唯一标识符的消息 ID,指示 Amazon SNS 服务已接受消息。然后,Amazon SNS 则尝试将它传输给主题订阅者。或者,您可以直接将 JSON 字符串提供给 message 参数,但使用文本文件将允许消息中出现换行符。

要了解有关 Amazon SNS 的更多信息,请参阅什么是 Amazon Simple Notification Service

清除资源

除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 Amazon 资源,可防止您的 Amazon 账户产生不必要的费用。

账户 A 中,清理您的 Amazon SNS 主题。

删除 Amazon SNS 主题

  1. 打开 Amazon SNS 控制台中的 Topics(主题)页面

  2. 选择您已创建的主题。

  3. 选择 Delete

  4. 在文本框中输入 delete me

  5. 选择 Delete

账户 B 中,清理您的执行角色、Lambda 函数和 Amazon SNS 订阅。

删除执行角色

  1. 打开 IAM 控制台的 Roles(角色)页面

  2. 选择您创建的执行角色。

  3. 选择 Delete role(删除角色)。

  4. 选择 Yes, delete(是,删除)。

删除 Lambda 函数

  1. 打开 Lamba 控制台的 Functions(函数)页面

  2. 选择您创建的函数。

  3. 选择 Actions (操作),然后选择 Delete (删除)

  4. 选择 Delete

删除 Amazon SNS 订阅

  1. 在 Amazon SNS 控制台中打开 Subscription(订阅)页面

  2. 选择您已创建的订阅。

  3. 选择 Delete(删除),Delete(删除)。