

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

# 教學課程：使用驗證測試部署 Amazon ECS 服務
<a name="tutorial-ecs-deployment-with-hooks"></a>

 在本教學課程中，您將了解如何使用 Lambda 函數來驗證已更新 Amazon ECS 應用程式的部分部署。本教學課程使用 CodeDeploy 應用程式、CodeDeploy 部署群組，以及您在 中使用的 Amazon ECS 應用程式[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)。請先完成該教學課程，再開始本教學課程。

 若要新增驗證測試，請先在 Lambda 函數中實作測試。接著，在部署 AppSpec 檔案中，為您要測試的生命週期掛鉤指定 Lambda 函數。如果驗證測試失敗，部署會停止、轉返，並標記為失敗。如果測試成功，部署會繼續下一個部署生命週期事件或勾點。

 在具有驗證測試的 Amazon ECS 部署期間，CodeDeploy 會使用負載平衡器，其設定有兩個目標群組：一個生產流量接聽程式和一個測試流量接聽程式。下圖顯示部署開始之前，負載平衡器、生產和測試接聽程式、目標群組和 Amazon ECS 應用程式之間的關聯。本教學課程會使用 Application Load Balancer。您也可以使用 Network Load Balancer。

![\[Application Load Balancer 或 Network Load Balancer、接聽程式、目標群組、任務集和 Amazon ECS 服務之間的連線。\]](http://docs.aws.amazon.com/zh_tw/codedeploy/latest/userguide/images/codedeploy-ecs-deployment-step-1.png)


 在 Amazon ECS 部署期間，有五個生命週期掛鉤可供測試。本教學課程會在第三個生命週期部署勾點 `AfterAllowTestTraffic` 期間實作一個測試。如需詳細資訊，請參閱[Amazon ECS 部署的生命週期事件掛鉤清單](reference-appspec-file-structure-hooks.md#reference-appspec-file-structure-hooks-list-ecs)。成功部署後，生產流量接聽程式會將流量轉送至新的替換任務集，並終止原始任務集。下圖顯示您的資源在成功部署後如何相關。如需詳細資訊，請參閱[Amazon ECS 部署期間會發生什麼情況](deployment-steps-ecs.md#deployment-steps-what-happens)。

![\[部署後Application Load Balancer 或 Network Load Balancer、接聽程式、目標群組和替換任務集之間的連線。\]](http://docs.aws.amazon.com/zh_tw/codedeploy/latest/userguide/images/codedeploy-ecs-deployment-step-6.png)


**注意**  
完成本教學課程可能會導致 AWS 您的帳戶產生費用。這些包括 CodeDeploy AWS Lambda和 CloudWatch 的可能費用。如需詳細資訊，請參閱[AWS CodeDeploy 定價](https://aws.amazon.com/codedeploy/pricing/)、[AWS Lambda 定價](https://aws.amazon.com/lambda/pricing/)和 [Amazon CloudWatch 定價](https://aws.amazon.com/cloudwatch/pricing/)。

**Topics**
+ [先決條件](tutorial-ecs-with-hooks-prereqs.md)
+ [步驟 1：建立測試接聽程式](tutorial-ecs-with-hooks-create-second-listener.md)
+ [步驟 2：更新您的 Amazon ECS 應用程式](tutorial-ecs-with-hooks-update-the-ecs-application.md)
+ [步驟 3：建立 lifecycle hook Lambda 函數](tutorial-ecs-with-hooks-create-hooks.md)
+ [步驟 4：更新您的 AppSpec 檔案](tutorial-ecs-with-hooks-create-appspec-file.md)
+ [步驟 5：使用 CodeDeploy 主控台部署您的 Amazon ECS 服務](tutorial-ecs-with-hooks-deployment.md)
+ [步驟 6：在 CloudWatch Logs 中檢視 Lambda 掛鉤函數輸出](tutorial-ecs-with-hooks-view-cw-logs.md)
+ [步驟 7：清除](tutoria-ecs-with-hooks-clean-up.md)

# 先決條件
<a name="tutorial-ecs-with-hooks-prereqs"></a>

若要成功完成此教學課程，您必須先：
+  完成 中 [先決條件](tutorial-ecs-prereqs.md) 的先決條件[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)。
+  完成「[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)」中的步驟。記下以下項目：
  +  負載平衡器的名稱。
  +  目標群組的名稱。
  +  負載平衡器接聽程式所使用的連接埠。
  +  負載平衡器的 ARN。這可用來建立新的接聽程式。
  +  其中一個目標群組的 ARN。這可用來建立新的接聽程式。
  +  您建立的 CodeDeploy 應用程式和部署群組。
  +  您建立的 AppSpec 檔案，供 CodeDeploy 部署使用。您在此教學課程中會編輯此檔案。

# 步驟 1：建立測試接聽程式
<a name="tutorial-ecs-with-hooks-create-second-listener"></a>

 具有驗證測試的 Amazon ECS 部署需要第二個接聽程式。此接聽程式用於在替代任務集中將測試流量提供給更新的 Amazon ECS 應用程式。您的驗證測試會針對測試流量執行。

 測試流量的接聽程式可以使用任一個目標群組。使用 [create-listener](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-listener.html) AWS CLI 命令建立第二個接聽程式，其中包含將測試流量轉送至連接埠 8080 的預設規則。使用負載平衡器的 ARN 和其中一個目標群組的 ARN。

```
aws elbv2 create-listener --load-balancer-arn your-load-balancer-arn \
--protocol HTTP --port 8080 \
--default-actions Type=forward,TargetGroupArn=your-target-group-arn --region your-aws-region
```

# 步驟 2：更新您的 Amazon ECS 應用程式
<a name="tutorial-ecs-with-hooks-update-the-ecs-application"></a>

 在本節中，您將更新 Amazon ECS 應用程式以使用其任務定義的新修訂。您建立新的修訂版，新增一個標籤稍做更新。

**更新您的任務定義**

1. 開啟 Amazon ECS 傳統主控台，網址為 [https://console.aws.amazon.com/ecs/](https://console.aws.amazon.com/ecs/)。

1.  在導覽窗格中，選擇 **Task Definitions** (任務定義)。

1.  選取 Amazon ECS 服務使用之任務定義的核取方塊。

1.  選擇 **Create new revision (建立新的修訂)**。

1.  稍微更新任務定義，只新增一個標籤。在頁面底部的 **Tags (標籤)** 中，輸入新的鍵值對來建立新的標籤。

1.  選擇**建立**。您應該會看到任務定義的修訂版編號已增加 1。

1.  選擇 **JSON** 標籤。記下 `taskDefinitionArn` 的值。格式為 `arn:aws:ecs:aws-region: account-id:task-definition/task-definition-family: task-definition-revision`。這是已更新之任務定義的 ARN。

# 步驟 3：建立 lifecycle hook Lambda 函數
<a name="tutorial-ecs-with-hooks-create-hooks"></a>

在本節中，您會為 Amazon ECS 部署的`AfterAllowTestTraffic`掛鉤實作一個 Lambda 函數。Lambda 函數會在安裝更新的 Amazon ECS 應用程式之前執行驗證測試。在此教學課程中，Lambda 函數會傳回 `Succeeded`。在真實世界部署期間，驗證測試會傳回 `Succeeded` 或 `Failed`，取決於驗證測試的結果。此外，在實際部署期間，您可以為一或多個其他 Amazon ECS 部署生命週期事件掛鉤 (`BeforeInstall`、`BeforeAllowTraffic`、 `AfterInstall`和 ) 實作 Lambda 測試函數`AfterAllowTraffic`。如需詳細資訊，請參閱[Amazon ECS 部署的生命週期事件掛鉤清單](reference-appspec-file-structure-hooks.md#reference-appspec-file-structure-hooks-list-ecs)。

 建立 Lambda 函數需要 IAM 角色。此角色授予 Lambda 函數寫入 CloudWatch Logs 的許可，並設定 CodeDeploy 生命週期掛鉤的狀態。

**若要建立一個 IAM 角色**

1. 前往 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 開啟 IAM 主控台。

1. 從導覽窗格，選擇 **Roles (角色)**，然後選擇 **Create role (建立角色)**。

1.  建立具備下列屬性的角色：
   +  **Trusted entity (信任實體)**：**AWS Lambda**。
   +  **Permissions (許可)**：**AWSLambdaBasicExecutionRole**。這會授予 Lambda 函數寫入 CloudWatch Logs 的許可。
   +  **Role name (角色名稱)**：**`lambda-cli-hook-role`**。

   如需詳細資訊，請參閱[建立 AWS Lambda 執行角色](https://docs.aws.amazon.com/lambda/latest/dg/with-userapp.html#with-userapp-walkthrough-custom-events-create-iam-role)。

1.  將許可 `codedeploy:PutLifecycleEventHookExecutionStatus` 連接至您建立的角色。這會授予 Lambda 函數在部署期間設定 CodeDeploy 生命週期掛鉤狀態的許可。如需詳細資訊，請參閱*AWS Identity and Access Management 《 使用者指南*》中的[新增 IAM 身分許可](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#add-policies-console)和《*CodeDeploy API 參考*》中的 [PutLifecycleEventHookExecutionStatus](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_PutLifecycleEventHookExecutionStatus.html)。

**建立`AfterAllowTestTraffic`勾點 Lambda 函數**

1.  使用下列內容建立名為 `AfterAllowTestTraffic.js` 的檔案。

   ```
   'use strict';
    
    const AWS = require('aws-sdk');
    const codedeploy = new AWS.CodeDeploy({apiVersion: '2014-10-06'});
    
    exports.handler = (event, context, callback) => {
    
    	console.log("Entering AfterAllowTestTraffic hook.");
    	
    	// Read the DeploymentId and LifecycleEventHookExecutionId from the event payload
     var deploymentId = event.DeploymentId;
    	var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;
    	var validationTestResult = "Failed";
    	
    	// Perform AfterAllowTestTraffic validation tests here. Set the test result 
    	// to "Succeeded" for this tutorial.
    	console.log("This is where AfterAllowTestTraffic validation tests happen.")
    	validationTestResult = "Succeeded";
    	
    	// Complete the AfterAllowTestTraffic hook by sending CodeDeploy the validation status
    	var params = {
    		deploymentId: deploymentId,
    		lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
    		status: validationTestResult // status can be 'Succeeded' or 'Failed'
    	};
    	
    	// Pass CodeDeploy the prepared validation test results.
    	codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) {
    		if (err) {
    			// Validation failed.
    			console.log('AfterAllowTestTraffic validation tests failed');
    			console.log(err, err.stack);
    			callback("CodeDeploy Status update failed");
    		} else {
    			// Validation succeeded.
    			console.log("AfterAllowTestTraffic validation tests succeeded");
    			callback(null, "AfterAllowTestTraffic validation tests succeeded");
    		}
    	});
    }
   ```

1.  建立 Lambda 部署套件。

   ```
   zip AfterAllowTestTraffic.zip AfterAllowTestTraffic.js 
   ```

1.  使用 `create-function`命令為您的`AfterAllowTestTraffic`勾點建立 Lambda 函數。

   ```
   aws lambda create-function --function-name AfterAllowTestTraffic \
          --zip-file fileb://AfterAllowTestTraffic.zip \
          --handler AfterAllowTestTraffic.handler \
          --runtime nodejs10.x \
          --role arn:aws:iam::aws-account-id:role/lambda-cli-hook-role
   ```

1.  在`create-function`回應中記下您的 Lambda 函數 ARN。在下一個步驟中更新 CodeDeploy 部署的 AppSpec 檔案時，您會使用此 ARN。

# 步驟 4：更新您的 AppSpec 檔案
<a name="tutorial-ecs-with-hooks-create-appspec-file"></a>

 在本節中，您會使用 `Hooks`區段更新 AppSpec 檔案。在 `Hooks`區段中，您可以為`AfterAllowTestTraffic`生命週期掛鉤指定 Lambda 函數。

**更新您的 AppSpec 檔案**

1.  開啟您在 中建立[步驟 2：建立 AppSpec 檔案](tutorial-ecs-create-appspec-file.md)的 AppSpec 檔案[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)。

1.  使用您在[步驟 2：更新您的 Amazon ECS 應用程式](tutorial-ecs-with-hooks-update-the-ecs-application.md)中記下的任務定義 ARN 來更新 `TaskDefinition` 屬性。

1. 將 `Hooks`區段複製並貼到您的 AppSpec 檔案。`AfterAllowTestTraffic` 使用您在 中記下的 Lambda 函數 ARN，更新 之後的 ARN[步驟 3：建立 lifecycle hook Lambda 函數](tutorial-ecs-with-hooks-create-hooks.md)。

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

   ```
   {
     "version": 0.0,
     "Resources": [
       {
         "TargetService": {
           "Type": "AWS::ECS::Service",
           "Properties": {
             "TaskDefinition": "arn:aws:ecs:aws-region-id:aws-account-id::task-definition/ecs-demo-task-definition:revision-number",
             "LoadBalancerInfo": {
               "ContainerName": "sample-website",
               "ContainerPort": 80
             }
           }
         }
       }
     ],
     "Hooks": [
       {
         "AfterAllowTestTraffic": "arn:aws:lambda:aws-region-id:aws-account-id:function:AfterAllowTestTraffic"
       }
     ]
   }
   ```

------
#### [ YAML AppSpec ]

   ```
   version: 0.0
   Resources:
     - TargetService:
         Type: AWS::ECS::Service
         Properties:
           TaskDefinition: "arn:aws:ecs:aws-region-id:aws-account-id::task-definition/ecs-demo-task-definition:revision-number"
           LoadBalancerInfo:
             ContainerName: "sample-website"
             ContainerPort: 80
   Hooks:
     - AfterAllowTestTraffic: "arn:aws:lambda:aws-region-id:aws-account-id:function:AfterAllowTestTraffic"
   ```

------

1.  儲存您的 AppSpec 檔案並上傳至其 S3 儲存貯體。

# 步驟 5：使用 CodeDeploy 主控台部署您的 Amazon ECS 服務
<a name="tutorial-ecs-with-hooks-deployment"></a>

 在本節中，您會指定測試接聽程式的連接埠，以更新部署群組。這是您在[步驟 1：建立測試接聽程式](tutorial-ecs-with-hooks-create-second-listener.md)中建立的接聽程式。在部署期間，CodeDeploy 會使用測試接聽程式提供給替代任務集的測試流量，在`AfterAllowTestTraffic`部署生命週期掛鉤期間執行驗證測試。您的驗證測試會傳回結果 `Succeeded`，因此部署會繼續進行下一個部署生命週期事件。在真實世界案例中，您的測試函數會傳回 `Succeeded` 或 `Failed`。

**將測試接聽程式新增至您的部署群組**

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/codedeploy/](https://console.aws.amazon.com/codedeploy/) 開啟 CodeDeploy 主控台。

1. 從導覽窗格中，選擇 **Applications (應用程式)**。

1. 選擇您在[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)中建立的應用程式。如果您使用建議的名稱，則為 **ecs-demo-codedeploy-app**。

1. 在 **Deployment group (部署群組)** 中，選擇您在[教學課程：將應用程式部署至 Amazon ECS](tutorial-ecs-deployment.md)中建立的部署群組。如果您已使用建議的名稱，則為 **ecs-demo-dg**。

1.  選擇**編輯**。

1. 從 **Test listener port (測試接聽程式連接埠)** 中，為您稍早在此教學課程中建立的測試接聽程式，選擇連接埠和通訊協定。此應為 **HTTP: 8080**。

1.  選擇**儲存變更**。

**部署 Amazon ECS 應用程式**

1. 從您的部署群組主控台頁面，選擇 **Create deployment (建立部署)**。

1.  針對 **Deployment group (部署群組)**，選擇 **ecs-demo-dg**。

1.  針對 **Revision type (修訂版類型)**，選擇 **My application is stored in Amazon S3 (我的應用程式存放在 Amazon S3)**。在**修訂位置**中，輸入 S3 儲存貯體的名稱和 AppSpec 檔案 （例如 **s3://my-s3-bucket/appspec.json**)。

1.  針對 **Revision file type (修訂檔案類型)**，視需要選擇 **.json** 或 **.yaml**。

1.  (選用) 在 **Deployment description (部署描述)** 中，輸入部署的描述。

1. 選擇 **Create deployment (建立部署)**。

 您可以在 **Deployment status (部署狀態)**中監控部署。將 100% 的生產流量路由至替代任務集後，您可以選擇**終止原始任務集**，以立即終止原始任務集。如果您不選擇 **Terminate original task set (終止原始任務集)**，原始任務集會在您建立部署群組時指定的持續時間後終止。

![\[CodeDeploy 主控台的部署狀態區段。\]](http://docs.aws.amazon.com/zh_tw/codedeploy/latest/userguide/images/ecs-tutorial-deployment-status-with-test-listener.png)


# 步驟 6：在 CloudWatch Logs 中檢視 Lambda 掛鉤函數輸出
<a name="tutorial-ecs-with-hooks-view-cw-logs"></a>

 如果您的 CodeDeploy 部署成功，Lambda 勾點函數中的驗證測試也會成功。您可以在 CloudWatch Logs 中查看勾點函數的日誌來確認這一點。

1. 透過 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 開啟 CloudWatch 主控台。

1.  從導覽窗格中，選擇 **Logs (日誌)**。您應該會看到 AppSpec 檔案中所指定 Lambda 勾點函數的一個新日誌群組。  
![\[CloudWatch 主控台中的新日誌群組。\]](http://docs.aws.amazon.com/zh_tw/codedeploy/latest/userguide/images/ecs-demo-cw-logs.png)

1.  選擇新的日誌群組。這應該是 **/aws/lambda/AfterAllowTestTrafficHook**。

1.  選擇日誌串流。如果您看到多個日誌串流，請選擇在 **Last Event Time (上次事件時間)** 下具有最新日期和時間的日誌串流。

1.  展開日誌串流事件，以確認您的 Lambda 勾點函數將成功訊息寫入日誌。以下顯示 `AfterAllowTraffic` Lambda 勾點函數成功。  
![\[顯示AfterAllowTraffic勾點的日誌串流事件。\]](http://docs.aws.amazon.com/zh_tw/codedeploy/latest/userguide/images/ecs-demo-cw-log-events.png)

# 步驟 7：清除
<a name="tutoria-ecs-with-hooks-clean-up"></a>

 完成此教學課程時，清除與其相關的資源，以免未使用的資源產生費用。此步驟中的資源名稱是本教學課程中建議的名稱 （例如，**ecs-demo-codedeploy-app**適用於 CodeDeploy 應用程式的名稱）。如果您使用不同的名稱，請務必在清理時使用這些名稱。

**清除教學課程資源**

1. 使用 [delete-deployment-group](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-deployment-group.html) 命令來刪除 CodeDeploy 部署群組。

   ```
   aws deploy delete-deployment-group --application-name ecs-demo-deployment-group --deployment-group-name ecs-demo-dg --region aws-region-id
   ```

1. 使用 [delete-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-application.html) 命令來刪除 CodeDeploy 應用程式。

   ```
   aws deploy delete-application --application-name ecs-demo-deployment-group --region aws-region-id
   ```

1. 使用 [delete-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/delete-function.html) 命令來刪除 Lambda 勾點函數。

   ```
   aws lambda delete-function --function-name AfterAllowTestTraffic
   ```

1. 使用 [delete-log-group](https://docs.aws.amazon.com/cli/latest/reference/logs/delete-log-group.html) 命令來刪除 CloudWatch 日誌群組。

   ```
   aws logs delete-log-group --log-group-name /aws/lambda/AfterAllowTestTraffic
   ```