

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 教學課程：使用資料指令碼和執行個體中繼資料來擷取生命週期狀態
<a name="tutorial-lifecycle-hook-instance-metadata"></a>

為 lifecycle hook 建立自訂動作的常見方法，是使用 Amazon EC2 Auto Scaling 傳送給其他服務 (如 Amazon EventBridge) 的通知。但是，您可以透過使用使用者資料指令碼將設定執行個體中繼資料並完成生命週期動作的程式碼移動至執行個體中繼資料本身，從而避免建立額外的基礎設施。

下列教學課程將介紹如何開始使用使用者資料指令碼和執行個體中繼資料。您可以使用使用者資料指令碼建立基本 Auto Scaling 群組配置，該指令碼可讀取群組中執行個體的[目標生命週期狀態](retrieving-target-lifecycle-state-through-imds.md)，並在執行個體生命週期的特定階段執行回呼動作以繼續啟動程序。

當您使用使用者資料指令碼執行自訂動作時，下圖摘要說明橫向擴展事件的流程。執行個體啟動後，透過逾時或 Amazon EC2 Auto Scaling 接收訊號以繼續，執行個體的生命週期會暫停，直到生命週期掛鉤完成為止。

![\[當您使用使用者資料指令碼執行自訂動作時，橫向擴展事件的流程。\]](http://docs.aws.amazon.com/zh_tw/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：新增 lifecycle hook](#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)，然後選擇 **Create policy** (建立政策)。

1. 選擇 **JSON** 標籤。

1. 在 **Policy Document** (政策文件) 方塊中，將下列政策文件複製並貼入方塊。將 **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. 針對 **Policy name** (政策名稱)，輸入 **TestAutoScalingEvent-policy**。選擇**建立政策**。

當您完成建立政策時，您可以建立一個使用它的角色。

**建立角色**

1. 在左側導覽窗格中，選擇 **Roles** (角色)。

1. 選擇建**立角色**。

1. 對於 **Select trusted entity** (選取信任的實體) 區段，選擇 **AWS service** (AWS 服務)。

1. 對於您的使用案例，選擇 **EC2**，然後選擇 **Next** (下一步)。

1. 在 **Add permissions** (新增許可) 下，選擇您建立的政策 (**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 磁碟區類型、64 位元 (x86)。

1. 在 **Instance type** (執行個體類型) 中，選擇 Amazon EC2 執行個體的類型 (例如 t2.micro)。

1. 針對 **Advanced details** (進階詳細資訊)，請展開此區段來檢視欄位。

1. 在 **IAM instance profile** (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`，請將執行個體的主機名稱變更為帶有 Auto Scaling 群組名稱的執行個體 ID
   + 透過叫用 **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 群組。

**建立 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：新增 lifecycle hook
<a name="instance-metadata-add-lifecycle-hook"></a>

新增 lifecycle hook，使執行個體保持等待狀態，直到您的生命週期動作完成。

**新增 lifecycle hook**

1. 開啟 Amazon EC2 主控台的 [Auto Scaling 群組頁面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 選取 Auto Scaling 群組旁的核取方塊。頁面底部會開啟一個分割窗格。

1. 在下方窗格中，在 **Instance management** (執行個體管理) 索引標籤的 **Lifecycle hooks** (lifecycle hook) 中，選擇 **Create lifecycle hook** (建立 lifecycle hook)。

1. 若要定義橫向擴展 (執行個體啟動) 的 lifecycle hook，請執行以下操作：

   1. 對於 **Lifecycle hook name** (lifecycle hook 名稱)，輸入 **TestAutoScalingEvent-hook**。

   1. 對於 **Lifecycle transition** (生命週期轉移)，選擇 **Instance launch** (執行個體啟動)。

   1. 在 **Heartbeat timeout** (活動訊號逾時) 中輸入 **300**，表示等待使用者資料指令碼回呼的秒數。

   1. 在 **Default result** (預設結果) 中，選擇 **ABANDON** (放棄)。如果掛鉤逾時而未收到來自您使用者資料指令碼的回呼，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 主控台的 [Auto Scaling 群組頁面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 選取 Auto Scaling 群組旁的核取方塊。在下方窗格中檢視詳細資料時，仍可看到上方窗格的頂端列。

1. 在下方窗格中，在 **Details** (詳細資訊) 索引標籤上選擇 **Group details** (群組詳細資訊)、**Edit** (編輯)。

1. 對於 **Desired capacity (所需容量)**，將目前值增加 1。

1. 選擇**更新**。正在啟動執行個體時，上方窗格中的 **Status** (狀態) 欄會顯示 *Updating capacity* (更新容量) 狀態。

增加所需容量後，您可以確認執行個體已成功啟動，並且未從擴展活動的描述中終止。

**檢視擴展活動**

1. 返回 **Auto Scaling groups** (Auto Scaling 群組) 頁面並選取群組。

1. 在 **Activity** (活動) 索引標籤的 **Activity history** (活動歷史記錄) 下方，**Status** (狀態) 欄會顯示 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>

如果您已完成使用針對此教學課程建立的資源，請按下列步驟將其刪除。

**刪除 lifecycle hook**

1. 開啟 Amazon EC2 主控台的 [Auto Scaling 群組頁面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 選取 Auto Scaling 群組旁的核取方塊。

1. 在 **Instance management** (執行個體管理) 索引標籤的 **Lifecycle hooks** (lifecycle hook) 中，選擇 lifecycle hook (`TestAutoScalingEvent-hook`)。

1. 選擇 **動作**、**刪除**。

1. 再次選擇 **Delete** (刪除) 進行確認。

**刪除啟動範本**

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 主控台的 [Auto Scaling 群組頁面](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups)。

1. 選取 Auto Scaling 群組旁邊的核取方塊 (`TestAutoScalingEvent-group`)，然後選擇 **Delete** (刪除)。

1. 出現確認提示時，請輸入 **delete** 來確認刪除特定的 Auto Scaling 群組，然後選擇 **Delete** (刪除)。

   **Name** (名稱) 欄位中的載入圖示會顯示正在刪除 Auto Scaling 群組。終止執行個體並刪除群組需要幾分鐘的時間。

**刪除 IAM 角色**

1. 開啟 IAM 主控台中的 [Roles](https://console.aws.amazon.com/iam/home?#/roles) (角色) 頁面。

1. 選取函數的角色 (`TestAutoScalingEvent-role`)。

1. 選擇 **刪除**。

1. 出現確認提示時，請輸入角色名稱，然後選擇 **Delete** (刪除)。

**刪除 IAM 政策**

1. 開啟 IAM 主控台中的[政策頁面](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). 本節說明其他使用案例 (例如執行個體終止) 的生命週期狀態。
+ [新增 lifecycle hook (主控台)](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 函數的 lifecycle hook](tutorial-lifecycle-hook-lambda.md)。