

# 教程：将跨账户 Amazon SQS 队列用作事件源
<a name="with-sqs-cross-account-example"></a>

在此教程中，您将创建一个使用来自不同 Amazon 账户中 Amazon Simple Queue Service (Amazon SQS) 队列的消息的 Lambda 函数。本教程涉及两个 Amazon 账户：**账户 A** 指包含您的 Lambda 函数的账户，而**账户 B** 指包含 Amazon SQS 队列的账户。

## 先决条件
<a name="with-sqs-cross-account-prepare"></a>

### 安装 Amazon Command Line Interface
<a name="install_aws_cli"></a>

如果您尚未安装 Amazon Command Line Interface，请按照[安装或更新最新版本的 Amazon CLI](https://docs.amazonaws.cn/cli/latest/userguide/getting-started-install.html) 中的步骤进行安装。

本教程需要命令行终端或 Shell 来运行命令。在 Linux 和 macOS 中，可使用您首选的 Shell 和程序包管理器。

**注意**  
在 Windows 中，操作系统的内置终端不支持您经常与 Lambda 一起使用的某些 Bash CLI 命令（例如 `zip`）。[安装 Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10)，获取 Ubuntu 和 Bash 与 Windows 集成的版本。

## 创建执行角色（账户 A）
<a name="with-sqs-cross-account-create-execution-role"></a>

在**账户 A** 中，创建一个[执行角色](lambda-intro-execution-role.md)，该角色向您的函数授予访问所需 Amazon 资源的权限。

**创建执行角色**

1. 在 Amazon Identity and Access Management IAM 控制台中，打开 [Roles (角色) 页面](https://console.amazonaws.cn/iam/home#/roles)。

1. 选择 **Create role**（创建角色）。

1. 创建具有以下属性的角色。
   + **Trusted entity (可信任的实体)** – **Amazon Lambda**
   + **Permissions（权限）** – **AWSLambdaSQSQueueExecutionRole**
   + **Role name**（角色名称）– **cross-account-lambda-sqs-role**

**AWSLambdaSQSQueueExecutionRole** 策略具有该函数从 Amazon SQS 中读取项目并将日志写入 Amazon CloudWatch Logs 所需的权限。

## 创建函数（账户 A）
<a name="with-sqs-cross-account-create-function"></a>

在**账户 A** 中，创建一个处理您 Amazon SQS 消息的 Lambda 函数。Lambda 函数和 Amazon SQS 队列必须位于同一 Amazon Web Services 区域。

下列 Node.js 代码示例将每条消息写入 CloudWatch Logs 中的日志。

**Example index.mjs**  

```
export const handler = async function(event, context) {
  event.Records.forEach(record => {
    const { body } = record;
    console.log(body);
  });
  return {};
}
```

**创建函数**
**注意**  
按照这些步骤在将创建一个 Node.js 函数。对于其他语言，步骤类似，但有些细节不同。

1. 将代码示例保存为名为 `index.mjs` 的文件。

1. 创建部署程序包。

   ```
   zip function.zip index.mjs
   ```

1. 使用 `create-function` Amazon Command Line Interface (Amazon CLI) 命令创建函数。将 `arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role` 替换为您之前创建的执行角色的 ARN。

   ```
   aws lambda create-function --function-name CrossAccountSQSExample \
   --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
   --role arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role
   ```

## 测试函数（账户 A）
<a name="with-sqs-cross-account-create-test-function"></a>

在**账户 A** 中，使用 `invoke` Amazon CLI 命令和示例 Amazon SQS 事件手动调用 Lambda 函数。

如果该处理程序正常返回并且没有异常，则 Lambda 认为该消息得到成功处理并开始读取队列中的新消息。成功处理消息后，Lambda 从队列中将其自动删除。如果该处理程序引发异常，则 Lambda 认为消息的批量处理并未成功进行，并且 Lambda 会用相同的批量消息调用该函数。

1. 将下列 JSON 保存为名为 `input.txt` 的文件。

   ```
   {
       "Records": [
           {
               "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
               "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
               "body": "test",
               "attributes": {
                   "ApproximateReceiveCount": "1",
                   "SentTimestamp": "1545082649183",
                   "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                   "ApproximateFirstReceiveTimestamp": "1545082649185"
               },
               "messageAttributes": {},
               "md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
               "eventSource": "aws:sqs",
               "eventSourceARN": "arn:aws:sqs:us-east-1:111122223333:example-queue",
               "awsRegion": "us-east-1"
           }
       ]
   }
   ```

   上述 JSON 模拟 Amazon SQS 可能发送到您的 Lambda 函数的事件，其中 `"body"` 包含来自该队列的实际消息。

1. 运行以下 `invoke` Amazon CLI 命令。

   ```
   aws lambda invoke --function-name CrossAccountSQSExample \
   --cli-binary-format raw-in-base64-out \
   --payload file://input.txt outputfile.txt
   ```

   如果使用 **cli-binary-format** 版本 2，则 Amazon CLI 选项是必需的。要将其设为默认设置，请运行 `aws configure set cli-binary-format raw-in-base64-out`。有关更多信息，请参阅*版本 2 的 Amazon Command Line Interface 用户指南*中的 [Amazon CLI 支持的全局命令行选项](https://docs.amazonaws.cn/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。

1. 在 `outputfile.txt` 文件中验证输出。

## 创建 Amazon SQS 队列（账户 B）。
<a name="with-sqs-cross-account-configure-sqs"></a>

在**账户 B** 中，创建一个可由**账户 A** 中 Lambda 函数用作事件源的 Amazon SQS 队列。Lambda 函数和 Amazon SQS 队列必须位于同一 Amazon Web Services 区域。

**创建队列**

1. 打开 [Amazon SQS 控制台](https://console.amazonaws.cn/sqs)。

1. 选择**创建队列**。

1. 创建具有以下属性的队列。
   + **类型** - **标准**
   + **名称** - **LambdaCrossAccountQueue**
   + **配置** - 保留默认设置。
   + **访问策略** - 选择 **Advanced (高级)**。粘贴以下 JSON 策略。替换以下值：
     + `111122223333`：**账户 A** 的 Amazon Web Services 账户 ID
     + `444455556666`：**账户 B** 的 Amazon Web Services 账户 ID

------
#### [ JSON ]

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Id": "Queue1_Policy_UUID",
         "Statement": [
             {
                 "Sid": "Queue1_AllActions",
                 "Effect": "Allow",
                 "Principal": {
                     "AWS": [
                         "arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role"
                     ]
                 },
                 "Action": "sqs:*",
                 "Resource": "arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue"
             }
         ]
     }
     ```

------

     此策略授予**账户 A** 中 Lambda 执行角色权限，以使用 Amazon SQS 队列中的消息。

1. 创建队列后，记录其 Amazon Resource Name (ARN)。在下一步中将该队列与您的 Lambda 函数关联时，您将需要此类信息。

## 配置事件源（帐户 A）
<a name="with-sqs-cross-account-event-source"></a>

在**账户 A** 中，通过运行以下 `create-event-source-mapping` Amazon CLI 命令创建**账户 B** 中 Amazon SQS 队列和 Lambda 函数之间的事件源映射。将 `arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue` 替换为在上一步中创建的 Amazon SQS 队列的 ARN。

```
aws lambda create-event-source-mapping --function-name CrossAccountSQSExample --batch-size 10 \
--event-source-arn arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue
```

要获取您的事件源映射的列表，请运行下列命令。

```
aws lambda list-event-source-mappings --function-name CrossAccountSQSExample \
--event-source-arn arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue
```

## 测试设置
<a name="with-sqs-final-integration-test-no-iam"></a>

现在，可以按以下方式测试设置：

1. 在**账户 B** 中，打开[Amazon SQS 控制台](https://console.amazonaws.cn/sqs)。

1. 选择之前创建的 **LambdaCrossAccountQueue**。

1. 选择 **Send and receive messages（发送和接收消息）**。

1. 在 **Message body (消息正文)** 中，输入测试消息。

1. 选择 **Send message**（发送消息）。

您在**账户 A** 中的 Lambda 函数应该收到消息。Lambda 将继续轮询队列以获取更新。当有新消息时，Lambda 会使用该新的事件数据从队列中调用您的函数。您的函数运行并在 Amazon CloudWatch 中创建日志。您可以在 [CloudWatch 控制台](https://console.amazonaws.cn/cloudwatch)中查看这些日志。

## 清除资源
<a name="cleanup"></a>

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

在**账户 A** 中，清理您的执行角色和 Lambda 函数。

**删除执行角色**

1. 打开 IAM 控制台的[角色页面](https://console.amazonaws.cn/iam/home#/roles)。

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

1. 选择**删除**。

1. 在文本输入字段中输入角色名称，然后选择**删除**。

**删除 Lambda 函数**

1. 打开 Lamba 控制台的 [Functions（函数）页面](https://console.amazonaws.cn/lambda/home#/functions)。

1. 选择您创建的函数。

1. 依次选择**操作**和**删除**。

1. 在文本输入字段中键入 **confirm**，然后选择 **Delete**（删除）。

在**账户 B** 中，清理 Amazon SQS 队列。

**删除 Amazon SQS 队列**

1. 登录到 Amazon Web Services 管理控制台 并打开 Amazon SQS 控制台，网址：[https://console.aws.amazon.com/vpc/](https://console.amazonaws.cn/sqs/)。

1. 选择创建的队列。

1. 选择**删除**。

1. 在文本输入字段中输入 **confirm**。

1. 选择**删除**。