

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

# 教程：使用数据脚本和实例元数据检索生命周期状态
<a name="tutorial-lifecycle-hook-instance-metadata"></a>

为生命周期挂钩创建自定义操作的一种常见方法是使用 Amazon EC2 Auto Scaling 发送到其他服务（例如亚马逊）的通知 EventBridge。但是，您可以避免创建额外的基础设施，方法是使用用户数据脚本将配置实例并完成生命周期操作的代码移动到实例本身中。

以下教程介绍如何开始使用用户数据脚本和实例元数据。您可以使用读取您组中实例的[目标周期状态](retrieving-target-lifecycle-state-through-imds.md)并在实例生命周期的特定阶段执行回调操作以继续启动过程的用户数据脚本来创建基本 Auto Scaling 组配置。

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

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


**Topics**
+ [步骤 1：创建具有完成生命周期操作权限的 IAM 角色](#instance-metadata-create-iam-role)
+ [步骤 2：创建启动模板并包含 IAM 角色和用户数据脚本](#instance-metadata-create-hello-world-function)
+ [步骤 3：创建 Auto Scaling 组](#instance-metadata-create-auto-scaling-group)
+ [步骤 4：添加生命周期钩子](#instance-metadata-add-lifecycle-hook)
+ [步骤 5：测试和验证功能](#instance-metadata-testing-hook)
+ [步骤 6：清除](#instance-metadata-lifecycle-hooks-tutorial-cleanup)
+ [相关资源](#instance-metadata-lifecycle-hooks-tutorial-related-resources)

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

当您使用 AWS CLI 或 AWS 软件开发工具包发送回调以完成生命周期操作时，必须使用具有完成生命周期操作权限的 IAM 角色。

**创建策略**

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

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

1. 在**策略文档**框中，将以下策略文档复制并粘贴到框中。将**sample text**替换为您的账号和您要创建的 Auto Scaling 群组的名称 (**TestAutoScalingEvent-group**)。

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

****  

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

------

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

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

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

**创建角色**

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

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

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

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

1. 在 “**添加权限**” 下，选择您创建的策略（**TestAutoScalingEvent-policy**）。然后选择**下一步**。

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

## 步骤 2：创建启动模板并包含 IAM 角色和用户数据脚本
<a name="instance-metadata-create-hello-world-function"></a>

创建用于 Auto Scaling 组的启动模板。包含您创建的 IAM 角色和提供的示例用户数据脚本。

**创建启动模板**

1. 打开 Amazon EC2 控制台的[启动模板页面](https://console.aws.amazon.com/ec2/v2/#LaunchTemplates)。

1. 选择**Create launch template**（创建启动模板）。

1. 对于 **Launch template name**（启动模板名称），输入 **TestAutoScalingEvent-template**。

1. 在 **Auto Scaling guidance**（Auto Scaling 指导）下，选中复选框。

1. 对于 **Application and OS Images (Amazon Machine Image)** [应用程序和操作系统镜像（Amazon Machine Image）]，请从 **Quick Start**（快速启动）列表中选择 Amazon Linux 2 (HVM)、SSD Volume Type（SSD 卷类型）、64-bit (x86) [64 位（x86）]。

1. 对于 **Instance type**（实例类型），选择一种 Amazon EC2 实例类型（例如“t2.micro”）。

1. 对于**高级详细信息**，展开该节以查看字段。

1. 对于 **IAM 实例配置文件**，请选择您的 IAM 角色（**TestAutoScalingEvent-** role）的 IAM 实例配置文件名称。实例配置文件是 IAM 角色的容器，在实例启动时允许 Amazon EC2 将 IAM 角色传递到实例。

   使用 IAM 控制台创建 IAM 角色时，控制台自动创建实例配置文件，按相应的角色为文件命名。

1. 对于 **User data**（用户数据），将下面的实例用户数据脚本粘贴到字段。将的示例文本替换为您`group_name`要创建的 Auto Scaling 组的`region`名称以及 AWS 区域 您想让 Auto Scaling 组使用的名称。

   ```
   #!/bin/bash
   
   function token {
       echo "X-aws-ec2-metadata-token: $(curl -X PUT 'http://169.254.169.254/latest/api/token' -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')"
   }
   
   function get_target_state {
       echo $(curl -H "$(token)" -s http://169.254.169.254/latest/meta-data/autoscaling/target-lifecycle-state)
   }
   
   function get_instance_id {
       echo $(curl -H "$(token)" -s http://169.254.169.254/latest/meta-data/instance-id)
   }
   
   function complete_lifecycle_action {
       instance_id=$(get_instance_id)
       group_name='TestAutoScalingEvent-group'
       region='us-west-2'
    
       echo $instance_id
       echo $region
       echo $(aws autoscaling complete-lifecycle-action \
         --lifecycle-hook-name TestAutoScalingEvent-hook \
         --auto-scaling-group-name $group_name \
         --lifecycle-action-result CONTINUE \
         --instance-id $instance_id \
         --region $region)
   }
   
   function main {
       while true
       do
           target_state=$(get_target_state)
           if [ \"$target_state\" = \"InService\" ]; then
               # Change hostname
               export new_hostname="${group_name}-$instance_id"
               hostname $new_hostname
               # Send callback
               complete_lifecycle_action
               break
           fi
           echo $target_state
           sleep 5
       done
   }
   
   main
   ```

   此简单用户数据脚本将执行以下操作：
   + 调用实例元数据以从实例元数据中检索目标生命周期状态和实例 ID
   + 重复检索目标生命周期状态，直到它变为 `InService`
   + 如果目标生命周期状态为 `InService`，则将实例的主机名更改为实例 ID 前面加上 Auto Scaling 组名称
   + 通过调用 **complete-lifecycle-action** CLI 命令向 Amazon EC2 Auto Scaling 发出信号以 `CONTINUE` EC2 启动过程来发送回调

1. 选择**Create launch template**（创建启动模板）。

1. 在确认页面上，选择 **Create Auto Scaling group**（创建 Auto Scaling 组）。

**注意**  
有关可用作开发用户数据脚本的参考的其他示例，请参阅 Amazon EC2 Auto Scaling 的[GitHub 存储库](https://github.com/aws-samples/amazon-ec2-auto-scaling-group-examples)。

## 步骤 3：创建 Auto Scaling 组
<a name="instance-metadata-create-auto-scaling-group"></a>

创建启动模板后，创建 Auto Scaling 组。

**创建 自动扩缩组**

1. 在 **Choose launch template or configuration**（选择启动模板或配置）页面上，对于 **Auto Scaling group name**（Auto Scaling 组名称），输入 Auto Scaling 组的名称 (**TestAutoScalingEvent-group**)。

1. 选择 **Next**（下一步）转至 **Choose instance launch options**（选择实例启动选项）页面。

1. 对于 **Network**（网络），选择 VPC。

1. 对于 **Availability Zones and subnets**（可用区和子网），请从一个或多个可用区中选择一个或多个子网。

1. 在 **Instance type requirements**（实例类型要求）部分中，使用默认设置简化此步骤。（请勿覆盖启动模板。） 在本教程中，您将仅使用启动模板中指定的实例类型启动一个按需型实例。

1. 在屏幕的底部选择 **Skip to review**（跳至审核）。

1. 在 **Review**（审核）页面中，检查 Auto Scaling 组的详细信息，然后选择 **Create Auto Scaling group**（创建 Auto Scaling 组）。

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

添加生命周期钩子以将实例保持在等待状态，直到您的生命周期操作完成。

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

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

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

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

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

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

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

   1. 对于 **Heartbeat timeout**（检测信号超时），输入 **300** 以获取等待用户数据脚本回调的秒数。

   1. 对于**默认结果**，请选择**放弃**。如果钩子超时而未收到来自您用户数据脚本的回调，Auto Scaling 组将终止新实例。

   1. （可选）将 **Notification metadata**（通知元数据）留空。

1. 选择**创建**。

## 步骤 5：测试和验证功能
<a name="instance-metadata-testing-hook"></a>

要测试功能，请通过将 Auto Scaling 组的所需容量增加 1 来更新 Auto Scaling 组。用户数据脚本运行并在实例启动后立即开始检查实例的目标生命周期状态。当目标生命周期状态为 `InService` 时，脚本会更改主机名并发送回调操作。完成此操作通常仅需要几秒钟时间。

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

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

1. 选中您的自动扩缩组旁边的复选框。在下方窗格中查看详细信息，同时仍然可以看到上方窗格的顶部几行。

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

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

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

在增加所需容量后，您可以通过扩缩活动的描述来验证您的实例是否已成功启动且未终止。

**查看扩展活动**

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

1. 在**活动**选项卡上的**活动历史记录**下，**状态**列显示您的 Auto Scaling 组是否已成功启动实例。

1. 如果用户数据脚本失败，则在超时时段过后，您会看到状态为 `Canceled` 且状态消息为 `Instance failed to complete user's Lifecycle Action: Lifecycle Action with token e85eb647-4fe0-4909-b341-a6c42EXAMPLE was abandoned: Lifecycle Action Completed with ABANDON Result` 的扩缩活动。

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

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

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

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

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

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

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

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

**要删除启动模板**

1. 打开 Amazon EC2 控制台的[启动模板页面](https://console.aws.amazon.com/ec2/v2/#LaunchTemplates)。

1. 选择启动模板 (`TestAutoScalingEvent-template`)，然后依次选择 **Actions**（操作）、**Delete template**（删除模板）。

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

如果您已完成使用此示例 Auto Scaling 组，请将其删除。您还可以删除您创建的 IAM 角色和权限策略。

**要删除 Auto Scaling 组**

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

1. 选中 Auto Scaling 组 (`TestAutoScalingEvent-group`) 旁边的复选框并选择 **Delete**（删除）。

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

   **Name**（名称）列中的加载图标指示 Auto Scaling 组正在被删除。终止实例并删除组需要几分钟时间。

**要删除 IAM 角色**

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

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

1. 选择**删除**。

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

**删除 IAM policy**

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

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

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

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

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

以下相关主题可能有助于您开发基于实例元数据中可用数据而调用实例操作的代码。
+ [通过实例元数据检索目标生命周期状态](retrieving-target-lifecycle-state-through-imds.md). 本节介绍其他使用案例的生命周期状态，例如实例终止。
+ [添加生命周期钩子（控制台）](adding-lifecycle-hooks.md#adding-lifecycle-hooks-console). 此过程向您演示如何为横向扩展（实例启动）和横向缩减（实例终止或返回到暖池）添加生命周期挂钩。
+ 《Amazon EC2 用户指南》**中的[实例元数据类别](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-categories)。本主题列出了可用于调用 EC2 实例操作的所有类别的实例元数据。

有关向您展示如何使用 Amazon EventBridge 创建规则，根据您的 Auto Scaling 组中实例发生的事件调用 Lambda 函数的教程，请参阅。[教程：配置调用 Lambda 函数的生命周期钩子](tutorial-lifecycle-hook-lambda.md)