

# 从 Aurora PostgreSQL 数据库集群 中调用 AWS Lambda 函数
<a name="PostgreSQL-Lambda"></a>

AWS Lambda 是事件驱动型计算服务，无需您预置或管理服务器即可运行代码。该服务可与许多 AWS 服务搭配使用，其中包括 Aurora PostgreSQL。例如，您可以使用 Lambda 函数处理来自数据库的事件通知，或者在将新文件上传到 Amazon S3 时从文件中加载数据。若要了解 Lambda 的更多信息，请参阅《AWS Lambda 开发人员指南**》中的[什么是 AWS Lambda？](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 

**注意**  
Aurora PostgreSQL 11.9 及更高版本（包括 Aurora Serverless v2）支持调用 AWS Lambda 函数。

设置 Aurora PostgreSQL 使用 Lambda 函数的过程包含多个步骤，其中涉及 AWS Lambda、IAM、VPC 和 Aurora PostgreSQL 数据库集群。下文对必要步骤进行了总结。

有关 Lambda 函数的更多信息，请参阅《AWS 开发人员指南[https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)》中的 [Lambda 入门](https://docs.aws.amazon.com/lambda/latest/dg/lambda-foundation.html)和 *AWS Lambda Lambda 函数*。

**Topics**
+ [步骤 1：配置 Aurora PostgreSQL 数据库集群，实现与 AWS Lambda 的出站连接](#PostgreSQL-Lambda-network)
+ [步骤 2：为 Aurora PostgreSQL 数据库集群和 AWS Lambda 配置 IAM](#PostgreSQL-Lambda-access)
+ [步骤 3：为 Aurora PostgreSQL 数据库集群安装 `aws_lambda` 扩展](#PostgreSQL-Lambda-install-extension)
+ [步骤 4：将 Lambda 帮助程序函数与 Aurora PostgreSQL 数据库集群 搭配使用（可选）](#PostgreSQL-Lambda-specify-function)
+ [步骤 5：从 Aurora PostgreSQL 数据库集群调用 Lambda 函数](#PostgreSQL-Lambda-invoke)
+ [步骤 6：授予其他用户调用 Lambda 函数的权限](#PostgreSQL-Lambda-grant-users-permissions)
+ [示例：从 Aurora PostgreSQL 数据库集群调用 Lambda 函数](PostgreSQL-Lambda-examples.md)
+ [Lambda 函数错误消息](PostgreSQL-Lambda-errors.md)
+ [AWS Lambda 函数和参数参考](PostgreSQL-Lambda-functions.md)

## 步骤 1：配置 Aurora PostgreSQL 数据库集群，实现与 AWS Lambda 的出站连接
<a name="PostgreSQL-Lambda-network"></a>

Lambda 函数始终在 AWS Lambda 服务拥有的 Amazon VPC 中运行。Lambda 将向此 VPC 应用网络访问和安全规则，并且会自动维护和监控 VPC。Aurora PostgreSQL 数据库集群向 Lambda 服务的 VPC 发送网络流量。其配置方式取决于 Aurora 数据库集群的主数据库实例是公有实例，还是私有实例。
+ **公有 Aurora PostgreSQL 数据库集群** – 如果数据库集群的主数据库实例位于 VPC 的公有子网中，并且该实例的“PublicyAccessible”属性为 `true`，则该实例是公有的。若要查找此属性的值，您可以使用 [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) AWS CLI 命令。您也可以使用 AWS 管理控制台 打开 **Connectivity & security**（连接和安全性）选项卡，然后检查 **Publicly accessible**（公开访问）是否为 **Yes**（是）。要验证实例是否在您的 VPC 的公有子网中，您可以使用 AWS 管理控制台或 AWS CLI。

  要设置对 Lambda 的访问权限，您可以使用 AWS 管理控制台 或 AWS CLI 在 VPC 的安全组上创建出站规则。出站规则指定 TCP 可以使用端口 443 将数据包发送到任何 IPv4 地址（0.0.0.0/0）。
+ **私有 Aurora PostgreSQL 数据库集群** – 在这种情况下，实例的“PublicyAccessible”属性为 `false` 或它位于私有子网中。要允许实例使用 Lambda，您可以使用网络地址转换（NAT）网关。有关更多信息，请参阅 [NAT 网关](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)。或者，您可以使用用于 Lambda 的 VPC 端点配置 VPC。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [VPC 端点](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints.html)。该端点响应 Aurora PostgreSQL 数据库集群对 Lambda 函数发出的调用。

您的 VPC 现在可以在网络级别与 AWS Lambda VPC 交互。接下来，您使用 IAM 配置权限。

## 步骤 2：为 Aurora PostgreSQL 数据库集群和 AWS Lambda 配置 IAM
<a name="PostgreSQL-Lambda-access"></a>

从 Aurora PostgreSQL 数据库集群调用 Lambda 函数需要特定权限。若要配置必要权限，建议创建允许调用 Lambda 函数的 IAM 策略，将该策略分配给一个角色，然后将该角色应用于数据库集群。这种方法授予数据库集群代表您调用指定 Lambda 函数的权限。以下步骤说明如何使用 AWS CLI 执行此操作。

**配置 IAM 权限以将集群与 Lambda 搭配使用**

1. 使用 [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) AWS CLI 命令创建允许 Aurora PostgreSQL 数据库集群调用指定 Lambda 函数的 IAM 策略。（语句 ID (Sid) 是策略语句的可选描述，对使用没有影响。） 此策略授予 Aurora 数据库集群调用指定 Lambda 函数所需的最低权限。

   ```
   aws iam create-policy  --policy-name rds-lambda-policy --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
           "Sid": "AllowAccessToExampleFunction",
           "Effect": "Allow",
           "Action": "lambda:InvokeFunction",
           "Resource": "arn:aws:lambda:aws-region:444455556666:function:my-function"
           }
       ]
   }'
   ```

   您也可以使用允许您调用任何 Lambda 函数的预定义 `AWSLambdaRole` 策略。有关更多信息，请参阅 [Lambda 的基于身份的 IAM 策略](https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html#access-policy-examples-aws-managed) 

1. 使用 [create-role](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-role.html) AWS CLI 命令创建该策略可在运行时担任的 IAM 角色。

   ```
   aws iam create-role  --role-name rds-lambda-role --assume-role-policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
           "Effect": "Allow",
           "Principal": {
               "Service": "rds.amazonaws.com"
           },
           "Action": "sts:AssumeRole"
           }
       ]
   }'
   ```

1. 使用 [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) AWS CLI 命令将策略应用于角色。

   ```
   aws iam attach-role-policy \
       --policy-arn arn:aws:iam::444455556666:policy/rds-lambda-policy \
       --role-name rds-lambda-role --region aws-region
   ```

1. 使用  [add-role-to-db-cluster](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/add-role-to-db-cluster.html)  AWS CLI 命令，将该角色应用于 Aurora PostgreSQL 数据库集群 。最后一步允许数据库集群的数据库用户调用 Lambda 函数。

   ```
   aws rds add-role-to-db-cluster \
          --db-cluster-identifier my-cluster-name \
          --feature-name Lambda \
          --role-arn  arn:aws:iam::444455556666:role/rds-lambda-role   \
          --region aws-region
   ```

完成 VPC 和 IAM 配置后，便可以安装 `aws_lambda` 扩展。（请注意，您可以随时安装扩展，但只有在您设置正确的 VPC 支持和 IAM 权限之后，`aws_lambda` 扩展才会对 Aurora PostgreSQL 数据库集群的功能添加内容。）

## 步骤 3：为 Aurora PostgreSQL 数据库集群安装 `aws_lambda` 扩展
<a name="PostgreSQL-Lambda-install-extension"></a>

要将 AWS Lambda 与 Aurora PostgreSQL 数据库集群结合使用，请将 `aws_lambda` PostgreSQL 扩展添加到 Aurora PostgreSQL 数据库集群。此扩展允许 Aurora PostgreSQL 数据库集群能从 PostgreSQL 调用 Lambda 函数。

**在 Aurora PostgreSQL 数据库集群中安装 `aws_lambda` 扩展**

使用 PostgreSQL `psql` 命令行或 pgAdmin 工具连接到 Aurora PostgreSQL 数据库集群。

1. 以具有 `rds_superuser` 权限的用户身份，连接到 Aurora PostgreSQL 数据库集群。默认 `postgres` 用户如示例所示。

   ```
   psql -h cluster-instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 安装 `aws_lambda` 扩展。`aws_commons` 扩展也是必要项。其为 PostgreSQL 的 `aws_lambda` 和许多其他 Aurora 扩展提供帮助程序函数。如果其尚未安装到 Aurora PostgreSQL 数据库集群上，则会按如下所示一并安装该扩展和 `aws_lambda`。

   ```
   CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
   NOTICE:  installing required extension "aws_commons"
   CREATE EXTENSION
   ```

`aws_lambda` 扩展已安装在 Aurora PostgreSQL 数据库集群的主数据库实例中。现在，您可以创建易于使用结构来调用 Lambda 函数。

## 步骤 4：将 Lambda 帮助程序函数与 Aurora PostgreSQL 数据库集群 搭配使用（可选）
<a name="PostgreSQL-Lambda-specify-function"></a>

您可以使用 `aws_commons` 扩展中的帮助程序函数来准备实体，以便更轻松地从 PostgreSQL 调用这些实体。为此，您需要获得有关 Lambda 函数的以下信息：
+ **Function name**（函数名称）：Lambda 函数的名称、Amazon Resource Name (ARN)、版本或别名。在 [步骤 2：为集群和 Lambda 配置 IAM](#PostgreSQL-Lambda-access) 中创建的 IAM 策略需要 ARN，所以建议您使用函数的 ARN。
+ **AWS 区域** —（可选）如果与 Aurora PostgreSQL 数据库集群 不在同一个区域中，则此区域为 Lambda 函数所在的 AWS 区域。

您可以使用 [aws\$1commons.create\$1lambda\$1function\$1arn](PostgreSQL-Lambda-functions.md#aws_commons.create_lambda_function_arn) 函数保存 Lambda 函数名称信息。此帮助程序函数创建了 `aws_commons._lambda_function_arn_1` 复合结构，其中包含调用函数所需的详细信息。在下文中，您可以找到三种替代方法来设置此复合结构。

```
SELECT aws_commons.create_lambda_function_arn(
   'my-function',
   'aws-region'
) AS aws_lambda_arn_1 \gset
```

```
SELECT aws_commons.create_lambda_function_arn(
   '111122223333:function:my-function',
   'aws-region'
) AS lambda_partial_arn_1 \gset
```

```
SELECT aws_commons.create_lambda_function_arn(
   'arn:aws:lambda:aws-region:111122223333:function:my-function'
) AS lambda_arn_1 \gset
```

这些值均可用于 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 函数调用。有关示例，请参阅 [步骤 5：从 Aurora PostgreSQL 数据库集群调用 Lambda 函数](#PostgreSQL-Lambda-invoke)。

## 步骤 5：从 Aurora PostgreSQL 数据库集群调用 Lambda 函数
<a name="PostgreSQL-Lambda-invoke"></a>

`aws_lambda.invoke` 函数采用同步还是异步调用方式取决于 `invocation_type`。此参数的两个可用选项分别为 `RequestResponse`（默认）和 `Event`，如下所示。
+ **`RequestResponse`**：此为*同步*调用类型。如果调用时未指定调用类型，默认此调用方式。响应有效负载包含 `aws_lambda.invoke` 函数的结果。如果工作流程需要接收 Lambda 函数的结果才能继续进行操作，请使用此调用类型。
+ **`Event`**：此为*异步*调用类型。响应不包含包含结果的有效负载。如果工作流程不需要 Lambda 函数的结果即可继续进行操作，请使用此调用类型。

要对设置进行简单测试，您可以使用 `psql` 连接到数据库实例，然后从命令行调用示例函数。假设在 Lambda 服务上设置了一个基本函数，例如下面屏幕截图中所示的简单 Python 函数。

![\[AWS Lambda 的 AWS CLI 中显示的示例 Lambda 函数\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/images/lambda_simple_function.png)


**调用示例函数**

1. 使用 `psql` 或 pgAdmin 连接到主数据库实例。

   ```
   psql -h cluster.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 使用函数的 ARN 调用该函数。

   ```
   SELECT * from aws_lambda.invoke(aws_commons.create_lambda_function_arn('arn:aws:lambda:aws-region:444455556666:function:simple', 'us-west-1'), '{"body": "Hello from Postgres!"}'::json );
   ```

   响应如下所示。

   ```
   status_code |                        payload                        | executed_version | log_result
   -------------+-------------------------------------------------------+------------------+------------
            200 | {"statusCode": 200, "body": "\"Hello from Lambda!\""} | $LATEST          |
   (1 row)
   ```

如果调用尝试不成功，请参阅 [Lambda 函数错误消息](PostgreSQL-Lambda-errors.md)。

## 步骤 6：授予其他用户调用 Lambda 函数的权限
<a name="PostgreSQL-Lambda-grant-users-permissions"></a>

在程序的这一步骤中，仅当您是 `rds_superuser` 才能调用 Lambda 函数。要允许其他用户调用您创建的任何函数，您需要向他们授予权限。

**要授予调用 Lambda 函数的其他权限，请执行以下操作：**

1. 使用 `psql` 或 pgAdmin 连接到主数据库实例。

   ```
   psql -h cluster.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 运行以下 SQL 命令：

   ```
   postgres=>  GRANT USAGE ON SCHEMA aws_lambda TO db_username;
   GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambda TO db_username;
   ```