

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 教程：配置调用 Lambda 函数的生命周期钩子
<a name="tutorial-lifecycle-hook-lambda"></a>

在本练习中，您将创建一条包含筛选模式的 Amazon EventBridge 规则，匹配该模式后，将调用一个 AWS Lambda 函数作为规则目标。我们提供了要使用的筛选条件模式和示例函数代码。

如果一切配置正确，则在本教程结束时，Lambda 函数将在实例启动时执行自定义操作。自定义操作只是在与 Lambda 函数关联的 CloudWatch 日志日志流中记录事件。

Lambda 函数还执行回调，以便在此操作成功时继续执行实例的生命周期，但允许实例放弃启动并在操作失败时终止。

下图总结了使用 Lambda 函数执行自定义操作时横向扩展事件的流程。实例启动后，实例的生命周期将暂停，直到生命周期挂钩完成（超时或 Amazon EC2 Auto Scaling 收到继续的信号）。

![\[使用 Lambda 函数执行自定义操作时横向扩展事件的流程。\]](http://docs.aws.amazon.com/zh_cn/autoscaling/ec2/userguide/images/lifecycle-hook-lambda-function.png)


**注意**  
根据您的用例，您可以按照以下步骤配置生命周期挂钩并创建 EventBridge 规则。或者，您可以使用 Lambda 函数直接配置生命周期挂钩，而无需创建 EventBridge 规则。

**Topics**
+ [前提条件](#lambda-hello-world-tutorial-prerequisites)
+ [步骤 1：创建具有完成生命周期操作权限的 IAM 角色](#lambda-create-iam-role)
+ [第 2 步：创建 Lambda 函数](#lambda-create-hello-world-function)
+ [步骤 3：创建 EventBridge 规则](#lambda-create-rule)
+ [步骤 4：添加生命周期钩子](#lambda-add-lifecycle-hook)
+ [步骤 5：测试和验证事件](#lambda-testing-hook-notifications)
+ [步骤 6：清除](#lambda-lifecycle-hooks-tutorial-cleanup)
+ [相关资源](#lambda-lifecycle-hooks-tutorial-related-resources)

## 前提条件
<a name="lambda-hello-world-tutorial-prerequisites"></a>

在开始本教程前，请创建 Auto Scaling 组（如果您还没有 Auto Scaling 组）。若要创建 自动扩缩组，请打开 Amazon EC2 控制台中的 [自动扩缩组页面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)，然后选择**创建自动扩缩组**。

## 步骤 1：创建具有完成生命周期操作权限的 IAM 角色
<a name="lambda-create-iam-role"></a>

在创建 Lambda 函数之前，必须首先创建执行角色和权限策略，以允许 Lambda 完成生命周期钩子。

**创建策略**

1. 打开 IAM 控制台的[策略](https://console.aws.amazon.com/iam/home?#/policies)页面，然后选择**创建策略**。

1. 请选择 **JSON** 选项卡。

1. 在 “**政策文档**” 框中，将以下策略文档粘贴到框中，将中的**italics**文本替换为您的账号和 Auto Scaling 组的名称。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "autoscaling:CompleteLifecycleAction"
         ],
         "Resource": "arn:aws:autoscaling:*:123456789012:autoScalingGroup:*:autoScalingGroupName/my-asg"
       }
     ]
   }
   ```

------

1. 选择**下一步**。

1. 对于**策略名称**，输入 **LogAutoScalingEvent-policy**。选择**创建策略**。

完成创建策略之后，您可以创建一个使用该策略的角色。

**创建角色**

1. 在左侧的导航窗格中，选择**角色**。

1. 选择**创建角色**。

1. 对于**选择可信实体**，选择 **AWS 服务**。

1. 对于您的使用案例，选择 **Lambda**，然后选择 **Next**（下一步）。

1. 在 “**添加权限**” 下，选择您创建的策略（**LogAutoScalingEvent-policy**）和名为**AWSLambdaBasicExecutionRole**的策略。然后选择**下一步**。
**注意**  
该**AWSLambdaBasicExecutionRole**策略具有该函数将日志写入 CloudWatch 日志所需的权限。

1. 在 **Name, review, and create**（命名、检查并创建）页面上，对于 **Role name**（角色名称），输入 **LogAutoScalingEvent-role**，然后选择 **Create role**（创建角色）。

## 第 2 步：创建 Lambda 函数
<a name="lambda-create-hello-world-function"></a>

创建 Lambda 函数以用作事件的目标。用 Node.js 编写的示例 Lambda 函数是在亚马逊 EC2 Auto Scaling 发出匹配事件 EventBridge 时调用的。

**创建 Lambda 函数**

1. 打开 Lambda 控制台的[函数](https://console.aws.amazon.com/lambda/home#/functions)页面。

1. 选择 **Create function**（创建函数），然后选择 **Author from scratch**（从头开始创作）。

1. 在**基本信息** 下，对于**函数名称**，输入 **LogAutoScalingEvent**。

1. 对于**运行时系统**，选择 **Node.js 18.x**。

1. 向下滚动并选择**更改默认执行角色**，然后对于**执行角色**，选择**使用现有角色**。

1. 对于**现有角色**，选择 **LogAutoScalingEvent-role**。

1. 保留其他默认值。

1. 选择**创建函数**。您将返回到函数的代码和配置。

1. 当 `LogAutoScalingEvent` 函数在控制台中保持打开状态时，在编辑器中的 **代码资源**下，将以下示例代码复制到名为 index.mjs 的文件中。

   ```
   import { AutoScalingClient, CompleteLifecycleActionCommand } from "@aws-sdk/client-auto-scaling";
   export const handler = async(event) => {
     console.log('LogAutoScalingEvent');
     console.log('Received event:', JSON.stringify(event, null, 2));
     var autoscaling = new AutoScalingClient({ region: event.region });
     var eventDetail = event.detail;
     var params = {
       AutoScalingGroupName: eventDetail['AutoScalingGroupName'], /* required */
       LifecycleActionResult: 'CONTINUE', /* required */
       LifecycleHookName: eventDetail['LifecycleHookName'], /* required */
       InstanceId: eventDetail['EC2InstanceId'],
       LifecycleActionToken: eventDetail['LifecycleActionToken']
     };
     var response;
     const command = new CompleteLifecycleActionCommand(params);
     try {
       var data = await autoscaling.send(command);
       console.log(data); // successful response
       response = {
         statusCode: 200,
         body: JSON.stringify('SUCCESS'),
       };
     } catch (err) {
       console.log(err, err.stack); // an error occurred
       response = {
         statusCode: 500,
         body: JSON.stringify('ERROR'),
       };
     }
     return response;
   };
   ```

   此代码仅记录事件，以便在本教程结束时，您可以看到与此 Lambda 函数关联的事件出现在 CloudWatch 日志日志流中。

1. 选择**部署**。

## 步骤 3：创建 EventBridge 规则
<a name="lambda-create-rule"></a>

创建一条 EventBridge 规则来运行您的 Lambda 函数。有关使用 EventBridge 的更多信息，请参阅[用于处理 EventBridge Auto Scaling 事件](automating-ec2-auto-scaling-with-eventbridge.md)。

**使用控制台创建规则**

1. 打开 [EventBridge 控制台](https://console.aws.amazon.com/events/)。

1. 在导航窗格中，选择**规则**。

1. 选择**创建规则**。

1. 对于**定义规则详细信息**，请执行以下操作：

   1. 对于**名称**，请输入 **LogAutoScalingEvent-rule**。

   1. 对于**事件总线**，选择**默认**。当您的账户 AWS 服务 中的某项生成事件时，它始终会转到您账户的默认事件总线。

   1. 对于**规则类型**，选择**具有事件模式的规则**。

   1. 选择**下一步**。

1. 对于 **Build event pattern**（构建事件模式），执行以下操作：

   1. 对于**事件来源**，选择**AWS 事件或 EventBridge 合作伙伴事件**。

   1. 向下滚动到 **事件模式**，然后执行以下操作：

   1. 

      1. 对于**事件源**，选择 **AWS 服务**。

      1. 对于 **AWS 服务**，选择 **Auto Scaling**。

      1. 对于 **Event Type (事件类型)**，选择 **Instance Launch and Terminate (实例启动和终止)**。

      1. 默认情况下，该规则会与任何横向缩减或横向扩展事件匹配。要创建在发生横向扩展事件并且因生命周期挂钩而使实例被置于等待状态时通知您的规则，请选择 **Specific instance event(s)**（特定实例事件），然后选择 **EC2 Instance-launch Lifecycle Action**（EC2 实例启动生命周期操作）。

      1. 默认情况下，该规则与区域中任何 Auto Scaling 组匹配。若要使该规则与特定自动扩缩组匹配，请选择 **特定组名称**并选择组。

      1. 选择**下一步**。

1. 对于 **Select target(s)**（选择目标），请执行以下操作：

   1. 对于 **Target types**（目标类型），选择 **AWS 服务**。

   1. 对于 **Select a target**（选择目标），选择 **Lambda function**（Lambda 函数）。

   1. 对于 “**函数**”，选择**LogAutoScalingEvent**。

   1. 选择**下一步**两次。

1. 请在 **审核和创建**页面上，选择 **创建**。

## 步骤 4：添加生命周期钩子
<a name="lambda-add-lifecycle-hook"></a>

在本节中，您将添加一个生命周期钩子，以便 Lambda 在启动时在实例上运行函数。

**添加生命周期挂钩**

1. 打开 Amazon EC2 控制台中的 [自动扩缩组页面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 选中您的自动扩缩组旁边的复选框。这时将在页面底部打开一个拆分窗格。

1. 在下方窗格中，在**实例管理**选项卡的**生命周期钩子**中，选择**创建生命周期钩子**。

1. 要为横向扩展（实例启动）定义生命周期挂钩，请执行以下操作：

   1. 对于**生命周期钩子名称**，请输入 **LogAutoScalingEvent-hook**。

   1. 对于**生命周期转换**，请选择**实例启动**。

   1. 对于**检测信号超时**，输入 **300** 以获取等待 Lambda 函数回调的秒数。

   1. 对于**默认结果**，请选择**放弃**。这意味着，如果钩子超时而未收到 Lambda 函数的回调，Auto Scaling 组将终止新实例。

   1. （可选）将**通知元数据**留空。我们传递给的事件数据 EventBridge 包含调用 Lambda 函数所需的所有必要信息。

1. 选择**创建**。

## 步骤 5：测试和验证事件
<a name="lambda-testing-hook-notifications"></a>

要测试事件，请通过将 Auto Scaling 组的所需容量增加 1 来更新 Auto Scaling 组。您的 Lambda 函数在增加所需容量后几秒钟内调用。

**增加您的 Auto Scaling 组的大小**

1. 打开 Amazon EC2 控制台中的 [自动扩缩组页面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 选中 Auto Scaling 组旁边的复选框可在下方窗格中查看详细信息，并且仍然可以看到上方窗格的顶行。

1. 在下方窗格中的**详细信息**选项卡上，选择**组详细信息**、**编辑**。

1. 对于 **Desired capacity (所需容量)**，将当前值增加 1。

1. 选择**更新**。启动实例时，上方窗格中的**状态**列会显示*正在更新容量*状态。

增加所需的容量后，可验证是否已调用 Lambda 函数。

**查看 Lambda 函数的输出**

1. 打开 CloudWatch 控制台的[日志组页面](https://console.aws.amazon.com/cloudwatch/home#logs:)。

1. 选择您的 Lambda 函数 (`/aws/lambda/LogAutoScalingEvent`) 的日志组的名称。

1. 选择日志流的名称，以查看由生命周期操作的函数提供的数据。

接下来，您可以通过扩展活动的描述来验证您的实例是否已成功启动。

**查看扩展活动**

1. 返回到 **Auto Scaling 组**页面并选择您的组。

1. 在**活动**选项卡上的**活动历史记录**下，**状态**列显示您的 Auto Scaling 组是否已成功启动实例。
   + 如果操作成功，扩展活动的状态将为“成功”。
   + 如果失败，在等待几分钟后，您将看到状态为“已取消”的扩展活动，并显示状态消息“实例无法完成用户的生命周期操作：使用令牌 e85eb647-4fe0-4909-b341-a6c42EXAMPLE 的生命周期操作已放弃：使用“放弃”结果完成的生命周期操作”。

**减少您的 Auto Scaling 组的大小**  
如果您不需要您为此测试启动的其他实例，则可以打开**详细信息**选项卡并将**所需容量**减少 1。

## 步骤 6：清除
<a name="lambda-lifecycle-hooks-tutorial-cleanup"></a>

如果您已完成仅为本教程创建的资源，请使用以下步骤将其删除。

**删除生命周期钩子**

1. 打开 Amazon EC2 控制台中的 [自动扩缩组页面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 选中您的自动扩缩组旁边的复选框。

1. 在**实例管理**选项卡的**生命周期钩子**中，选择生命周期钩子 (`LogAutoScalingEvent-hook`)。

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

1. 再次选择**删除**以确认。

**删除 Amazon EventBridge 规则**

1. 在 Amazon EventBridge 控制台中打开 “[规则” 页面](https://console.aws.amazon.com/events/home?#/rules)。

1. 在**事件总线**下，选择与规则 (`Default`) 关联的事件总线。

1. 然后选中您的规则 (`LogAutoScalingEvent-rule`) 旁边的复选框。

1. 选择**删除**。

1. 在系统提示进行确认时，键入规则的名称，然后选择 **Delete**（删除）。

如果您已完成使用此示例函数，请将其删除。您还可以删除存储函数日志的日志组以及您创建的执行角色和权限策略。

**要删除 Lambda 函数**

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

1. 选择函数 (`LogAutoScalingEvent`)。

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

1. 当系统提示进行确认时，键入 **delete** 以确认删除指定函数，然后选择 **Delete**（删除）。

**删除日志组**

1. 打开 CloudWatch 控制台的[日志组页面](https://console.aws.amazon.com/cloudwatch/home#logs:)。

1. 选择函数的日志组 (`/aws/lambda/LogAutoScalingEvent`)。

1. 依次选择 **Actions**（操作）和 **Delete log group(s)**（删除日志组）。

1. 在 **Delete log group(s)**（删除日志组）对话框中，选择 **Delete**（删除）。

**删除执行角色**

1. 打开 IAM 控制台的 [Roles page](https://console.aws.amazon.com/iam/home?#/roles)（角色页面）。

1. 选择函数的角色 (`LogAutoScalingEvent-role`)。

1. 选择**删除**。

1. 在系统提示进行确认时，键入角色的名称，然后选择 **Delete**（删除）。

**删除 IAM policy**

1. 打开 IAM 控制台的 [Policies（策略）页面](https://console.aws.amazon.com/iam/home?#/policies)。

1. 选择您创建的策略 (`LogAutoScalingEvent-policy`)。

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

1. 在系统提示进行确认时，键入策略的名称，然后选择 **Delete**（删除）。

## 相关资源
<a name="lambda-lifecycle-hooks-tutorial-related-resources"></a>

当您根据发生在 Auto Scaling 组中的实例的事件创建 EventBridge 规则时，以下相关主题可能会有所帮助。
+ [用于处理 EventBridge Auto Scaling 事件](automating-ec2-auto-scaling-with-eventbridge.md). 本节向您演示其他使用案例的事件示例，包括针对横向缩减的事件。
+ [添加生命周期钩子（控制台）](adding-lifecycle-hooks.md#adding-lifecycle-hooks-console). 此过程向您演示如何为横向扩展（实例启动）和横向缩减（实例终止或返回到暖池）添加生命周期挂钩。

有关向您演示如何使用实例元数据服务 (IMDS) 从实例本身内部调用操作的教程，请参阅 [教程：使用数据脚本和实例元数据检索生命周期状态](tutorial-lifecycle-hook-instance-metadata.md)。