

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

# Amazon ECS 教學課程
<a name="ecs-tutorials"></a>

以下教學課程說明如何使用 Amazon ECS 執行常見的任務。

您可以透過下列任一教學課程，進一步了解如何開始使用 Amazon ECS。


| 教學課程概觀 | 進一步了解 | 
| --- | --- | 
|  開始在 Fargate 上使用 Amazon ECS。  |  [了解如何為 Fargate 建立 Amazon ECS Linux 任務](getting-started-fargate.md)  | 
|  開始在 Fargate 上使用 Windows 容器。  |  [了解如何為 Fargate 建立 Amazon ECS Windows 任務](Windows_fargate-getting_started.md)  | 
|  開始使用 EC2 Windows 容器。  |  [了解如何為 EC2 建立 Amazon ECS Windows 任務](getting-started-ecs-ec2-v2.md)  | 

您可以使用下列任何教學課程，使用 在 Amazon ECS 上部署任務 AWS CLI


| 教學課程概觀 | 進一步了解 | 
| --- | --- | 
|  為 Fargate 建立 Linux 任務。  |  [使用 為 Fargate 建立 Amazon ECS Linux 任務 AWS CLI](ECS_AWSCLI_Fargate.md)  | 
|  為 Fargate 建立 Windows 任務。  |  [使用 為 Fargate 建立 Amazon ECS Windows 任務 AWS CLI](ECS_AWSCLI_Fargate_windows.md)  | 
|  為 EC2 建立 Linux 任務。  |  [使用 為 EC2 建立 Amazon ECS 任務 AWS CLI](ECS_AWSCLI_EC2.md)  | 

您可以透過下列任一教學課程，進一步了解監控與記錄相關知識。


| 教學課程概觀 | 進一步了解 | 
| --- | --- | 
|  設定一個簡單的 Lambda 函式，用於監聽任務事件並將之寫入 CloudWatch Logs 日誌串流。  |  [設定 Amazon ECS 監聽 CloudWatch Events 事件](ecs_cwet.md)  | 
|  設定一項 Amazon EventBridge 事件規則，使其僅擷取因其中一個必要容器終止而導致任務停止執行的任務事件。  |  [針對 Amazon ECS 任務停止事件傳送 Amazon Simple Notification Service 提醒](ecs_cwet2.md)  | 
|  串連最初屬於一筆內容但分割至多筆記錄或日誌明細行的日誌訊息。  |  [串連多行或堆疊追蹤的 Amazon ECS 日誌訊息](firelens-concatanate-multiline.md)  | 
|  在於 Amazon ECS 中執行的 Windows 執行個體上部署 Fluent Bit 容器，將 Windows 任務產生的日誌串流至 Amazon CloudWatch 進行集中式記錄。  |  [在 Amazon ECS Windows 容器上部署 Fluent Bit](tutorial-deploy-fluentbit-on-windows.md)  | 

您可以透過下列任一教學課程，進一步了解如何在 Amazon ECS 上搭配 Active Directory 身分驗證使用群組受管服務帳戶。


| 教學課程概觀 | 進一步了解 | 
| --- | --- | 
|  在 EC2 上搭配 Linux 容器使用群組受管服務帳戶。  |  [在 Amazon ECS 上為 EC2 Linux 容器使用 gMSA](linux-gmsa.md)  | 
|  在 EC2 上搭配 Windows 容器使用群組受管服務帳戶。  |  [了解如何在 Amazon ECS 上為 EC2 Windows 容器使用 gMSA](windows-gmsa.md)  | 
|  在 Fargate 上搭配 Linux 容器使用群組受管服務帳戶。  |  [在 Fargate 上為 Linux 容器使用 gMSA](fargate-linux-gmsa.md)  | 
|  建立一個執行 Windows 容器的任務，該容器具備透過無網域群組受管服務帳戶存取 Active Directory 的憑證。  |  [gMSA 使用 搭配無網域使用 Amazon ECS Windows 容器 AWS CLI](tutorial-gmsa-windows.md)  | 

# 使用 為 Fargate 建立 Amazon ECS Linux 任務 AWS CLI
<a name="ECS_AWSCLI_Fargate"></a>

以下步驟會協助您使用 AWS CLI在 Amazon ECS 中設定叢集、註冊任務定義、執行 Linux 任務，以及執行其他常見案例。使用 AWS CLI的最新版本。如需有關如何升級至最新版本的詳細資訊，請參閱 [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。

**Topics**
+ [

## 先決條件
](#ECS_AWSCLI_Fargate_prereq)
+ [

## 步驟 1：建立叢集
](#ECS_AWSCLI_Fargate_create_cluster)
+ [

## 步驟 2：註冊 Linux 任務定義
](#ECS_AWSCLI_Fargate_register_task_definition)
+ [

## 步驟 3：列出任務定義
](#ECS_AWSCLI_Fargate_list_task_definitions)
+ [

## 步驟 4：建立服務
](#ECS_AWSCLI_Fargate_create_service)
+ [

## 步驟 5：列出服務
](#ECS_AWSCLI_Fargate_list_services)
+ [

## 步驟 6：描述執行中的服務
](#ECS_AWSCLI_Fargate_describe_service)
+ [

## 步驟 7：測試
](#ECS_AWSCLI_Fargate_test)
+ [

## 步驟 8：清除
](#ECS_AWSCLI_Fargate_clean_up)

## 先決條件
<a name="ECS_AWSCLI_Fargate_prereq"></a>

本教學課程假設已完成下列先決條件。
+  AWS CLI 已安裝並設定最新版本的 。如需安裝或升級 AWS CLI、[安裝或更新至最新版本 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)的詳細資訊。
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+ 您已建立 VPC 和安全群組。本教學課程使用託管於 Amazon ECR Public 的容器映像，因此任務必須有網際網路連線。若要將網際網路的路由提供給任務，請使用下列其中一個選項。
  + 透過具有彈性 IP 地址的 NAT 閘道使用私有子網路。
  + 使用公有子網路，然後將公有 IP 地址指派給任務。

  如需詳細資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。

  如需有關安全群組和規則的資訊，請參閱《Amazon Virtual Private Cloud 使用者指南》**中的 [VPC 的預設安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#DefaultSecurityGroup)和[規則範例](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#security-group-rule-examples)。
+  如果您使用私有子網路遵循本教學課程，則可以使用 Amazon ECS Exec 直接與您的容器互動並測試部署。您必須建立任務 IAM 角色才能使用 ECS Exec。如需有關任務 IAM 角色及其他先決條件的詳細資訊，請參閱[使用 Amazon ECS Exec 監控 Amazon ECS 容器](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html)。
+ （選用） AWS CloudShell 是一種工具，可為客戶提供命令列，而不需要建立自己的 EC2 執行個體。如需詳細資訊，請參閱*AWS CloudShell 《 使用者指南*》中的[什麼是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 步驟 1：建立叢集
<a name="ECS_AWSCLI_Fargate_create_cluster"></a>

您的帳戶預設會得到 `default` 叢集。

**注意**  
使用為您提供之 `default` 叢集的優點是，您不必在後續的命令中指定 `--cluster cluster_name` 選項。如果您建立的是自己的叢集，不是預設叢集，您必須在打算對該叢集使用的每個命令中指定 `--cluster cluster_name`。

使用下列命令以唯一的名稱建立您自己的叢集：

```
aws ecs create-cluster --cluster-name fargate-cluster
```

輸出：

```
{
    "cluster": {
        "status": "ACTIVE", 
        "defaultCapacityProviderStrategy": [], 
        "statistics": [], 
        "capacityProviders": [], 
        "tags": [], 
        "clusterName": "fargate-cluster", 
        "settings": [
            {
                "name": "containerInsights", 
                "value": "disabled"
            }
        ], 
        "registeredContainerInstancesCount": 0, 
        "pendingTasksCount": 0, 
        "runningTasksCount": 0, 
        "activeServicesCount": 0, 
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster"
    }
}
```

## 步驟 2：註冊 Linux 任務定義
<a name="ECS_AWSCLI_Fargate_register_task_definition"></a>

您必須先註冊任務定義，才能在您的 ECS 叢集中執行任務。任務定義是分在一組的容器清單。下列範例是使用託管於 Docker Hub 的 httpd 容器映像來建立 PHP Web 應用程式的簡單任務定義。如需可用之任務定義參數的詳細資訊，請參閱「[Amazon ECS 任務定義](task_definitions.md)」。在本教學課程中，僅當您在私有子網路中部署任務並希望測試部署時，才需要 `taskRoleArn`。如 [先決條件](#ECS_AWSCLI_Fargate_prereq) 中所述，將 `taskRoleArn` 取代為您為使用 ECS Exec 建立的 IAM 任務角色。

```
 {
        "family": "sample-fargate",
        "networkMode": "awsvpc",
        "taskRoleArn": "arn:aws:iam::aws_account_id:role/execCommandRole", 
        "containerDefinitions": [
            {
                "name": "fargate-app",
                "image": "public.ecr.aws/docker/library/httpd:latest",
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "entryPoint": [
                    "sh",
                    "-c"
                ],
                "command": [
                    "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                ]
            }
        ],
        "requiresCompatibilities": [
            "FARGATE"
        ],
        "cpu": "256",
        "memory": "512"
}
```

將任務定義 JSON 儲存為檔案，並使用 `--cli-input-json file://path_to_file.json` 選項進行傳遞。

將 JSON 檔案用於容器定義中：

```
aws ecs register-task-definition --cli-input-json file://$HOME/tasks/fargate-task.json
```

**register-task-definition** 命令會在完成註冊後傳回任務定義的描述。

## 步驟 3：列出任務定義
<a name="ECS_AWSCLI_Fargate_list_task_definitions"></a>

您可以使用 **list-task-definitions** 命令隨時列出您帳戶的任務定義。這個命令的輸出會顯示 `family` 和 `revision` 值，可在呼叫 **run-task** 或 **start-task** 時一起使用。

```
aws ecs list-task-definitions
```

輸出：

```
{
    "taskDefinitionArns": [
        "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1"
    ]
}
```

## 步驟 4：建立服務
<a name="ECS_AWSCLI_Fargate_create_service"></a>

為您的帳戶註冊任務之後，您就可以在您的叢集中建立已註冊任務的服務。在此範例中，您將透過在叢集中執行之 `sample-fargate:1` 任務定義的一個執行個體建立服務。該任務需要網際網路的路由，因此您可透過兩種方法達成。一種方法是，使用透過 NAT 閘道所設定的私有子網路，而該閘道在公有子網路中具有彈性 IP 地址。另一種方法是，使用公有子網路並將公有 IP 地址指派至任務。以下提供這兩種範例。

使用私有子網路的範例。需要 ` enable-execute-command ` 選項才能使用 Amazon ECS Exec。

```
aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234]}" --enable-execute-command
```

使用公有子網路的範例。

```
aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234],assignPublicIp=ENABLED}"
```

**create-service** 命令會在完成註冊後傳回任務定義的描述。

## 步驟 5：列出服務
<a name="ECS_AWSCLI_Fargate_list_services"></a>

列出您叢集的服務。您應該會看到您在先前一節所建立的服務。您可以記下這個命令傳回的服務名稱或完整的 ARN，稍後將用以描述服務。

```
aws ecs list-services --cluster fargate-cluster
```

輸出：

```
{
    "serviceArns": [
        "arn:aws:ecs:region:aws_account_id:service/fargate-cluster/fargate-service"
    ]
}
```

## 步驟 6：描述執行中的服務
<a name="ECS_AWSCLI_Fargate_describe_service"></a>

使用之前擷取的服務名稱來描述服務，以取得任務的詳細資訊。

```
aws ecs describe-services --cluster fargate-cluster --services fargate-service
```

如果成功，這會傳回服務失敗和服務的描述。例如，在 ` services ` 區段中，您將可以找到部署的相關資訊，例如執行中或擱置中的任務狀態。您也可以找到任務定義、網路組態和時間戳記事件的相關資訊。在失敗區段中，您將可以找到與呼叫相關聯的失敗 (如果有的話) 的相關資訊。如需故障診斷，請參閱[服務事件訊息](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-event-messages.html)。如需服務描述的詳細資訊，請參閱[描述服務](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DescribeServices)。

```
{
    "services": [
        {
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-abcd1234"
                    ], 
                    "securityGroups": [
                        "sg-abcd1234"
                    ], 
                    "assignPublicIp": "ENABLED"
                }
            }, 
            "launchType": "FARGATE", 
            "enableECSManagedTags": false, 
            "loadBalancers": [], 
            "deploymentController": {
                "type": "ECS"
            }, 
            "desiredCount": 1, 
            "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster", 
            "serviceArn": "arn:aws:ecs:region:aws_account_id:service/fargate-service", 
            "deploymentConfiguration": {
                "maximumPercent": 200, 
                "minimumHealthyPercent": 100
            }, 
            "createdAt": 1692283199.771, 
            "schedulingStrategy": "REPLICA", 
            "placementConstraints": [], 
            "deployments": [
                {
                    "status": "PRIMARY", 
                    "networkConfiguration": {
                        "awsvpcConfiguration": {
                            "subnets": [
                                "subnet-abcd1234"
                            ], 
                            "securityGroups": [
                                "sg-abcd1234"
                            ], 
                            "assignPublicIp": "ENABLED"
                        }
                    }, 
                    "pendingCount": 0, 
                    "launchType": "FARGATE", 
                    "createdAt": 1692283199.771, 
                    "desiredCount": 1, 
                    "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1", 
                    "updatedAt": 1692283199.771, 
                    "platformVersion": "1.4.0", 
                    "id": "ecs-svc/9223370526043414679", 
                    "runningCount": 0
                }
            ], 
            "serviceName": "fargate-service", 
            "events": [
                {
                    "message": "(service fargate-service) has started 2 tasks: (task 53c0de40-ea3b-489f-a352-623bf1235f08) (task d0aec985-901b-488f-9fb4-61b991b332a3).", 
                    "id": "92b8443e-67fb-4886-880c-07e73383ea83", 
                    "createdAt": 1510811841.408
                }, 
                {
                    "message": "(service fargate-service) has started 2 tasks: (task b4911bee-7203-4113-99d4-e89ba457c626) (task cc5853e3-6e2d-4678-8312-74f8a7d76474).", 
                    "id": "d85c6ec6-a693-43b3-904a-a997e1fc844d", 
                    "createdAt": 1510811601.938
                }, 
                {
                    "message": "(service fargate-service) has started 2 tasks: (task cba86182-52bf-42d7-9df8-b744699e6cfc) (task f4c1ad74-a5c6-4620-90cf-2aff118df5fc).", 
                    "id": "095703e1-0ca3-4379-a7c8-c0f1b8b95ace", 
                    "createdAt": 1510811364.691
                }
            ], 
            "runningCount": 0, 
            "status": "ACTIVE", 
            "serviceRegistries": [], 
            "pendingCount": 0, 
            "createdBy": "arn:aws:iam::aws_account_id:user/user_name", 
            "platformVersion": "LATEST", 
            "placementStrategy": [], 
            "propagateTags": "NONE", 
            "roleArn": "arn:aws:iam::aws_account_id:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS", 
            "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1"
        }
    ], 
    "failures": []
}
```

## 步驟 7：測試
<a name="ECS_AWSCLI_Fargate_test"></a>

### 使用公有子網路部署的測試任務
<a name="ECS_AWSCLI_Fargate_test_public"></a>

描述服務中的任務，以便取得任務的彈性網路介面 (ENI)。

首先，要取得任務 ARN。

```
aws ecs list-tasks --cluster fargate-cluster --service fargate-service
```

輸出包含任務 ARN。

```
{
    "taskArns": [
        "arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE
    ]
}
```

描述任務並找到 ENI ID。將任務 ARN 用於 `tasks` 參數。

```
aws ecs describe-tasks --cluster fargate-cluster --tasks arn:aws:ecs:us-east-1:123456789012:task/service/EXAMPLE
```

連接資訊將在輸出中列出。

```
{
    "tasks": [
        {
            "attachments": [
                {
                    "id": "d9e7735a-16aa-4128-bc7a-b2d5115029e9",
                    "type": "ElasticNetworkInterface",
                    "status": "ATTACHED",
                    "details": [
                        {
                            "name": "subnetId",
                            "value": "subnetabcd1234"
                        },
                        {
                            "name": "networkInterfaceId",
                            "value": "eni-0fa40520aeEXAMPLE"
                        },
                    ]
                }
…
}
```

描述 ENI 以獲得公有 IP 地址。

```
aws ec2 describe-network-interfaces --network-interface-id  eni-0fa40520aeEXAMPLE
```

公有 IP 地址會在輸出中。

```
{
    "NetworkInterfaces": [
        {
            "Association": {
                "IpOwnerId": "amazon",
                "PublicDnsName": "ec2-34-229-42-222.compute-1.amazonaws.com",
                "PublicIp": "198.51.100.2"
            },
…
}
```

在 Web 瀏覽器中輸入公有 IP 地址，然後您應該會看到顯示 **Amazon ECS** 範例應用程式的網頁。

### 使用私有子網路部署的測試任務
<a name="ECS_AWSCLI_Fargate_test_private.title"></a>

 描述任務並找出 `managedAgents`，以驗證 `ExecuteCommandAgent` 是否正在執行。記下 `privateIPv4Address` 以供稍後使用。

```
aws ecs describe-tasks --cluster fargate-cluster --tasks arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE
```

 受管代理程式資訊將在輸出中列出。

```
{
     "tasks": [
        {
            "attachments": [
                {
                    "id": "d9e7735a-16aa-4128-bc7a-b2d5115029e9",
                    "type": "ElasticNetworkInterface",
                    "status": "ATTACHED",
                    "details": [
                        {
                            "name": "subnetId",
                            "value": "subnetabcd1234"
                        },
                        {
                            "name": "networkInterfaceId",
                            "value": "eni-0fa40520aeEXAMPLE"
                        },
                        {
                            "name": "privateIPv4Address",
                            "value": "10.0.143.156"
                        }
                    ]
                }
            ],
     ...  
     "containers": [
         {
         ...
        "managedAgents": [
                        {
                            "lastStartedAt": "2023-08-01T16:10:13.002000+00:00",
                            "name": "ExecuteCommandAgent",
                            "lastStatus": "RUNNING"
                        } 
                ],
        ...
    }
```

 驗證 ` ExecuteCommandAgent` 正在執行之後，您可以執行下列命令，以在任務中的容器上執行互動式 Shell。

```
  aws ecs execute-command --cluster fargate-cluster \
      --task  arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE  \
      --container  fargate-app \
      --interactive \
      --command "/bin/sh"
```

 互動式 Shell 執行後，執行以下命令來安裝 cURL。

```
apt update 
```

```
apt install curl 
```

 安裝 cURL 後，使用您先前獲得的私有 IP 地址執行以下命令。

```
 curl 10.0.143.156 
```

 您應該會看到相當於 **Amazon ECS** 範例應用程式網頁的 HTML。

```
<html>
    <head> 
     <title>Amazon ECS Sample App</title> 
     <style>body {margin-top: 40px; background-color: #333;} </style>
    </head>
      <body> 
      <div style=color:white;text-align:center> 
      <h1>Amazon ECS Sample App</h1> 
      <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> 
      </div>
      </body>
</html>
```

## 步驟 8：清除
<a name="ECS_AWSCLI_Fargate_clean_up"></a>

完成此教學課程時，建議您清除相關聯的資源，以免未使用的資源產生費用。

刪除服務。

```
aws ecs delete-service --cluster fargate-cluster --service fargate-service --force
```

刪除叢集。

```
aws ecs delete-cluster --cluster fargate-cluster
```

# 使用 為 Fargate 建立 Amazon ECS Windows 任務 AWS CLI
<a name="ECS_AWSCLI_Fargate_windows"></a>

以下步驟會協助您使用 AWS CLI在 Amazon ECS 中設定叢集、註冊任務定義、執行 Windows 任務，以及執行其他常見案例。請務必使用最新版本的 AWS CLI。如需有關如何升級至最新版本的詳細資訊，請參閱 [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。

**Topics**
+ [

## 先決條件
](#ECS_AWSCLI_Fargate_windows_prereq)
+ [

## 步驟 1：建立叢集
](#ECS_AWSCLI_Fargate_windows_create_cluster)
+ [

## 步驟 2：註冊 Windows 任務定義
](#ECS_AWSCLI_Fargate_windows_register_task_definition)
+ [

## 步驟 3：列出任務定義
](#ECS_AWSCLI_Fargate_windows__list_task_definitions)
+ [

## 步驟 4：建立服務
](#ECS_AWSCLI_Fargate_windows_create_service)
+ [

## 步驟 5：列出服務
](#ECS_AWSCLI_Fargate_windows_list_services)
+ [

## 步驟 6：描述執行中的服務
](#ECS_AWSCLI_Fargate_windows_describe_service)
+ [

## 步驟 7：清除
](#ECS_AWSCLI_Fargate_windows_clean_up)

## 先決條件
<a name="ECS_AWSCLI_Fargate_windows_prereq"></a>

本教學課程假設已完成下列先決條件。
+  AWS CLI 已安裝並設定最新版本的 。如需安裝或升級 的詳細資訊 AWS CLI，請參閱[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+ 您已建立 VPC 和安全群組。本教學課程使用託管於 Docker Hub 的容器映像，因此任務必須有網際網路連線。若要將網際網路的路由提供給任務，請使用下列其中一個選項。
  + 透過具有彈性 IP 地址的 NAT 閘道使用私有子網路。
  + 使用公有子網路，然後將公有 IP 地址指派給任務。

  如需詳細資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。

  如需有關安全群組和規則的資訊，請參閱《Amazon Virtual Private Cloud 使用者指南》**中的 [VPC 的預設安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#DefaultSecurityGroup)和[規則範例](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#security-group-rule-examples)。
+ （選用） AWS CloudShell 是一種工具，可為客戶提供命令列，而不需要建立自己的 EC2 執行個體。如需詳細資訊，請參閱*AWS CloudShell 《 使用者指南*》中的[什麼是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 步驟 1：建立叢集
<a name="ECS_AWSCLI_Fargate_windows_create_cluster"></a>

您的帳戶預設會得到 `default` 叢集。

**注意**  
使用為您提供之 `default` 叢集的優點是，您不必在後續的命令中指定 `--cluster cluster_name` 選項。如果您建立的是自己的叢集，不是預設叢集，您必須在打算對該叢集使用的每個命令中指定 `--cluster cluster_name`。

使用下列命令以唯一的名稱建立您自己的叢集：

```
aws ecs create-cluster --cluster-name fargate-cluster
```

輸出：

```
{
    "cluster": {
        "status": "ACTIVE", 
        "statistics": [], 
        "clusterName": "fargate-cluster", 
        "registeredContainerInstancesCount": 0, 
        "pendingTasksCount": 0, 
        "runningTasksCount": 0, 
        "activeServicesCount": 0, 
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster"
    }
}
```

## 步驟 2：註冊 Windows 任務定義
<a name="ECS_AWSCLI_Fargate_windows_register_task_definition"></a>

您必須先註冊任務定義，才能在您的 Amazon ECS 叢集中執行 Windows 任務。任務定義是分在一組的容器清單。以下範例是建立 Web 應用程式的簡單任務定義。如需可用之任務定義參數的詳細資訊，請參閱「[Amazon ECS 任務定義](task_definitions.md)」。

```
{
    "containerDefinitions": [
        {
            "command": ["New-Item -Path C:\\inetpub\\wwwroot\\index.html -Type file -Value '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p>'; C:\\ServiceMonitor.exe w3svc"],
            "entryPoint": [
                "powershell",
                "-Command"
            ],
            "essential": true,
            "cpu": 2048,
            "memory": 4096,
            "image": "mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019",
            "name": "sample_windows_app",
            "portMappings": [
                {
                    "hostPort": 80,
                    "containerPort": 80,
                    "protocol": "tcp"
                }
            ]
        }
    ],
    "memory": "4096",
    "cpu": "2048",
    "networkMode": "awsvpc",
    "family": "windows-simple-iis-2019-core",
    "executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
    "runtimePlatform": {"operatingSystemFamily": "WINDOWS_SERVER_2019_CORE"},
    "requiresCompatibilities": ["FARGATE"]
}
```

上述範例 JSON 可以透過 AWS CLI 兩種方式傳遞至 ：您可以將任務定義 JSON 儲存為 檔案，並使用 `--cli-input-json file://path_to_file.json`選項將其傳遞。

將 JSON 檔案用於容器定義中：

```
aws ecs register-task-definition --cli-input-json file://$HOME/tasks/fargate-task.json
```

**register-task-definition** 命令會在完成註冊後傳回任務定義的描述。

## 步驟 3：列出任務定義
<a name="ECS_AWSCLI_Fargate_windows__list_task_definitions"></a>

您可以使用 **list-task-definitions** 命令隨時列出您帳戶的任務定義。這個命令的輸出會顯示 `family` 和 `revision` 值，可在呼叫 **run-task** 或 **start-task** 時一起使用。

```
aws ecs list-task-definitions
```

輸出：

```
{
    "taskDefinitionArns": [
        "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate-windows:1"
    ]
}
```

## 步驟 4：建立服務
<a name="ECS_AWSCLI_Fargate_windows_create_service"></a>

為您的帳戶註冊任務之後，您就可以在您的叢集中建立已註冊任務的服務。在此範例中，您將透過在叢集中執行之 `sample-fargate:1` 任務定義的一個執行個體建立服務。該任務需要網際網路的路由，因此您可透過兩種方法達成。一種方法是，使用透過 NAT 閘道所設定的私有子網路，而該閘道在公有子網路中具有彈性 IP 地址。另一種方法是，使用公有子網路並將公有 IP 地址指派至任務。以下提供這兩種範例。

使用私有子網路的範例。

```
aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate-windows:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234]}"
```

使用公有子網路的範例。

```
aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate-windows:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234],assignPublicIp=ENABLED}"
```

**create-service** 命令會在完成註冊後傳回任務定義的描述。

## 步驟 5：列出服務
<a name="ECS_AWSCLI_Fargate_windows_list_services"></a>

列出您叢集的服務。您應該會看到您在先前一節所建立的服務。您可以記下這個命令傳回的服務名稱或完整的 ARN，稍後將用以描述服務。

```
aws ecs list-services --cluster fargate-cluster
```

輸出：

```
{
    "serviceArns": [
        "arn:aws:ecs:region:aws_account_id:service/fargate-service"
    ]
}
```

## 步驟 6：描述執行中的服務
<a name="ECS_AWSCLI_Fargate_windows_describe_service"></a>

使用之前擷取的服務名稱來描述服務，以取得任務的詳細資訊。

```
aws ecs describe-services --cluster fargate-cluster --services fargate-service
```

如果成功，這會傳回服務失敗和服務的描述。例如，在服務區段中，您將可以找到部署的相關資訊，例如執行中或擱置中的任務狀態。您也可以找到任務定義、網路組態和時間戳記事件的相關資訊。在失敗區段中，您將可以找到與呼叫相關聯的失敗 (如果有的話) 的相關資訊。如需故障診斷，請參閱[服務事件訊息](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-event-messages.html)。如需服務描述的詳細資訊，請參閱[描述服務](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_DescribeServices)。

```
{
    "services": [
        {
            "status": "ACTIVE", 
            "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate-windows:1", 
            "pendingCount": 2, 
            "launchType": "FARGATE", 
            "loadBalancers": [], 
            "roleArn": "arn:aws:iam::aws_account_id:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS", 
            "placementConstraints": [], 
            "createdAt": 1510811361.128, 
            "desiredCount": 2, 
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-abcd1234"
                    ], 
                    "securityGroups": [
                        "sg-abcd1234"
                    ], 
                    "assignPublicIp": "DISABLED"
                }
            }, 
            "platformVersion": "LATEST", 
            "serviceName": "fargate-service", 
            "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster", 
            "serviceArn": "arn:aws:ecs:region:aws_account_id:service/fargate-service", 
            "deploymentConfiguration": {
                "maximumPercent": 200, 
                "minimumHealthyPercent": 100
            }, 
            "deployments": [
                {
                    "status": "PRIMARY", 
                    "networkConfiguration": {
                        "awsvpcConfiguration": {
                            "subnets": [
                                "subnet-abcd1234"
                            ], 
                            "securityGroups": [
                                "sg-abcd1234"
                            ], 
                            "assignPublicIp": "DISABLED"
                        }
                    }, 
                    "pendingCount": 2, 
                    "launchType": "FARGATE", 
                    "createdAt": 1510811361.128, 
                    "desiredCount": 2, 
                    "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate-windows:1", 
                    "updatedAt": 1510811361.128, 
                    "platformVersion": "0.0.1", 
                    "id": "ecs-svc/9223370526043414679", 
                    "runningCount": 0
                }
            ], 
            "events": [
                {
                    "message": "(service fargate-service) has started 2 tasks: (task 53c0de40-ea3b-489f-a352-623bf1235f08) (task d0aec985-901b-488f-9fb4-61b991b332a3).", 
                    "id": "92b8443e-67fb-4886-880c-07e73383ea83", 
                    "createdAt": 1510811841.408
                }, 
                {
                    "message": "(service fargate-service) has started 2 tasks: (task b4911bee-7203-4113-99d4-e89ba457c626) (task cc5853e3-6e2d-4678-8312-74f8a7d76474).", 
                    "id": "d85c6ec6-a693-43b3-904a-a997e1fc844d", 
                    "createdAt": 1510811601.938
                }, 
                {
                    "message": "(service fargate-service) has started 2 tasks: (task cba86182-52bf-42d7-9df8-b744699e6cfc) (task f4c1ad74-a5c6-4620-90cf-2aff118df5fc).", 
                    "id": "095703e1-0ca3-4379-a7c8-c0f1b8b95ace", 
                    "createdAt": 1510811364.691
                }
            ], 
            "runningCount": 0, 
            "placementStrategy": []
        }
    ], 
    "failures": []
}
```

## 步驟 7：清除
<a name="ECS_AWSCLI_Fargate_windows_clean_up"></a>

完成此教學課程時，建議您清除相關聯的資源，以免未使用的資源產生費用。

刪除服務。

```
aws ecs delete-service --cluster fargate-cluster --service fargate-service --force
```

刪除叢集。

```
aws ecs delete-cluster --cluster fargate-cluster
```

# 使用 為 EC2 建立 Amazon ECS 任務 AWS CLI
<a name="ECS_AWSCLI_EC2"></a>

以下步驟會協助您使用 AWS CLI在 Amazon ECS 中設定叢集、註冊任務定義、執行任務，以及執行其他常見案例。使用 AWS CLI的最新版本。如需有關如何升級至最新版本的詳細資訊，請參閱 [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。

**Topics**
+ [

## 先決條件
](#AWSCLI_EC2_prereq)
+ [

## 建立 叢集
](#AWSCLI_EC2_create_cluster)
+ [

## 使用 Amazon ECS AMI 啟動容器執行個體
](#AWSCLI_EC2_launch_container_instance)
+ [

## 列出容器執行個體
](#AWSCLI_EC2_list_container_instances)
+ [

## 描述容器執行個體
](#AWSCLI_EC2_describe_container_instance)
+ [

## 註冊任務定義
](#AWSCLI_EC2_register_task_definition)
+ [

## 列出任務定義
](#AWSCLI_EC2_list_task_definitions)
+ [

## 建立服務
](#AWSCLI_EC2_run_task)
+ [

## 列出服務
](#AWSCLI_EC2_list_tasks)
+ [

## 描述服務
](#AWSCLI_EC2_describe_service)
+ [

## 描述執行中的任務
](#AWSCLI_EC2_describe_task)
+ [

## 測試 Web 伺服器
](#AWSCLI_EC2_test_web_server)
+ [

## 清除資源
](#AWSCLI_EC2_clean_up_resources)

## 先決條件
<a name="AWSCLI_EC2_prereq"></a>

本教學課程假設已完成下列先決條件：
+  AWS CLI 已安裝並設定最新版本的 。如需安裝或升級 的詳細資訊 AWS CLI，請參閱[安裝或更新至最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+ 您已建立可供使用的容器執行個體 IAM 角色。如需詳細資訊，請參閱 [Amazon ECS 容器執行個體 IAM 角色](instance_IAM_role.md)。
+ 您已建立可供使用的 VPC。如需詳細資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。
+ （選用） AWS CloudShell 是一種工具，可為客戶提供命令列，而不需要建立自己的 EC2 執行個體。如需詳細資訊，請參閱*AWS CloudShell 《 使用者指南*》中的[什麼是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 建立 叢集
<a name="AWSCLI_EC2_create_cluster"></a>

當您啟動第一個容器執行個體時，您的帳戶預設會得到 `default` 叢集。

**注意**  
使用為您提供之 `default` 叢集的優點是，您不必在後續的命令中指定 `--cluster cluster_name` 選項。如果您建立的是自己的叢集，不是預設叢集，您必須在打算對該叢集使用的每個命令中指定 `--cluster cluster_name`。

使用下列命令以唯一的名稱建立您自己的叢集：

```
aws ecs create-cluster --cluster-name MyCluster
```

輸出：

```
{
    "cluster": {
        "clusterName": "MyCluster",
        "status": "ACTIVE",
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/MyCluster"
    }
}
```

## 使用 Amazon ECS AMI 啟動容器執行個體
<a name="AWSCLI_EC2_launch_container_instance"></a>

容器執行個體是執行 Amazon ECS 容器代理程式並已在叢集中註冊的 EC2 執行個體。在本節中，您將使用 ECS 最佳化 AMI 來啟動 EC2 執行個體。

**使用 啟動容器執行個體 AWS CLI**

1.  AWS 區域 使用下列命令擷取 的最新 ECS 最佳化 Amazon Linux 2 AMI ID。此命令使用 AWS Systems Manager 參數存放區來取得最新的 ECS 最佳化 AMI ID。AMI 包含預先安裝的 Amazon ECS 容器代理程式與 Docker 執行時期。

   ```
   aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/recommended --query 'Parameters[0].Value' --output text | jq -r '.image_id'
   ```

   輸出：

   ```
   ami-abcd1234
   ```

1. 建立一個安全群組，該群組允許透過 SSH 存取來管理容器執行個體，也允許 Web 伺服器的 HTTP 存取。

   ```
   aws ec2 create-security-group --group-name ecs-tutorial-sg --description "ECS tutorial security group"
   ```

   輸出：

   ```
   {
       "GroupId": "sg-abcd1234"
   }
   ```

1. 執行下列命令，將傳入規則新增至安全群組。

   ```
   aws ec2 authorize-security-group-ingress --group-id sg-abcd1234 --protocol tcp --port 80 --cidr 0.0.0.0/0
   ```

   輸出：

   ```
   {
       "Return": true,
       "SecurityGroupRules": [
           {
               "SecurityGroupRuleId": "sgr-efgh5678",
               "GroupId": "sg-abcd1234",
               "GroupOwnerId": "123456789012",
               "IsEgress": false,
               "IpProtocol": "tcp",
               "FromPort": 80,
               "ToPort": 80,
               "CidrIpv4": "0.0.0.0/0"
           }
       ]
   }
   ```

   安全群組現在允許來自指定 IP 範圍的 SSH 存取，也允許來自任何位置的 HTTP 存取。在生產環境中，您應將 SSH 存取限制為特定 IP 位址，並視需要考量限制 HTTP 存取。

1. 建立一個用於對容器執行個體進行 SSH 存取的 EC2 金鑰對。

   ```
   aws ec2 create-key-pair --key-name ecs-tutorial-key --query 'KeyMaterial' --output text > ecs-tutorial-key.pem
   chmod 400 ecs-tutorial-key.pem
   ```

   私有金鑰會儲存至本機電腦，且具有適用於 SSH 存取的適當許可。

1. 使用 ECS 最佳化 AMI 啟動 EC2 執行個體，並將執行個體設定為加入叢集。

   ```
   aws ec2 run-instances --image-id ami-abcd1234 --instance-type t3.micro --key-name ecs-tutorial-key --security-group-ids sg-abcd1234 --iam-instance-profile Name=ecsInstanceRole --user-data '#!/bin/bash
   echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.config'
   {
       "Instances": [
           {
               "InstanceId": "i-abcd1234",
               "ImageId": "ami-abcd1234",
               "State": {
                   "Code": 0,
                   "Name": "pending"
               },
               "PrivateDnsName": "",
               "PublicDnsName": "",
               "StateReason": {
                   "Code": "pending",
                   "Message": "pending"
               },
               "InstanceType": "t3.micro",
               "KeyName": "ecs-tutorial-key",
               "LaunchTime": "2025-01-13T10:30:00.000Z"
           }
       ]
   }
   ```

   使用者資料指令碼會設定 Amazon ECS 代理程式，將執行個體註冊至 `MyCluster`。執行個體使用 `ecsInstanceRole` IAM 角色，該角色為代理程式提供必要許可。

## 列出容器執行個體
<a name="AWSCLI_EC2_list_container_instances"></a>

在您啟動容器執行個體後的幾分鐘內，Amazon ECS 代理程式會將該執行個體註冊至您的 MyCluster 叢集。您可以執行下列命令列出叢集中的容器執行個體：

```
aws ecs list-container-instances --cluster MyCluster
```

輸出：

```
{
    "containerInstanceArns": [
        "arn:aws:ecs:us-east-1:aws_account_id:container-instance/container_instance_ID"
    ]
}
```

## 描述容器執行個體
<a name="AWSCLI_EC2_describe_container_instance"></a>

在您取得容器執行個體的 ARN 或 ID 之後，您可以使用 **describe-container-instances** 命令取得執行個體的實用資訊，例如剩餘的和已註冊的 CPU 與記憶體資源。

```
aws ecs describe-container-instances --cluster MyCluster --container-instances container_instance_ID
```

輸出：

```
{
    "failures": [],
    "containerInstances": [
        {
            "status": "ACTIVE",
            "registeredResources": [
                {
                    "integerValue": 1024,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "CPU",
                    "doubleValue": 0.0
                },
                {
                    "integerValue": 995,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "MEMORY",
                    "doubleValue": 0.0
                },
                {
                    "name": "PORTS",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [
                        "22",
                        "2376",
                        "2375",
                        "51678"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                },
                {
                    "name": "PORTS_UDP",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ],
            "ec2InstanceId": "instance_id",
            "agentConnected": true,
            "containerInstanceArn": "arn:aws:ecs:us-west-2:aws_account_id:container-instance/container_instance_ID",
            "pendingTasksCount": 0,
            "remainingResources": [
                {
                    "integerValue": 1024,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "CPU",
                    "doubleValue": 0.0
                },
                {
                    "integerValue": 995,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "MEMORY",
                    "doubleValue": 0.0
                },
                {
                    "name": "PORTS",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [
                        "22",
                        "2376",
                        "2375",
                        "51678"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                },
                {
                    "name": "PORTS_UDP",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ],
            "runningTasksCount": 0,
            "attributes": [
                {
                    "name": "com.amazonaws.ecs.capability.privileged-container"
                },
                {
                    "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
                },
                {
                    "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
                },
                {
                    "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
                },
                {
                    "name": "com.amazonaws.ecs.capability.logging-driver.json-file"
                },
                {
                    "name": "com.amazonaws.ecs.capability.logging-driver.syslog"
                }
            ],
            "versionInfo": {
                "agentVersion": "1.5.0",
                "agentHash": "b197edd",
                "dockerVersion": "DockerVersion: 1.7.1"
            }
        }
    ]
}
```

您也可以找到 Amazon EC2 執行個體 ID，用來在 Amazon EC2 主控台中監控執行個體，或搭配 **aws ec2 describe-instances --instance-id *instance\$1id*** 命令使用。

## 註冊任務定義
<a name="AWSCLI_EC2_register_task_definition"></a>

您必須先註冊任務定義，才能在 Amazon ECS 叢集中執行任務。任務定義是分在一組的容器清單。以下範例是使用 `nginx` 映像的簡單任務定義。如需可用之任務定義參數的詳細資訊，請參閱「[Amazon ECS 任務定義](task_definitions.md)」。

```
{
    "family": "nginx-task",
    "containerDefinitions": [
        {
            "name": "nginx",
            "image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest",
            "cpu": 256,
            "memory": 512,
            "essential": true,
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp"
                }
            ]
        }
    ],
    "requiresCompatibilities": ["EC2"],
    "networkMode": "bridge"
}
```

上述範例 JSON 可以透過 AWS CLI 兩種方式傳遞至 ：您可以將任務定義 JSON 儲存為 檔案，並使用 `--cli-input-json file://path_to_file.json`選項將其傳遞。或者，您可以逸出 JSON 中的引號，在命令列上傳遞 JSON 容器定義。如果您選擇用命令列傳送容器定義，您的命令需要使用額外的 `--family` 參數，以保留多個彼此相關聯的任務定義版本。

將 JSON 檔案用於容器定義中：

```
aws ecs register-task-definition --cli-input-json file://$HOME/tasks/nginx.json
```

**register-task-definition** 會在完成註冊後，傳回任務定義的描述。

```
{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:us-east-1:123456789012:task-definition/nginx-task:1",
        "family": "nginx-task",
        "revision": 1,
        "status": "ACTIVE",
        "containerDefinitions": [
            {
                "name": "nginx",
                "image": "public.ecr.aws/docker/library/nginx:latest",
                "cpu": 256,
                "memory": 512,
                "essential": true,
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "environment": [],
                "mountPoints": [],
                "volumesFrom": []
            }
        ],
        "volumes": [],
        "networkMode": "bridge",
        "compatibilities": [
            "EC2"
        ],
        "requiresCompatibilities": [
            "EC2"
        ]
    }
}
```

## 列出任務定義
<a name="AWSCLI_EC2_list_task_definitions"></a>

您可以使用 **list-task-definitions** 命令隨時列出您帳戶的任務定義。這個命令的輸出會顯示 `family` 與 `revision` 值，可在呼叫 **create-service** 時一起使用。

```
aws ecs list-task-definitions
```

輸出：

```
{
    "taskDefinitionArns": [
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/sleep360:1",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/sleep360:2",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/nginx-task:1",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/wordpress:3",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/wordpress:4",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/wordpress:5",
        "arn:aws:ec2:us-east-1:aws_account_id:task-definition/wordpress:6"
    ]
}
```

## 建立服務
<a name="AWSCLI_EC2_run_task"></a>

在為帳戶註冊任務並啟動已註冊至叢集的容器執行個體後，即可建立 Amazon ECS 服務。該服務會使用您註冊的任務定義，同時執行並維持所需數量的任務。在此範例中，您會在 MyCluster 叢集中置放 `nginx:1` 任務定義的單一執行個體。

```
aws ecs create-service --cluster MyCluster --service-name nginx-service --task-definition nginx-task:1 --desired-count 1
```

輸出：

```
{
    "service": {
        "serviceArn": "arn:aws:ecs:us-east-1:aws_account_id:service/MyCluster/nginx-service",
        "serviceName": "nginx-service",
        "clusterArn": "arn:aws:ecs:us-east-1:aws_account_id:cluster/MyCluster",
        "taskDefinition": "arn:aws:ecs:us-east-1:aws_account_id:task-definition/nginx-task:1",
        "desiredCount": 1,
        "runningCount": 0,
        "pendingCount": 0,
        "launchType": "EC2",
        "status": "ACTIVE",
        "createdAt": "2025-01-13T10:45:00.000Z"
    }
}
```

## 列出服務
<a name="AWSCLI_EC2_list_tasks"></a>

列出您叢集的服務。您應該會看到您在先前一節所建立的服務。您可以記下這個命令傳回的服務 ID 或完整的 ARN，稍後將用以描述服務。

```
aws ecs list-services --cluster MyCluster
```

輸出：

```
{
    "taskArns": [
        "arn:aws:ecs:us-east-1:aws_account_id:task/task_ID"
    ]
}
```

## 描述服務
<a name="AWSCLI_EC2_describe_service"></a>

使用下列命令描述服務，取得有關服務的詳細資訊。

```
aws ecs describe-services --cluster MyCluster --services nginx-service
```

輸出：

```
{
    "services": [
        {
            "serviceArn": "arn:aws:ecs:us-east-1:aws_account_id:service/MyCluster/nginx-service",
            "serviceName": "nginx-service",
            "clusterArn": "arn:aws:ecs:us-east-1:aws_account_id:cluster/MyCluster",
            "taskDefinition": "arn:aws:ecs:us-east-1:aws_account_id:task-definition/nginx-task:1",
            "desiredCount": 1,
            "runningCount": 1,
            "pendingCount": 0,
            "launchType": "EC2",
            "status": "ACTIVE",
            "createdAt": "2025-01-13T10:45:00.000Z",
            "events": [
                {
                    "id": "abcd1234-5678-90ab-cdef-1234567890ab",
                    "createdAt": "2025-01-13T10:45:30.000Z",
                    "message": "(service nginx-service) has started 1 tasks: (task abcd1234-5678-90ab-cdef-1234567890ab)."
                }
            ]
        }
    ]
}
```

## 描述執行中的任務
<a name="AWSCLI_EC2_describe_task"></a>

描述服務之後，請執行下列命令，取得作為服務一部分的執行中任務的詳細資訊。

```
aws ecs list-tasks --cluster MyCluster --service-name nginx-service
```

 輸出：

```
{
    "tasks": [
        {
            "taskArn": "arn:aws:ecs:us-east-1:aws_account_id:task/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
            "clusterArn": "arn:aws:ecs:us-east-1:aws_account_id:cluster/MyCluster",
            "taskDefinitionArn": "arn:aws:ecs:us-east-1:aws_account_id:task-definition/nginx-task:1",
            "containerInstanceArn": "arn:aws:ecs:us-east-1:aws_account_id:container-instance/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
            "lastStatus": "RUNNING",
            "desiredStatus": "RUNNING",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:us-east-1:aws_account_id:container/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab/abcd1234-5678-90ab-cdef-1234567890ab",
                    "taskArn": "arn:aws:ecs:us-east-1:aws_account_id:task/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
                    "name": "nginx",
                    "lastStatus": "RUNNING",
                    "networkBindings": [
                        {
                            "bindIP": "0.0.0.0",
                            "containerPort": 80,
                            "hostPort": 80,
                            "protocol": "tcp"
                        }
                    ]
                }
            ],
            "createdAt": "2025-01-13T10:45:00.000Z",
            "startedAt": "2025-01-13T10:45:30.000Z"
        }
    ]
}
```

## 測試 Web 伺服器
<a name="AWSCLI_EC2_test_web_server"></a>

**測試 Web 伺服器**

1. 透過執行下列命令，擷取容器執行個體的公有 IP 位址。

   ```
   aws ec2 describe-instances --instance-ids i-abcd1234 --query 'Reservations[0].Instances[0].PublicIpAddress' --output text
   ```

   輸出：

   ```
   203.0.113.25
   ```

1. 擷取 IP 位址之後，請使用 IP 位址執行下列 `curl` 命令。

   ```
   curl http://203.0.113.25
   ```

   輸出：

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   ...
   </head>
   <body>
   <h1>Welcome to nginx!</h1>
   <p>If you can see this page, the nginx web server is successfully installed and working.</p>
   ...
   </body>
   </html>
   ```

   出現的 nginx 歡迎頁面即確認服務已成功執行，可從網際網路存取。

## 清除資源
<a name="AWSCLI_EC2_clean_up_resources"></a>

若要避免產生費用，需清理在此教學課程中建立的資源。

**清理資源**

1. 將服務的所需任務數量更新為零，然後刪除服務。

   ```
   aws ecs update-service --cluster MyCluster --service nginx-service --desired-count 0
   {
       "service": {
           "serviceArn": "arn:aws:ecs:us-east-1:123456789012:service/MyCluster/nginx-service",
           "serviceName": "nginx-service",
           "desiredCount": 0,
           "runningCount": 1,
           "pendingCount": 0,
           "status": "ACTIVE"
       }
   }
   ```

1. 等待執行中任務停止，然後刪除服務。

   ```
   aws ecs delete-service --cluster MyCluster --service nginx-service
   {
       "service": {
           "serviceArn": "arn:aws:ecs:us-east-1:123456789012:service/MyCluster/nginx-service",
           "serviceName": "nginx-service",
           "status": "DRAINING"
       }
   }
   ```

1. 終止已建立的容器執行個體。

   ```
   aws ec2 terminate-instances --instance-ids i-abcd1234
   {
       "TerminatingInstances": [
           {
               "InstanceId": "i-abcd1234",
               "CurrentState": {
                   "Code": 32,
                   "Name": "shutting-down"
               },
               "PreviousState": {
                   "Code": 16,
                   "Name": "running"
               }
           }
       ]
   }
   ```

1. 清理已建立的安全群組與金鑰對。

   ```
   aws ec2 delete-security-group --group-id sg-abcd1234
   aws ec2 delete-key-pair --key-name ecs-tutorial-key
   rm ecs-tutorial-key.pem
   ```

1. 刪除 Amazon ECS 叢集。

   ```
   aws ecs delete-cluster --cluster MyCluster
   {
       "cluster": {
           "clusterArn": "arn:aws:ecs:us-east-1:123456789012:cluster/MyCluster",
           "clusterName": "MyCluster",
           "status": "INACTIVE"
       }
   }
   ```

# 設定 Amazon ECS 監聽 CloudWatch Events 事件
<a name="ecs_cwet"></a>

了解如何設定一個簡單的 Lambda 函式，用於監聽 Amazon ECS 任務事件並將之寫入 CloudWatch Logs 日誌串流。

## 先決條件：設定測試叢集
<a name="cwet_step_1"></a>

如果您沒有可供擷取事件的執行中叢集，請遵循「[為 Fargate 工作負載建立 Amazon ECS 叢集](create-cluster-console-v2.md)」中的步驟建立叢集。在此教學課程的最後，您在此叢集上執行任務，以測試您的 Lambda 函數設定是否正確。

## 步驟 1：建立 Lambda 函數
<a name="cwet_step_2"></a>

在此程序中，您要建立一個簡單的 Lambda 函數，做為 Amazon ECS 事件資料流訊息的目標。

1. 在 https：//[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 開啟 AWS Lambda 主控台。

1. 選擇 **Create function** (建立函數)。

1. 在 **Author from scratch** (從頭開始撰寫) 畫面上，執行下列操作：

   1. 對於 **Name (名稱)**，輸入值。

   1. 針對 **Runtime** (執行時間)，選擇您的 Python 版本，例如：**Python 3.9**。

   1. 針對 **Role (角色)**，選擇 **Create a new role with basic Lambda permissions (建立具備基本 Lambda 許可的新角色)**。

1. 選擇**建立函數**。

1. 在 **Function code** (函數程式碼) 區段中，編輯範本程式碼以符合下列範例：

   ```
   import json
   
   def lambda_handler(event, context):
       if event["source"] != "aws.ecs":
          raise ValueError("Function only supports input from events with a source type of: aws.ecs")
          
       print('Here is the event:')
       print(json.dumps(event))
   ```

   這是一個簡單的 Python 3.9 函數，此函數列印 Amazon ECS 所傳送的事件。如果一切設定正確，則在此教學課程的最後，您會看到事件詳細資訊出現在與此 Lambda 函數建立關聯的 CloudWatch Logs 日誌串流中。

1. 選擇**儲存**。

## 步驟 2：註冊事件規則
<a name="cwet_step_3"></a>

 接著，您會建立一個 CloudWatch Events 事件規則，擷取來自 Amazon ECS 叢集的任務事件。此規則會擷取來自所定義的帳戶內所有叢集的所有事件。任務訊息本身包含事件來源的資訊 (包含其所在的叢集)，從而能以程式設計方式篩選和排序事件。

**注意**  
當您使用 AWS 管理主控台 建立事件規則時，主控台會自動新增必要的 IAM 許可，以授予 CloudWatch Events 呼叫 Lambda 函數的許可。如果您使用 建立事件規則 AWS CLI，則需要明確授予此許可。如需詳細資訊，請參閱 *Amazon EventBridge User Guide* 中的 [Events in Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html) 與 [Amazon EventBridge event patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html)。

**將事件路由至 Lambda 函數**

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

1. 在導覽窗格上，選擇 **Events (事件)**、**Rules (規則)**、**Create rule (建立規則)**。

1. 針對 **Event Source** (事件來源)，選擇 **ECS** 做為事件來源。根據預設，此規則套用至所有 Amazon ECS 群組的 Amazon ECS 事件。或者，您可以選取特定事件或特定 Amazon ECS 群組。

1. 對於 **Targets** (目標)，選擇 **Add target** (新增目標)，並對於 **Target type** (目標類型)，選擇 **Lambda function** (Lambda 函數)，然後選取您的 Lambda 函數。

1. 選擇**設定詳細資訊**。

1. 針對 **Rule definition (規則定義)**，輸入您規則的名稱和描述，然後選擇 **Create rule (建立規則)**。

## 步驟 3：建立任務定義
<a name="cwet_step_task-def"></a>

建立任務定義。

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

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

1. 選擇 **Create new Task Definition** (建立新任務定義)，以及 **Create new revision with JSON** (使用 JSON 建立新修訂版)。

1. 複製下列任務定義範例並貼到方塊中，然後選擇 **Save (儲存)**。

   ```
   {
      "containerDefinitions": [ 
         { 
            "command": [
               "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
            ],
            "entryPoint": [
               "sh",
               "-c"
            ],
            "essential": true,
            "image": "public.ecr.aws/docker/library/httpd:2.4",
            "logConfiguration": { 
               "logDriver": "awslogs",
               "options": { 
                  "awslogs-group" : "/ecs/fargate-task-definition",
                  "awslogs-region": "us-east-1",
                  "awslogs-stream-prefix": "ecs"
               }
            },
            "name": "sample-fargate-app",
            "portMappings": [ 
               { 
                  "containerPort": 80,
                  "hostPort": 80,
                  "protocol": "tcp"
               }
            ]
         }
      ],
      "cpu": "256",
      "executionRoleArn": "arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
      "family": "fargate-task-definition",
      "memory": "512",
      "networkMode": "awsvpc",
      "runtimePlatform": {
           "operatingSystemFamily": "LINUX"
       },
      "requiresCompatibilities": [ 
          "FARGATE" 
       ]
   }
   ```

1. 選擇**建立**。

## 步驟 4：測試您的規則
<a name="cwet_step_4"></a>

 最後，您會建立一個 CloudWatch Events 事件規則，擷取來自 Amazon ECS 叢集的任務事件。此規則會擷取來自所定義的帳戶內所有叢集的所有事件。任務訊息本身包含事件來源的資訊 (包含其所在的叢集)，從而能以程式設計方式篩選和排序事件。

**測試規則**

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

1. 選擇 **Task definitions** (任務定義)。

1. 選擇 **console-sample-app-static**，然後選擇 **Deploy** (部署)、**Run new task** (執行新任務)。

1. 在 **Cluster** (叢集) 欄位中選擇預設，然後選擇 **Deploy** (部署)。

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

1. 在導覽窗格上，選擇 **Logs** (日誌)，然後選取 Lambda 函數的日誌群組 (例如，**/aws/lambda/***my-function*)。

1. 選取日誌串流，以檢視事件資料。

# 針對 Amazon ECS 任務停止事件傳送 Amazon Simple Notification Service 提醒
<a name="ecs_cwet2"></a>

設定一項 Amazon EventBridge 事件規則，使其僅擷取因其中一個必要容器終止而導致任務停止執行的任務事件。事件只會將具有特定 `stoppedReason` 屬性的任務事件傳送至指定的 Amazon SNS 主題。

## 先決條件：設定測試叢集
<a name="cwet2_step_1"></a>

 如果您沒有可供擷取事件的執行中叢集，請遵循[使用 AWS Fargate上的 Linux 容器來開始使用主控台](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/getting-started-fargate.html#get-started-fargate-cluster)中的步驟建立叢集。在此教學課程的最後，您會在此叢集上執行任務，以測試您的 Amazon SNS 主題和 EventBridge 規則設定是否正確。

## 先決條件：設定 Amazon SNS 的許可
<a name="cwet2_step_1a"></a>

若要允許 EventBridge 發佈到 Amazon SNS 主題，請使用 aws sns get-topic-attributes 和 aws sns set-topic-attributes 命令。

如需有關如何建立許可的詳細資訊，請參閱《Amazon Simple Notification Service 開發人員指南》**中的 [Amazon SNS 許可](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-use-resource-based.html#eb-sns-permissions)。

新增下列許可：

```
{
  "Sid": "PublishEventsToMyTopic",
  "Effect": "Allow",
  "Principal": {
     "Service": "events.amazonaws.com"
  },
  "Action": "sns: Publish",
  "Resource": "arn:aws:sns:region:account-id:TaskStoppedAlert",
}
```

## 步驟 1：建立並訂閱 Amazon SNS 主題
<a name="cwet2_step_2"></a>

 在此教學課程中，您會設定 Amazon SNS 主題，做為新事件規則的事件目標。

如需有關如何建立和訂閱 Amazon SNS 主題的資訊，請參閱《Amazon Simple Notification Service 開發人員指南》**中的 [Amazon SNS 入門](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html#step-create-queue)，並使用下表來決定要選取的選項。


| 選項 | Value | 
| --- | --- | 
|  Type  | 標準 | 
| 名稱 |  TaskStoppedAlert  | 
| 通訊協定 | Email | 
| Endpoint |  您目前能存取的電子郵件地址  | 

## 步驟 2：註冊事件規則
<a name="cwet2_step_3"></a>

 接下來，您會登錄事件規則，只擷取具有停止容器之任務的任務停止事件。

如需有關如何建立和訂閱 Amazon SNS 主題的資訊，請參閱《Amazon EventBridge 使用者指南》**中的[在 Amazon EventBridge 中建立規則](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)，並使用下表來決定要選取的選項。


| 選項 | Value | 
| --- | --- | 
|  規則類型  |  具有事件模式的規則  | 
| 事件來源 | AWS 事件或 EventBridge 合作夥伴事件 | 
| 事件模式 |  自訂模式 (JSON 編輯器)  | 
| 事件模式 |  <pre>{<br />   "source":[<br />      "aws.ecs"<br />   ],<br />   "detail-type":[<br />      "ECS Task State Change"<br />   ],<br />   "detail":{<br />      "lastStatus":[<br />         "STOPPED"<br />      ],<br />      "stoppedReason":[<br />         "Essential container in task exited"<br />      ]<br />   }<br />}</pre> | 
| Target type (目標類型) |  AWS 服務  | 
| Target | SNS 主題 | 
| 主題 |  TaskStoppedAlert (您在步驟 1 中建立的主題)  | 

## 步驟 3：測試您的規則
<a name="cwet2_step_4"></a>

藉由執行在啟動後立即結束的任務，確認規則是否正常運作。如果您的事件規則設定正確，您應該會在幾分鐘內收到一封包含事件文字的電子郵件訊息。如果您有可以滿足規則需求的現有任務定義，請使用它來執行任務。如果沒有，以下步驟將引導您註冊 Fargate 任務定義並執行它。

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

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

1. 選擇 **Create new task definitio** (建立新任務定義)、**Create new task definition with JSON** (使用 JSON 建立新的任務定義)。

1. 在 JSON 編輯工具方塊中，編輯您的 JSON 檔案，將下列內容複製至編輯器。

   ```
   {
      "containerDefinitions":[
         {
            "command":[
               "sh",
               "-c",
               "sleep 5"
            ],
            "essential":true,
            "image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
            "name":"test-sleep"
         }
      ],
      "cpu":"256",
      "executionRoleArn":"arn:aws:iam::012345678910:role/ecsTaskExecutionRole",
      "family":"fargate-task-definition",
      "memory":"512",
      "networkMode":"awsvpc",
      "requiresCompatibilities":[
         "FARGATE"
      ]
   }
   ```

1. 選擇**建立**。

**從主控台執行任務**

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

1. 在**叢集**頁面，選擇您要在先決條件中建立的叢集。

1. 在 **Tasks** (任務) 標籤中，選擇 **Run new task** (執行新任務)。

1. 針對 **Application type** (應用程式類型)，選擇 **Task** (任務)。

1. 在**任務定義**中，選擇 **fargate-task-definition**。

1. 針對 **Desired tasks** (所需任務)，輸入要啟動的任務數目。

1. 選擇**建立**。

# 串連多行或堆疊追蹤的 Amazon ECS 日誌訊息
<a name="firelens-concatanate-multiline"></a>

從 AWS for Fluent Bit 2.22.0 版開始，包含多行篩選條件。多行篩選條件有助於串連最初屬於一筆內容但分割到多筆記錄或日誌明細行的日誌訊息。如需有關多行篩選條件的詳細資訊，請參閱《[Fluent Bit 說明文件](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)》。

分割日誌訊息的常見範例有：
+ 堆疊追蹤。
+ 在多行上列印日誌的應用程式。
+ 因為日誌訊息長於指定的執行時間緩衝大小上限而分割的日誌訊息。您可以按照 GitHub 上的範例來串連由容器執行時間分割的日誌訊息：[FireLens 範例：串聯部分/分割容器日誌](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/filter-multiline-partial-message-mode)。

## 所需的 IAM 許可
<a name="iam-permissions"></a>

請務必先確定您擁有必要的 IAM 許可，讓容器代理程式可從 Amazon ECR 中提取容器映像，也讓容器可將日誌路由到 CloudWatch Logs。

對於這些許可，您必須具有下列角色：
+ 任務 IAM 角色。
+ 任務執行 IAM 角色。

您需要具備下列許可：
+ `logs:CreateLogStream`
+ `logs:CreateLogGroup`
+ `logs:PutLogEvents`

## 確定何時使用多行日誌設定
<a name="determine-filter"></a>

以下是您在 CloudWatch Logs 主控台中看到的範例日誌片段，其中包含預設日誌設定。您可以查看以 `log` 開頭的行，以確定是否需要多行篩選條件。當內容相同時，您可以使用多行日誌設定。在此範例中，內容為 "com.myproject.model.MyProject"。

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "source=": "stdout", "log": ": "     at com.myproject.modele.(MyProject.badMethod.java:22)",
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log": ": "     at com.myproject.model.MyProject.badMethod(MyProject.java:22)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE",
      "ecs_task_definition": "firelense-example-multiline:3"
     }
```

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "stdout", "log": ": "     at com.myproject.modele.(MyProject.oneMoreMethod.java:18)",
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log": ": "     at com.myproject.model.MyProject.oneMoreMethod(MyProject.java:18)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE,
      "ecs_task_definition": "firelense-example-multiline:3"
     }
```

使用多行日誌設定後，輸出看起來類似下列範例。

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "stdout",...
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log:    "September 20, 2022 06:41:48 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!\n    
    at com.myproject.module.MyProject.badMethod(MyProject.java:22)\n    at   
    at com.myproject.model.MyProject.oneMoreMethod(MyProject.java:18) com.myproject.module.MyProject.main(MyProject.java:6)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE",
      "ecs_task_definition": "firelense-example-multiline:2"
     }
```

## 剖析並串連選項
<a name="parse-multiline-log"></a>

若要剖析日誌並串連因新行而分割的行數，您可以使用這兩個選項中的任一選項。
+ 使用您自己的剖析器檔案 (包含要剖析的規則) 並串連屬於相同訊息的明細行。
+ 使用 Fluent Bit 內建剖析器。如需 Fluent Bit 內建剖析器所支援的語言清單，請參閱 [Fluent Bit 說明文件](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)。

下列教學會引導您逐步演練每個使用案例的步驟。這些步驟向您展示如何串聯多行並將日誌傳送到 Amazon CloudWatch。您可以為您的日誌指定其他目的地。

### 範例：使用您建立的剖析器
<a name="customer-parser"></a>

在本範例中，您會完成下列步驟：

1. 建置並上傳 Fluent Bit 容器的映像。

1. 建置並上傳可執行、失敗並產生多行堆疊追蹤之試用版多行應用程式的映像。

1. 建立任務定義並執行任務。

1. 檢視日誌以確認跨多行的訊息是否顯示為串連。

**建置並上傳 Fluent Bit 容器的映像**

此映像將包含您指定常規運算式的剖析器檔案和參照剖析器檔案的組態文件。

1. 建立名稱為 `FluentBitDockerImage` 的資料夾。

1. 在資料夾內，建立剖析器檔案 (包含要剖析日誌的規則) 並串連屬於相同訊息的明細行。

   1. 將以下內容貼到該剖析器檔案：

      ```
      [MULTILINE_PARSER]
          name          multiline-regex-test
          type          regex
          flush_timeout 1000
          #
          # Regex rules for multiline parsing
          # ---------------------------------
          #
          # configuration hints:
          #
          #  - first state always has the name: start_state
          #  - every field in the rule must be inside double quotes
          #
          # rules |   state name  | regex pattern                  | next state
          # ------|---------------|--------------------------------------------
          rule      "start_state"   "/(Dec \d+ \d+\:\d+\:\d+)(.*)/"  "cont"
          rule      "cont"          "/^\s+at.*/"                     "cont"
      ```

      當您自訂 Regex 運算式模式時，我們建議您使用常規運算式編輯器來測試運算式。

   1. 儲存檔案為 `parsers_multiline.conf`。

1. 在 `FluentBitDockerImage` 資料夾內，建立參照了您在前一個步驟中建立的剖析器檔案之自訂組態檔案。

   如需有關自訂組態檔案的詳細資訊，請參閱《[Amazon Elastic Container Service 開發人員指南](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig)》中的*指定自訂組態檔案* 

   1. 將以下內容貼到該檔案：

      ```
      [SERVICE]
          flush                 1
          log_level             info
          parsers_file          /parsers_multiline.conf
          
      [FILTER]
          name                  multiline
          match                 *
          multiline.key_content log
          multiline.parser      multiline-regex-test
      ```
**注意**  
您必須使用剖析器的絕對路徑。

   1. 儲存檔案為 `extra.conf`。

1. 在 `FluentBitDockerImage` 資料夾內，建立具有 Fluent Bit 映像與剖析器和您建立的組態檔案之 Dockerfile。

   1. 將以下內容貼到該檔案：

      ```
      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest
      
      ADD parsers_multiline.conf /parsers_multiline.conf
      ADD extra.conf /extra.conf
      ```

   1. 儲存檔案為 `Dockerfile`。

1. 使用 Dockerfile，建置內含剖析器與自訂組態檔案的自訂 Fluent Bit 映像。
**注意**  
您可以將剖析器檔案和組態檔案放置在 Docker 影像中除了 `/fluent-bit/etc/fluent-bit.conf` 以外的任何位置，因為該檔案路徑會由 FireLens 使用。

   1. 建置映像：`docker build -t fluent-bit-multiline-image.`

      其中：`fluent-bit-multiline-image` 是此範例中映像的名稱。

   1. 驗證映像已正確建立：`docker images —filter reference=fluent-bit-multiline-image`

      如果成功，輸出會顯示映像和 `latest` 標籤。

1. 將自訂 Fluent Bit 映像上傳至 Amazon Elastic 容器登錄檔。

   1. 建立 Amazon ECR 儲存庫，以便存放映像：`aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      其中：`fluent-bit-multiline-repo` 是此範例中儲存庫的名稱，`us-east-1` 是此範例中的區域。

      輸出為您提供了新儲存庫的詳細資訊。

   1. 使用來自先前輸出的 `repositoryUri` 值，標記您的映像：`docker tag fluent-bit-multiline-image repositoryUri`

      範例：`docker tag fluent-bit-multiline-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

   1. 執行 Docker 影像以確認是否能正確執行：`docker images —filter reference=repositoryUri`

      在輸出中，儲存庫名稱從 fluent-bit-multiline-repo 變更為 `repositoryUri`。

   1. 透過執行 `aws ecr get-login-password` 命令並指定您要驗證的登錄 ID 來驗證 Amazon ECR：`aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com`

      範例：`ecr get-login-password | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com`

      畫面上會顯示成功登入訊息。

   1. 將映像推送至 Amazon ECR：`docker push registry ID.dkr.ecr.region.amazonaws.com/repository name`

      範例：`docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

**建置並上傳試用版多行應用程式的映像**

此映像將包含執行應用程式的 Python 指令碼檔案和樣本日誌檔案。

當您執行任務時，應用程式會模擬執行，然後失敗並建立堆疊追蹤。

1. 建立名為 `multiline-app` 的資料夾：`mkdir multiline-app`

1. 建立 Python 指令碼檔案。

   1. 在 `multiline-app` 資料夾中，建立檔案，並將它命名為 `main.py`。

   1. 將以下內容貼到該檔案：

      ```
      import os
      import time
      file1 = open('/test.log', 'r')
      Lines = file1.readlines()
       
      count = 0
      
      for i in range(10):
          print("app running normally...")
          time.sleep(1)
      
      # Strips the newline character
      for line in Lines:
          count += 1
          print(line.rstrip())
      print(count)
      print("app terminated.")
      ```

   1. 儲存 `main.py` 檔案。

1. 建立範例日誌檔案。

   1. 在 `multiline-app` 資料夾中，建立檔案，並將它命名為 `test.log`。

   1. 將以下內容貼到該檔案：

      ```
      single line...
      Dec 14 06:41:08 Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
          at com.myproject.module.MyProject.badMethod(MyProject.java:22)
          at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
          at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
          at com.myproject.module.MyProject.someMethod(MyProject.java:10)
          at com.myproject.module.MyProject.main(MyProject.java:6)
      another line...
      ```

   1. 儲存 `test.log` 檔案。

1. 在 `multiline-app` 資料夾內，建立 Dockerfile。

   1. 將以下內容貼到該檔案：

      ```
      FROM public.ecr.aws/amazonlinux/amazonlinux:latest
      ADD test.log /test.log
      
      RUN yum upgrade -y && yum install -y python3
      
      WORKDIR /usr/local/bin
      
      COPY main.py .
      
      CMD ["python3", "main.py"]
      ```

   1. 儲存 `Dockerfile` 檔案。

1. 使用 Dockerfile，建置映像。

   1. 建置映像：`docker build -t multiline-app-image `

      其中：`multiline-app-image` 是此範例中映像的名稱。

   1. 驗證映像已正確建立：`docker images —filter reference=multiline-app-image`

      如果成功，輸出會顯示映像和 `latest` 標籤。

1. 將映像上傳至 Amazon Elastic 容器登錄檔。

   1. 建立 Amazon ECR 儲存庫，以便存放映像：`aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      其中：`multiline-app-repo` 是此範例中儲存庫的名稱，`us-east-1` 是此範例中的區域。

      輸出為您提供了新儲存庫的詳細資訊。請記下 `repositoryUri` 值，因為您將在後續步驟用到它。

   1. 使用來自先前輸出的 `repositoryUri` 值，標記您的映像：`docker tag multiline-app-image repositoryUri`

      範例：`docker tag multiline-app-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

   1. 執行 Docker 影像以確認是否能正確執行：`docker images —filter reference=repositoryUri`

      在輸出中，儲存庫名稱會從 `multiline-app-repo` 變更為 `repositoryUri` 值。

   1. 將映像推送至 Amazon ECR：`docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name`

      範例：`docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

**建立任務定義並執行任務**

1. 建立檔案名稱為 `multiline-task-definition.json` 的任務定義檔案。

1. 將以下內容貼到該 `multiline-task-definition.json` 檔案：

   ```
   {
       "family": "firelens-example-multiline",
       "taskRoleArn": "task role ARN,
       "executionRoleArn": "execution role ARN",
       "containerDefinitions": [
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-image:latest",
               "name": "log_router",
               "firelensConfiguration": {
                   "type": "fluentbit",
                   "options": {
                       "config-file-type": "file",
                       "config-file-value": "/extra.conf"
                   }
               },
               "memoryReservation": 50
           },
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/multiline-app-image:latest",
               "name": "app",
               "logConfiguration": {
                   "logDriver": "awsfirelens",
                   "options": {
                       "Name": "cloudwatch_logs",
                       "region": "us-east-1",
                       "log_group_name": "multiline-test/application",
                       "auto_create_group": "true",
                       "log_stream_prefix": "multiline-"
                   }
               },
               "memoryReservation": 100
           }
       ],
       "requiresCompatibilities": ["FARGATE"],
       "networkMode": "awsvpc",
       "cpu": "256",
       "memory": "512"
   }
   ```

   取代下列在 `multiline-task-definition.json` 任務定義中的項目：

   1. `task role ARN`

      若要尋找任務角色 ARN，請前往 IAM 主控台。選擇 **Roles** (角色) 並尋找您建立的 `ecs-task-role-for-firelens` 任務角色。選擇角色並複製顯示於 **Summary** (摘要) 區段的 **ARN**。

   1. `execution role ARN`

      若要尋找執行角色 ARN，請前往 IAM 主控台。選擇 **Roles** (角色) 並尋找 `ecsTaskExecutionRole` 角色。選擇角色並複製顯示於 **Summary** (摘要) 區段的 **ARN**。

   1. `aws_account_id`

      若要尋找您的 `aws_account_id`，請登入 AWS 管理主控台。選擇右上角的使用者名稱並複製您的帳戶 ID。

   1. `us-east-1`

      如有必要，請取代該區域。

1. 註冊任務定義檔案：`aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region region`

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

1. 在導覽窗格中，選擇 **Task Definitions** (任務定義)，然後選擇 `firelens-example-multiline` 系列，因為我們已在上述任務定義的第一行中將任務定義註冊到此系列。

1. 選擇最新版本。

1. 選擇**部署**、**執行任務**。

1. 在**執行任務**頁面上，針對**叢集**選擇叢集，然後在**聯網**下，針對**子網路**選擇任務的可用子網路。

1. 選擇**建立**。

**確認 Amazon CloudWatch 中的多行日誌訊息是否顯示為串連**

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

1. 在導覽窗格中，展開 **Logs** (日誌) 並選擇 **Log groups** (日誌群組)。

1. 選擇 `multiline-test/applicatio` 日誌群組。

1. 選擇日誌。檢視訊息。系統會串連與剖析器檔案中的規則相符之明細行，並顯示為單則訊息。

   下列日誌程式碼片段顯示了串連到單一 Java 堆疊追蹤事件的明細行：

   ```
   {
       "container_id": "xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "log": "Dec 14 06:41:08 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!\n    at com.myproject.module.MyProject.badMethod(MyProject.java:22)\n    at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)\n    at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)\n    at com.myproject.module.MyProject.someMethod(MyProject.java:10)\n    at com.myproject.module.MyProject.main(MyProject.java:6)",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:2"
   }
   ```

   下列日誌程式碼片段顯示了相同訊息僅以單筆明細行顯示的方式 (如果您執行了未串連多行日誌訊息的 Amazon ECS 容器)。

   ```
   {
       "log": "Dec 14 06:41:08 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:3"
   }
   ```

### 範例：使用 Fluent Bit 內建剖析器
<a name="fluent-bit-parser"></a>

在本範例中，您會完成下列步驟：

1. 建置並上傳 Fluent Bit 容器的映像。

1. 建置並上傳可執行、失敗並產生多行堆疊追蹤之試用版多行應用程式的映像。

1. 建立任務定義並執行任務。

1. 檢視日誌以確認跨多行的訊息是否顯示為串連。

**建置並上傳 Fluent Bit 容器的映像**

此映像將包含參照了 Fluent Bit 剖析器的組態檔案。

1. 建立名稱為 `FluentBitDockerImage` 的資料夾。

1. 在 `FluentBitDockerImage` 資料夾內，建立參照了 Fluent Bit 內建剖析器檔案的自訂組態檔案。

   如需有關自訂組態檔案的詳細資訊，請參閱《[Amazon Elastic Container Service 開發人員指南](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig)》中的*指定自訂組態檔案* 

   1. 將以下內容貼到該檔案：

      ```
      [FILTER]
          name                  multiline
          match                 *
          multiline.key_content log
          multiline.parser      go
      ```

   1. 儲存檔案為 `extra.conf`。

1. 在 `FluentBitDockerImage` 資料夾內，建立具有 Fluent Bit 映像與剖析器和您建立的組態檔案之 Dockerfile。

   1. 將以下內容貼到該檔案：

      ```
      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest
      ADD extra.conf /extra.conf
      ```

   1. 儲存檔案為 `Dockerfile`。

1. 使用 Dockerfile，建置內含自訂組態檔案的自訂 Fluent Bit 映像。
**注意**  
您可以將組態檔案放置在 Docker 影像中除了 `/fluent-bit/etc/fluent-bit.conf` 以外的任何位置，因為該檔案路徑會由 FireLens 使用。

   1. 建置映像：`docker build -t fluent-bit-multiline-image.`

      其中：`fluent-bit-multiline-image` 是此範例中映像的名稱。

   1. 驗證映像已正確建立：`docker images —filter reference=fluent-bit-multiline-image`

      如果成功，輸出會顯示映像和 `latest` 標籤。

1. 將自訂 Fluent Bit 映像上傳至 Amazon Elastic 容器登錄檔。

   1. 建立 Amazon ECR 儲存庫，以便存放映像：`aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      其中：`fluent-bit-multiline-repo` 是此範例中儲存庫的名稱，`us-east-1` 是此範例中的區域。

      輸出為您提供了新儲存庫的詳細資訊。

   1. 使用來自先前輸出的 `repositoryUri` 值，標記您的映像：`docker tag fluent-bit-multiline-image repositoryUri`

      範例：`docker tag fluent-bit-multiline-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

   1. 執行 Docker 影像以確認是否能正確執行：`docker images —filter reference=repositoryUri`

      在輸出中，儲存庫名稱從 fluent-bit-multiline-repo 變更為 `repositoryUri`。

   1. 透過執行 `aws ecr get-login-password` 命令並指定您要驗證的登錄 ID 來驗證 Amazon ECR：`aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com`

      範例：`ecr get-login-password | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com`

      畫面上會顯示成功登入訊息。

   1. 將映像推送至 Amazon ECR：`docker push registry ID.dkr.ecr.region.amazonaws.com/repository name`

      範例：`docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

**建置並上傳試用版多行應用程式的映像**

此映像將包含執行應用程式的 Python 指令碼檔案和樣本日誌檔案。

1. 建立名為 `multiline-app` 的資料夾：`mkdir multiline-app`

1. 建立 Python 指令碼檔案。

   1. 在 `multiline-app` 資料夾中，建立檔案，並將它命名為 `main.py`。

   1. 將以下內容貼到該檔案：

      ```
      import os
      import time
      file1 = open('/test.log', 'r')
      Lines = file1.readlines()
       
      count = 0
      
      for i in range(10):
          print("app running normally...")
          time.sleep(1)
      
      # Strips the newline character
      for line in Lines:
          count += 1
          print(line.rstrip())
      print(count)
      print("app terminated.")
      ```

   1. 儲存 `main.py` 檔案。

1. 建立範例日誌檔案。

   1. 在 `multiline-app` 資料夾中，建立檔案，並將它命名為 `test.log`。

   1. 將以下內容貼到該檔案：

      ```
      panic: my panic
      
      goroutine 4 [running]:
      panic(0x45cb40, 0x47ad70)
        /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c
      main.main.func1(0xc420024120)
        foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1
      created by main.main
        foo.go:5 +0x58
      
      goroutine 1 [chan receive]:
      runtime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c
      runtime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e
      runtime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8)
        /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4
      runtime.chanrecv1(0xc420024120, 0x0)
        /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b
      main.main()
        foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef
      runtime.main()
        /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1
      
      goroutine 2 [force gc (idle)]:
      runtime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c
      runtime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e
      runtime.forcegchelper()
        /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1
      created by runtime.init.4
        /usr/local/go/src/runtime/proc.go:227 +0x35
      
      goroutine 3 [GC sweep wait]:
      runtime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c
      runtime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e
      runtime.bgsweep(0xc42001e150)
        /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1
      created by runtime.gcenable
        /usr/local/go/src/runtime/mgc.go:216 +0x58
      one more line, no multiline
      ```

   1. 儲存 `test.log` 檔案。

1. 在 `multiline-app` 資料夾內，建立 Dockerfile。

   1. 將以下內容貼到該檔案：

      ```
      FROM public.ecr.aws/amazonlinux/amazonlinux:latest
      ADD test.log /test.log
      
      RUN yum upgrade -y && yum install -y python3
      
      WORKDIR /usr/local/bin
      
      COPY main.py .
      
      CMD ["python3", "main.py"]
      ```

   1. 儲存 `Dockerfile` 檔案。

1. 使用 Dockerfile，建置映像。

   1. 建置映像：`docker build -t multiline-app-image `

      其中：`multiline-app-image` 是此範例中映像的名稱。

   1. 驗證映像已正確建立：`docker images —filter reference=multiline-app-image`

      如果成功，輸出會顯示映像和 `latest` 標籤。

1. 將映像上傳至 Amazon Elastic 容器登錄檔。

   1. 建立 Amazon ECR 儲存庫，以便存放映像：`aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      其中：`multiline-app-repo` 是此範例中儲存庫的名稱，`us-east-1` 是此範例中的區域。

      輸出為您提供了新儲存庫的詳細資訊。請記下 `repositoryUri` 值，因為您將在後續步驟用到它。

   1. 使用來自先前輸出的 `repositoryUri` 值，標記您的映像：`docker tag multiline-app-image repositoryUri`

      範例：`docker tag multiline-app-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

   1. 執行 Docker 影像以確認是否能正確執行：`docker images —filter reference=repositoryUri`

      在輸出中，儲存庫名稱會從 `multiline-app-repo` 變更為 `repositoryUri` 值。

   1. 將映像推送至 Amazon ECR：`docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name`

      範例：`docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

**建立任務定義並執行任務**

1. 建立檔案名稱為 `multiline-task-definition.json` 的任務定義檔案。

1. 將以下內容貼到該 `multiline-task-definition.json` 檔案：

   ```
   {
       "family": "firelens-example-multiline",
       "taskRoleArn": "task role ARN,
       "executionRoleArn": "execution role ARN",
       "containerDefinitions": [
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-image:latest",
               "name": "log_router",
               "firelensConfiguration": {
                   "type": "fluentbit",
                   "options": {
                       "config-file-type": "file",
                       "config-file-value": "/extra.conf"
                   }
               },
               "memoryReservation": 50
           },
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/multiline-app-image:latest",
               "name": "app",
               "logConfiguration": {
                   "logDriver": "awsfirelens",
                   "options": {
                       "Name": "cloudwatch_logs",
                       "region": "us-east-1",
                       "log_group_name": "multiline-test/application",
                       "auto_create_group": "true",
                       "log_stream_prefix": "multiline-"
                   }
               },
               "memoryReservation": 100
           }
       ],
       "requiresCompatibilities": ["FARGATE"],
       "networkMode": "awsvpc",
       "cpu": "256",
       "memory": "512"
   }
   ```

   取代下列在 `multiline-task-definition.json` 任務定義中的項目：

   1. `task role ARN`

      若要尋找任務角色 ARN，請前往 IAM 主控台。選擇 **Roles** (角色) 並尋找您建立的 `ecs-task-role-for-firelens` 任務角色。選擇角色並複製顯示於 **Summary** (摘要) 區段的 **ARN**。

   1. `execution role ARN`

      若要尋找執行角色 ARN，請前往 IAM 主控台。選擇 **Roles** (角色) 並尋找 `ecsTaskExecutionRole` 角色。選擇角色並複製顯示於 **Summary** (摘要) 區段的 **ARN**。

   1. `aws_account_id`

      若要尋找您的 `aws_account_id`，請登入 AWS 管理主控台。選擇右上角的使用者名稱並複製您的帳戶 ID。

   1. `us-east-1`

      如有必要，請取代該區域。

1. 註冊任務定義檔案：`aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region us-east-1`

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

1. 在導覽窗格中，選擇 **Task Definitions** (任務定義)，然後選擇 `firelens-example-multiline` 系列，因為我們已在上述任務定義的第一行中將任務定義註冊到此系列。

1. 選擇最新版本。

1. 選擇**部署**、**執行任務**。

1. 在**執行任務**頁面上，針對**叢集**選擇叢集，然後在**聯網**下，針對**子網路**選擇任務的可用子網路。

1. 選擇**建立**。

**確認 Amazon CloudWatch 中的多行日誌訊息是否顯示為串連**

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

1. 在導覽窗格中，展開 **Logs** (日誌) 並選擇 **Log groups** (日誌群組)。

1. 選擇 `multiline-test/applicatio` 日誌群組。

1. 選擇日誌並檢視訊息。系統會串連與剖析器檔案中的規則相符之明細行，並顯示為單則訊息。

   下列日誌程式碼片段顯示了串連到單一事件的 Go 堆疊追蹤：

   ```
   {
       "log": "panic: my panic\n\ngoroutine 4 [running]:\npanic(0x45cb40, 0x47ad70)\n  /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c\nmain.main.func1(0xc420024120)\n  foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1\ncreated by main.main\n  foo.go:5 +0x58\n\ngoroutine 1 [chan receive]:\nruntime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c\nruntime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e\nruntime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8)\n  /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4\nruntime.chanrecv1(0xc420024120, 0x0)\n  /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b\nmain.main()\n  foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef\nruntime.main()\n  /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1\n\ngoroutine 2 [force gc (idle)]:\nruntime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c\nruntime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e\nruntime.forcegchelper()\n  /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1\ncreated by runtime.init.4\n  /usr/local/go/src/runtime/proc.go:227 +0x35\n\ngoroutine 3 [GC sweep wait]:\nruntime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c\nruntime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e\nruntime.bgsweep(0xc42001e150)\n  /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1\ncreated by runtime.gcenable\n  /usr/local/go/src/runtime/mgc.go:216 +0x58",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:2"
   }
   ```

   下列日誌程式碼片段顯示了相同事件顯示的方式 (如果您執行了未串連多行日誌訊息的 ECS 容器)。日誌欄位包含單筆明細行。

   ```
   {
       "log": "panic: my panic",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:3"
   ```

**注意**  
如果您的日誌轉到日誌檔案而不是標準輸出，我們建議您在[結尾輸入外掛程式](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-support) (而非篩選條件) 中指定 `multiline.parser` 和 `multiline.key_content` 組態參數。

# 在 Amazon ECS Windows 容器上部署 Fluent Bit
<a name="tutorial-deploy-fluentbit-on-windows"></a>

Fluent Bit 是一種快速靈活的日誌處理器和路由器，支援各種作業系統。它可用來將日誌路由到各種 AWS 目的地，例如 Amazon CloudWatch Logs、Firehose Amazon S3 和 Amazon OpenSearch Service。Fluent Bit 支援常見的合作夥伴解決方案，例如 [Datadog](https://www.datadoghq.com/)、[Splunk](https://www.splunk.com/) 和自訂 HTTP 伺服器。如需有關 Fluent Bit 的詳細資訊，請參閱 [https://fluentbit.io/](https://fluentbit.io/) 網站。

**AWS for Fluent Bit** 映像在大多數區域的 Amazon ECR Public Gallery 和 Amazon ECR 儲存庫的 Amazon ECR 上可用以提供高可用性。如需詳細資訊，請參閱 GitHub 網站上的 [https://github.com/aws/aws-for-fluent-bit](https://github.com/aws/aws-for-fluent-bit)。

本教學課程會逐步引導您如何在 Amazon ECS 中執行的 Windows 執行個體上部署 Fluent Bit 容器，從而將 Windows 任務產生的日誌串流至 Amazon CloudWatch 進行集中式記錄。

本教學課程使用下列作法：
+ Fluent Bit 可作為具有常駐程式排程策略的服務執行。此策略可確保 Fluent Bit 的單一執行個體一律在叢集中的容器執行個體上執行。
  + 使用轉寄輸入外掛程式接聽連接埠 24224。
  + 向主機公開連接埠 24224，以便 Docker 執行時間可使用此公開連接埠將日誌傳送到 Fluent Bit。
  + 具有允許 Fluent Bit 將日誌記錄傳送到指定目的地的組態。
+ 使用 Fluentd 日誌記錄驅動程式啟動所有其他 Amazon ECS 任務容器。如需詳細資訊，請參閱 Docker 文件網站上的 [Fluentd logging driver](https://docs.docker.com/engine/logging/drivers/fluentd/) (Fluentd 日誌記錄驅動程式)。
  + Docker 連線到主機命名空間內 localhost 上的 TCP 通訊端 24224。
  + Amazon ECS 代理程式會將標籤新增至容器，其中包括叢集名稱、任務定義系列名稱、任務定義修訂版編號、任務 ARN 和容器名稱。使用 Fluentd Docker 日誌記錄驅動程式的標籤選項將相同的資訊新增到日誌記錄中。如需詳細資訊，請參閱 Docker 文件網站上的 [labels、labels-regex、env 和 env-regex](https://docs.docker.com/config/containers/logging/fluentd/#labels-labels-regex-env-and-env-regex)。
  + 由於 Fluentd 日誌記錄驅動程式的 `async` 選項設定為 `true`，當 Fluent Bit 容器重新啟動時，Docker 會緩衝日誌，直到 Fluent Bit 容器重新啟動為止。您可以透過設定 fluentd-buffer-limit 選項來增加緩衝限制。如需詳細資訊，請參閱 Docker 文件網站上的 [fluentd-buffer-limit](https://docs.docker.com/config/containers/logging/fluentd/#fluentd-buffer-limit)。

 工作流程如下所示：
+ Fluent Bit 容器會啟動並接聽公開至主機的連接埠 24224。
+ Fluent Bit 會使用任務定義中指定的任務 IAM 角色憑證。
+ 在同一個執行個體上啟動的其他任務，會使用 Fluentd Docker 日誌記錄驅動程式連線到連接埠 24224 上的 Fluent Bit 容器。
+ 當應用程式容器生成日誌時，Docker 執行時間會標記這些記錄，新增標籤中指定的其他中繼資料，然後在主機命名空間的連接埠 24224 上轉寄這些中繼資料。
+ Fluent Bit 會接收連接埠 24224 上的日誌記錄，因為其公開到主機命名空間。
+ Fluent Bit 會執行其內部處理，並依照指定的方式路由日誌。

本教學課程使用預設的 CloudWatch Fluent Bit 組態，可執行下列作業：
+ 為每個叢集和任務定義系列建立新的日誌群組。
+ 每當啟動新任務時，為上述產生的日誌群組中的每個任務容器建立新的日誌串流。每個串流將標記容器所屬的任務 ID。
+ 在每個日誌項目中新增其他中繼資料，包括叢集名稱、任務 ARN、任務容器名稱、任務定義系列以及任務定義修訂版編號。

  例如，如果您的 `task_1` 帶有 `container_1` 和 `container_2`，而 `ask_2` 帶有 `container_3`，則下列項目為 CloudWatch 日誌串流：
  + `/aws/ecs/windows.ecs_task_1`

    `task-out.TASK_ID.container_1`

    `task-out.TASK_ID.container_2`
  + `/aws/ecs/windows.ecs_task_2`

    `task-out.TASK_ID.container_3`

**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。

**Topics**
+ [

## 先決條件
](#tutorial-deploy-fluentbit-on-windows-prereqs)
+ [

## 步驟 1：建立 IAM 存取角色
](#tutorial-deploy-fluentbit-on-windows-iam-access-role)
+ [

## 步驟 2：建立 Amazon ECS Windows 容器執行個體
](#tutorial-deploy-fluentbit-on-windows-instance)
+ [

## 步驟 3：設定 Fluent Bit
](#tutorial-deploy-fluentbit-on-windows-configure-fluentbit)
+ [

## 步驟 4：註冊會將日誌路由到 CloudWatch 的 Windows Fluent Bit 任務定義
](#tutorial-deploy-fluentbit-on-windows-register-task-definition)
+ [

## 步驟 5：使用常駐程式排程策略以 Amazon ECS 服務形式執行 `ecs-windows-fluent-bit` 任務定義
](#tutorial-deploy-fluentbit-on-windows-run-task)
+ [

## 步驟 6：註冊會產生日誌的 Windows 任務定義
](#tutorial-deploy-fluentbit-on-windows-register-task-def-logs)
+ [

## 步驟 7：執行 `windows-app-task` 任務定義
](#tutorial-deploy-fluentbit-on-windows-run-task-fluentbit)
+ [

## 步驟 8：驗證 CloudWatch 上的日誌
](#tutorial-deploy-fluentbit-on-windows-verify)
+ [

## 步驟 9：清除
](#tutorial-deploy-fluentbit-on-windows-cleanup)

## 先決條件
<a name="tutorial-deploy-fluentbit-on-windows-prereqs"></a>

本教學課程假設已完成下列先決條件：
+  AWS CLI 已安裝並設定最新版本的 。如需詳細資訊，請參閱 [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ `aws-for-fluent-bit` 容器映像可用於下列 Windows 作業系統：
  + Windows Server 2019 Core
  + Windows Server 2019 Full
  + Windows Server 2022 Core
  + Windows Server 2022 Full
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您有一個叢集。在本教學課程中，叢集名稱是 **FluentBit-cluster**。
+ 您有一個帶有公共子網路的 VPC，EC2 執行個體將在其中啟動。您可以使用預設 VPC。您也可以使用允許 Amazon CloudWatch 端點連上子網路的私有子網路。如需有關 Amazon CloudWatch 端點的詳細資訊，請參閱《AWS 一般參考》**中的 [Amazon CloudWatch 端點和配額](https://docs.aws.amazon.com/general/latest/gr/cw_region.html)。如需使用 Amazon VPC 精靈建立 VPC 的相關資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。

## 步驟 1：建立 IAM 存取角色
<a name="tutorial-deploy-fluentbit-on-windows-iam-access-role"></a>

建立 Amazon ECS IAM 角色。

1.  建立名為「ecsInstanceRole」的 Amazon ECS 容器執行個體角色。如需詳細資訊，請參閱 [Amazon ECS 容器執行個體 IAM 角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html)。

1. 為命名為 `fluentTaskRole` 的 Fluent Bit 任務建立 IAM 角色。如需詳細資訊，請參閱[Amazon ECS 任務 IAM 角色](task-iam-roles.md)。

    在此 IAM 角色中授予的 IAM 許可是由任務容器承繼。為了允許 Fluent Bit 傳送日誌到 CloudWatch，您需要將下列許可附加到任務 IAM 角色。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "logs:CreateLogStream",
               "logs:CreateLogGroup",
               "logs:DescribeLogStreams",
               "logs:PutLogEvents"
           ],
           "Resource": "*"
       }
       ]
   }
   ```

------

1. 將政策連接到角色。

   1. 將上述內容儲存在名為 `fluent-bit-policy.json` 的檔案中。

   1. 執行下列命令，將內嵌政策附加到 `fluentTaskRole` IAM 角色。

      ```
      aws iam put-role-policy --role-name fluentTaskRole --policy-name fluentTaskPolicy --policy-document file://fluent-bit-policy.json
      ```

## 步驟 2：建立 Amazon ECS Windows 容器執行個體
<a name="tutorial-deploy-fluentbit-on-windows-instance"></a>

建立 Amazon ECS Windows 容器執行個體。

**建立 Amazon ECS 執行個體**

1. 使用 `aws ssm get-parameters` 命令擷取託管 VPC 的區域 AMI ID。如需詳細資訊，請參閱[擷取 Amazon ECS 最佳化 AMI 中繼資料](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/retrieve-ecs-optimized_windows_AMI.html)。

1. 使用 Amazon EC2 主控台來啟動執行個體。

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

   1. 從導覽列中選取要使用的「區域」。

   1. 在 **EC2 儀表板**中，選擇 **Launch instance** (啟動執行個體)。

   1. 在 **Name (名稱)** 輸入唯一的名稱。

   1. 在 **Application and OS Images (Amazon Machine Image)** (應用程式和作業系統映像 (Amazon Machine Image)) 欄位中，選擇您在步驟 1 中擷取的 AMI。

   1. 對於 **Instance type (執行個體類型)**，選擇 `t3.xlarge`。

   1. 在 **Key pair (login)** (金鑰對 (登入)) 欄位中，選擇一個金鑰對。

   1. 在 **Network settings** (網路設定) 下的 **Security group** (安全群組) 欄位中，選擇一個現有的安全群組，或建立一個新的安全群組。

   1. 在 **Network settings** (網路設定) 下的 **Auto-assign Public IP** (自動指派公有 IP) 欄位中，選取 **Enable** (啟用)。

   1. 在 **Advanced details** (進階詳細資料) 下的 **IAM instance profile** (IAM 執行個體設定檔) 欄位中，選擇 **ecsInstanceRole**。

   1. 利用下列使用者資料設定您的 Amazon ECS 容器執行個體。在 **Advanced details** (進階詳細資料) 下的 **User data** (使用者資料) 欄位中，貼入下列指令碼，以您的叢集名稱取代 *cluster\$1name*。

      ```
      <powershell>
      Import-Module ECSTools
      Initialize-ECSAgent -Cluster cluster-name -EnableTaskENI -EnableTaskIAMRole -LoggingDrivers '["awslogs","fluentd"]'
      </powershell>
      ```

   1. 準備就緒後，請選取 acknowledgment (確認) 欄位，再選擇 **Launch Instances** (啟動執行個體)。

   1. 會有確認頁面讓您知道您的執行個體正在啟動。選擇 **View Instances** (檢視執行個體) 關閉確認頁面並返回主控台。

## 步驟 3：設定 Fluent Bit
<a name="tutorial-deploy-fluentbit-on-windows-configure-fluentbit"></a>

您可以使用 提供的下列預設組態 AWS 來快速開始使用：
+ [Amazon CloudWatch](https://github.com/aws/aws-for-fluent-bit/blob/mainline/ecs_windows_forward_daemon/cloudwatch.conf)，即基於《Fluent Bit 官方手冊》**中 [Amazon CloudWatch](https://docs.fluentbit.io/manual/v/1.9-pre/pipeline/outputs/cloudwatch) 的 Fluent Bit 外掛程式。

或者，您可以使用 提供的其他預設組態 AWS。如需詳細資訊，請參閱 Github 網站上有關 `aws-for-fluent-bit` 的 [Overriding the entrypoint for the Windows image](https://github.com/aws/aws-for-fluent-bit/tree/mainline/ecs_windows_forward_daemon#overriding-the-entrypoint-for-the-windows-image) (覆寫 Windows 映像的進入點)。

預設的 Amazon CloudWatch Fluent Bit 組態如下所示。

取代下列變數：
+ 將 *region* 取代為您要將 Amazon CloudWatch Logs 傳送到的區域。

```
[SERVICE]
    Flush               5
    Log_Level           info
    Daemon              off

[INPUT]
    Name                forward
    Listen              0.0.0.0
    Port                24224
    Buffer_Chunk_Size   1M
    Buffer_Max_Size     6M
    Tag_Prefix          ecs.

# Amazon ECS agent adds the following log keys as labels to the docker container.
# We would use fluentd logging driver to add these to log record while sending it to Fluent Bit.
[FILTER]
    Name                modify
    Match               ecs.*
    Rename              com.amazonaws.ecs.cluster ecs_cluster
    Rename              com.amazonaws.ecs.container-name ecs_container_name
    Rename              com.amazonaws.ecs.task-arn ecs_task_arn
    Rename              com.amazonaws.ecs.task-definition-family ecs_task_definition_family
    Rename              com.amazonaws.ecs.task-definition-version ecs_task_definition_version

[FILTER]
    Name                rewrite_tag
    Match               ecs.*
    Rule                $ecs_task_arn ^([a-z-:0-9]+)/([a-zA-Z0-9-_]+)/([a-z0-9]+)$  out.$3.$ecs_container_name false
    Emitter_Name        re_emitted

[OUTPUT]
    Name                cloudwatch_logs
    Match               out.*
    region              region
    log_group_name      fallback-group
    log_group_template  /aws/ecs/$ecs_cluster.$ecs_task_definition_family
    log_stream_prefix   task-
    auto_create_group   On
```

每個進入 Fluent Bit 的日誌都有一個您指定的標籤，或者在您不提供標籤時自動生成。這些標籤可用來將不同的日誌路由到不同的目的地。如需詳細資訊，請參閱《Fluent Bit 官方手冊》**中的[標籤](https://docs.fluentbit.io/manual/concepts/key-concepts#tag)。

上述 Fluent Bit 組態具有下列屬性：
+ 轉寄輸入外掛程式會接聽 TCP 連接埠 24224 上的傳入流量。
+ 在該連接埠上收到的每個日誌項目都有一個標籤，轉寄輸入外掛程式會修改該標籤，以在記錄前面加上 `ecs.` 字串。
+ Fluent Bit 內部管道會路由日誌項目，以使用符合規則運算式修改篩選條件。此篩選條件將日誌記錄 JSON 中的金鑰替換為 Fluent Bit 可以使用的格式。
+ 然後，rewrite\$1tag 篩選條件會使用修改後的日誌項目。此篩選條件會將日誌記錄的標籤變更為格式輸出 *TASK\$1ID*.*CONTAINER\$1NAME*。
+ 新標籤將路由至輸出 cloudwatch\$1logs 外掛程式，該外掛程式會使用 CloudWatch 輸出外掛程式的 `log_group_template` 和 `log_stream_prefix` 選項來建立前文所述的日誌群組和串流。如需其他資訊，請參閱《Fluent Bit 官方手冊》**中的[組態參數](https://docs.fluentbit.io/manual/v/1.9-pre/pipeline/outputs/cloudwatch#configuration-parameters)。

## 步驟 4：註冊會將日誌路由到 CloudWatch 的 Windows Fluent Bit 任務定義
<a name="tutorial-deploy-fluentbit-on-windows-register-task-definition"></a>

註冊會將日誌路由到 CloudWatch 的 Windows Fluent Bit 任務定義。

**注意**  
此任務定義會將 Fluent Bit 容器連接埠 24224 公開至主機連接埠 24224。確認此連接埠未在 EC2 執行個體安全群組中開啟，防止從外部存取。

**註冊任務定義**

1. 使用下列內容建立名為 `fluent-bit.json` 的檔案。

   取代下列變數：
   + 將 *task-iam-role* 替代為任務 IAM 角色的 Amazon Resource Name (ARN)
   + 將 *region* 替代為任務執行所在的區域

   ```
   {
     "family": "ecs-windows-fluent-bit",
     "taskRoleArn": "task-iam-role",
     "containerDefinitions": [
       {
         "name": "fluent-bit",
         "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:windowsservercore-latest",
         "cpu": 512,
         "portMappings": [
           {
             "hostPort": 24224,
             "containerPort": 24224,
             "protocol": "tcp"
           }
         ],
         "entryPoint": [
           "Powershell",
           "-Command"
         ],
         "command": [
           "C:\\entrypoint.ps1 -ConfigFile C:\\ecs_windows_forward_daemon\\cloudwatch.conf"
         ],
         "environment": [
           {
             "name": "AWS_REGION",
             "value": "region"
           }
         ],
         "memory": 512,
         "essential": true,
         "logConfiguration": {
           "logDriver": "awslogs",
           "options": {
             "awslogs-group": "/ecs/fluent-bit-logs",
             "awslogs-region": "region",
             "awslogs-stream-prefix": "flb",
             "awslogs-create-group": "true"
           }
         }
       }
     ],
     "memory": "512",
     "cpu": "512"
   }
   ```

1. 執行下列命令來註冊任務定義。

   ```
   aws ecs register-task-definition --cli-input-json file://fluent-bit.json --region region
   ```

   您可以執行 `list-task-definitions` 命令列出您帳戶的任務定義。輸出顯示可與 `run-task` 或 `start-task` 搭配使用的系列和修訂版值。

## 步驟 5：使用常駐程式排程策略以 Amazon ECS 服務形式執行 `ecs-windows-fluent-bit` 任務定義
<a name="tutorial-deploy-fluentbit-on-windows-run-task"></a>

註冊帳戶的任務定義後，您就可以在叢集中執行任務。在本教學課程中，您會在 `FluentBit-cluster` 叢集中執行 `ecs-windows-fluent-bit:1` 任務定義的一個執行個體。在使用常駐程式排程策略的服務中執行任務，用以確保 Fluent Bit 的單一執行個體一律在每個容器執行個體上執行。

**執行任務**

1. 執行下列命令，以服務形式啟動 `ecs-windows-fluent-bit:1` 任務定義 (在上一個步驟中註冊)。
**注意**  
此任務定義使用 `awslogs` 日誌記錄驅動程式，您的容器執行個體需要具有必要的許可。

   取代下列變數：
   + 將 *region* 替代為服務執行所在的區域

   ```
   aws ecs create-service \
       --cluster FluentBit-cluster \
       --service-name FluentBitForwardDaemonService \
       --task-definition ecs-windows-fluent-bit:1 \
       --launch-type EC2 \
       --scheduling-strategy DAEMON \
       --region region
   ```

1. 執行下列命令以列出您的任務。

   取代下列變數：
   + 將 *region* 替代為服務任務執行所在的區域

   ```
   aws ecs list-tasks --cluster FluentBit-cluster --region region
   ```

## 步驟 6：註冊會產生日誌的 Windows 任務定義
<a name="tutorial-deploy-fluentbit-on-windows-register-task-def-logs"></a>

註冊會產生日誌的任務定義。此任務定義會部署 Windows 容器映像，該映像會每秒向 `stdout` 寫入一個遞增數字。

任務定義會使用連線到 Fluent Bit 外掛程式接聽連接埠 24224 的 Fluentd 日誌記錄驅動程式。Amazon ECS 代理程式會為每個 Amazon ECS 容器新增標籤，包括叢集名稱、任務 ARN、任務定義系列名稱、任務定義修訂版編號和任務容器名稱。這些鍵/值對標籤會傳遞至 Fluent Bit。

**注意**  
此任務會使用 `default` 網路模式。不過，您也可以在任務中使用 `awsvpc` 網路模式。

**註冊任務定義**

1. 使用下列內容建立名為 `windows-app-task.json` 的檔案。

   ```
   {
     "family": "windows-app-task",
     "containerDefinitions": [
       {
         "name": "sample-container",
         "image": "mcr.microsoft.com/windows/servercore:ltsc2019",
         "cpu": 512,
         "memory": 512,
         "essential": true,
         "entryPoint": [
           "Powershell",
           "-Command"
         ],
         "command": [
           "$count=1;while(1) { Write-Host $count; sleep 1; $count=$count+1;}"
         ],
         "logConfiguration": {
           "logDriver": "fluentd",
           "options": {
             "fluentd-address": "localhost:24224",
             "tag": "{{ index .ContainerLabels \"com.amazonaws.ecs.task-definition-family\" }}",
             "fluentd-async": "true",
             "labels": "com.amazonaws.ecs.cluster,com.amazonaws.ecs.container-name,com.amazonaws.ecs.task-arn,com.amazonaws.ecs.task-definition-family,com.amazonaws.ecs.task-definition-version"
           }
         }
       }
     ],
     "memory": "512",
     "cpu": "512"
   }
   ```

1. 執行下列命令來註冊任務定義。

   取代下列變數：
   + 將 *region* 替代為任務執行所在的區域

   ```
   aws ecs register-task-definition --cli-input-json file://windows-app-task.json --region region
   ```

   您可以執行 `list-task-definitions` 命令列出您帳戶的任務定義。輸出顯示可與 `run-task` 或 `start-task` 搭配使用的系列和修訂版值。

## 步驟 7：執行 `windows-app-task` 任務定義
<a name="tutorial-deploy-fluentbit-on-windows-run-task-fluentbit"></a>

註冊 `windows-app-task` 任務定義之後，請在 `FluentBit-cluster` 叢集中執行該定義。

**執行任務**

1. 執行您在上一個步驟中註冊的 `windows-app-task:1` 任務定義。

   取代下列變數：
   + 將 *region* 替代為任務執行所在的區域

   ```
   aws ecs run-task --cluster FluentBit-cluster --task-definition windows-app-task:1 --count 2 --region region
   ```

1. 執行下列命令以列出您的任務。

   ```
   aws ecs list-tasks --cluster FluentBit-cluster
   ```

## 步驟 8：驗證 CloudWatch 上的日誌
<a name="tutorial-deploy-fluentbit-on-windows-verify"></a>

為了驗證您的 Fluent Bit 設定，請在 CloudWatch 主控台中檢查下列日誌群組：
+ `/ecs/fluent-bit-logs` – 這是日誌群組，對應在容器執行個體上執行的 Fluent Bit 常駐程式容器。
+ `/aws/ecs/FluentBit-cluster.windows-app-task` - 這是日誌群組，對應在 `FluentBit-cluster` 叢集內為 `windows-app-task` 任務定義系列啟動的所有任務。

   `task-out.FIRST_TASK_ID.sample-container` – 此日誌串流包含 sample-container 任務容器中由任務的第一個執行個體產生的所有日誌。

  `task-out.SECOND_TASK_ID.sample-container` – 此日誌串流包含 sample-container 任務容器中由任務的第二個執行個體產生的所有日誌。

 `task-out.TASK_ID.sample-container` 日誌串流的欄位與下列類似：

```
{
    "source": "stdout",
    "ecs_task_arn": "arn:aws:ecs:region:0123456789012:task/FluentBit-cluster/13EXAMPLE",
    "container_name": "/ecs-windows-app-task-1-sample-container-cEXAMPLE",
    "ecs_cluster": "FluentBit-cluster",
    "ecs_container_name": "sample-container",
    "ecs_task_definition_version": "1",
    "container_id": "61f5e6EXAMPLE",
    "log": "10",
    "ecs_task_definition_family": "windows-app-task"
}
```

**驗證 Fluent Bit 設定**

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

1. 在導覽窗格中，選擇 **Log groups** (日誌群組)。請確定您位於將 Fluent Bit 部署到容器的區域。

   在 中的日誌群組清單中 AWS 區域，您應該會看到以下內容：
   + `/ecs/fluent-bit-logs`
   + `/aws/ecs/FluentBit-cluster.windows-app-task`

   如果您看到這些日誌群組，表示 Fluent Bit 設定已通過驗證。

## 步驟 9：清除
<a name="tutorial-deploy-fluentbit-on-windows-cleanup"></a>

完成此教學課程時，清除與其相關的資源，以免未使用的資源產生費用。

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

1. 停止 `windows-simple-task` 任務和 `ecs-fluent-bit` 任務。如需詳細資訊，請參閱[停止 Amazon ECS 任務](standalone-task-stop.md)。

1. 執行下列命令來刪除 `/ecs/fluent-bit-logs` 日誌群組。如需有關刪除日誌群組的詳細資訊，請參閱《AWS Command Line Interface 參考》**中的 [delete-log-group](https://docs.aws.amazon.com/cli/latest/reference/logs/delete-log-group.html)。

   ```
   aws logs delete-log-group --log-group-name /ecs/fluent-bit-logs
   aws logs delete-log-group --log-group-name /aws/ecs/FluentBit-cluster.windows-app-task
   ```

1. 執行下列命令以終止執行個體。

   ```
   aws ec2 terminate-instances --instance-ids instance-id
   ```

1. 執行下列命令以刪除 IAM 角色。

   ```
   aws iam delete-role --role-name ecsInstanceRole
   aws iam delete-role --role-name fluentTaskRole
   ```

1. 執行下列命令以刪除 Amazon ECS 叢集。

   ```
   aws ecs delete-cluster --cluster FluentBit-cluster
   ```

# 在 Amazon ECS 上為 EC2 Linux 容器使用 gMSA
<a name="linux-gmsa"></a>

Amazon ECS 透過名為*群組受管服務帳戶* (gMSA) 的特殊類型服務帳戶，支援為 EC2 上的 Linux 容器提供 Active Directory 身分驗證。

.NET Core 應用程式等以 Linux 為基礎的網路應用程式，可使用 Active Directory 來促進使用者和服務之間的身分驗證和授權管理。您可以透過設計與 Active Directory 整合並在加入網域的伺服器上執行的應用程式來使用此功能。但是，由於 Linux 容器無法加入網域，因此您需要設定 Linux 容器來執行 gMSA。

使用 gMSA 執行的 Linux 容器依賴在容器主機 Amazon EC2 執行個體上執行的 `credentials-fetcher` 常駐程式。也就是說，常駐程式會從 Active Directory 網域控制站擷取 gMSA 憑證，然後將這些憑證傳輸到容器執行個體。如需有關服務帳戶的詳細資訊，請參閱 Microsoft Learn 網站上的[針對 Windows 容器建立 gMSAs](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts)。

## 考量事項
<a name="linux-gmsa-considerations"></a>

針對 Linux 容器使用 gMSA 前，請考慮以下事項：
+ 如果您的容器在 EC2 上執行，則可以針對 Windows 容器和 Linux 容器使用 gMSA。如需有關在 Fargate 上為 Linux 容器使用 gMSA 的詳細資訊，請參閱[在 Fargate 上為 Linux 容器使用 gMSA](fargate-linux-gmsa.md)。
+ 您可能需要加入網域的 Windows 電腦才能完成先決條件。例如，您可能需要加入網域的 Windows 電腦，才能在使用 PowerShell 的 Active Directory 中建立 gMSA。RSATActive Director PowerShell 工具僅適用於 Windows。如需詳細資訊，請參閱[安裝 Active Directory 管理工具](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_install_ad_tools.html)。
+ 您可以選擇**無網域 gMSA** 或**將每個執行個體加入單一網域**。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

  然後，選擇 CredSpec 的資料儲存，也可以選擇無網域 gMSA 的 Active Directory 使用者憑證的資料儲存。

  Amazon ECS 使用 Active Directory 憑證規格檔案 (CredSpec)。此檔案包含用於將 gMSA 帳戶內容傳播至容器的 gMSA 中繼資料。您會產生 CredSpec 檔案，然後將其儲存在下表中特定於容器執行個體的作業系統的 CredSpec 儲存選項之一。若要使用無網域方法，CredSpec 檔案中的選擇性區段可以在下表中的 *domainless user credentials* 儲存選項之一中指定憑證 (特定於容器執行個體的作業系統)。    
<a name="gmsa-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonECS/latest/developerguide/linux-gmsa.html)

## 先決條件
<a name="linux-gmsa-prerequisites"></a>

在搭配 Amazon ECS 使用 Linux 容器功能適用的 gMSA 之前，請先完成下列各項：
+ 您可以使用您希望容器存取的資源來設定 Active Directory 網域。Amazon ECS 支援下列設定：
  +  Directory Service Active Directory. Directory Service 是在 Amazon EC2 上託管的 AWS 受管 Active Directory。如需詳細資訊，請參閱《 *AWS Directory Service 管理指南*》中的 [AWS Managed Microsoft AD 入門](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)。
  + 內部部署 Active Directory。您必須確認 Amazon ECS Linux 容器執行個體可以加入網域。如需詳細資訊，請參閱[AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect.html)。
+ 您在 Active Directory 中擁有現有的 gMSA 帳戶。如需詳細資訊，請參閱[在 Amazon ECS 上為 EC2 Linux 容器使用 gMSA](#linux-gmsa)。
+ 您已在 Amazon ECS Linux 容器執行個體上安裝並執行 `credentials-fetcher` 常駐程式。您也將一組初始的憑證新增至 `credentials-fetcher` 常駐程式，以便透過 Active Directory 進行身分驗證。
**注意**  
`credentials-fetcher` 常駐程式僅適用於 Amazon Linux 2023 和 Fedora 37 及更新版本。該常駐程式不適用於 Amazon Linux 2。如需詳細資訊，請參閱 GitHub 上的 [aws/credentials-fetcher](https://github.com/aws/credentials-fetcher)。
+ 您可以設定 `credentials-fetcher` 常駐程式的憑證，以便使用 Active Directory 進行身分驗證。憑證必須是具有 gMSA 帳戶存取權的 Active Directory 安全群組的成員。[決定是否要將執行個體加入網域，或是要使用無網域 gMSA。](#linux-gmsa-initial-creds) 中有多個選項。
+ 您已新增必要的 IAM 許可 所需的許可取決於您為初始憑證選擇的方法以及儲存憑證規格的方法：
  + 如果您使用*無網域gMSA*做為初始登入資料， AWS Secrets Manager 則任務執行角色需要 的 IAM 許可。
  + 如果您將憑證規格存放在 SSM 參數存放區中，則任務執行角色需要 Amazon EC2 Systems Manager 參數存放區的 IAM 許可。
  + 如果您將憑證規格存放在 Amazon S3 中，則任務執行角色需要 Amazon Simple Storage Service 的 IAM 許可。

## 在 Amazon ECS 上設定能夠使用 gMSA 功能的 Linux 容器
<a name="linux-gmsa-setup"></a>
<a name="linux-gmsa-setup-infra"></a>
**準備基礎設施**  
下列步驟是執行一次的考量和設定。完成這些步驟後，您可以自動建立容器執行個體以重複使用此組態。

決定如何提供初始憑證，並在可重複使用的 EC2 啟動範本中設定 EC2 使用者資料以安裝 `credentials-fetcher` 常駐程式。

1. <a name="linux-gmsa-initial-creds"></a>

**決定是否要將執行個體加入網域，或是要使用無網域 gMSA。**
   + <a name="linux-gmsa-initial-join"></a>

**將 EC2 執行個體加入 Active Directory 網域**

     
     + <a name="linux-gmsa-initial-join-userdata"></a>

**透過使用者資料加入執行個體**

       在 EC2 啟動範本中新增將 Active Directory 網域加入 EC2 使用者資料的步驟。多個 Amazon EC2 Auto Scaling 群組可以使用相同的啟動範本。

       您可以在 Fedora 文件中使用這些步驟[加入 Active Directory 或 FreeIPA 網域](https://docs.fedoraproject.org/en-US/quick-docs/join-active-directory-freeipa/)。
   + <a name="linux-gmsa-initial-domainless"></a>

**建立無網域 gMSA 的 Active Directory 使用者**

     `credentials-fetcher` 常駐程式具有稱為*無網域 gMSA* 的功能。此功能需要網域，但 EC2 執行個體不需要加入網域。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。相反地，您會在 CredSpec 檔案中提供 AWS Secrets Manager 祕密的名稱。祕密必須包含使用者名稱、密碼和要登入的網域。

     此功能受到支援，可與 Linux 和 Windows 容器搭配使用。

     此功能與 *gMSA support for non-domain-joined container hosts* 功能類似。如需有關 Windows 功能的詳細資訊，請參閱 Microsoft Learn 網站上的 [gMSA 架構和改進](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements)。

     1. 在 Active Directory 網域中建立使用者。Active Directory 中的使用者必須具有存取您在任務中使用之 gMSA 服務帳戶的權限。

     1. 在 Active Directory 中建立使用者之後 AWS Secrets Manager，在 中建立秘密。如需詳細資訊，請參閱[建立 AWS Secrets Manager 秘密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)。

     1. 將使用者的使用者名稱、密碼和網域分別輸入到名為 `username`、`password` 和 `domainName` 的 JSON 鍵值組中。

        ```
        {"username":"username","password":"passw0rd", "domainName":"example.com"}
        ```

     1. 將組態新增至服務帳戶的 CredSpec 檔案。其他的 `HostAccountConfig` 包含 Secrets Manager 祕密的 Amazon Resource Name (ARN)。

        在 Windows 上，`PluginGUID` 必須符合下列範例程式碼片段中的 GUID。在 Linux 上，會忽略 `PluginGUID`。將 `MySecret` 替換為含有祕密的 Amazon Resource Name (ARN) 的範例。

        ```
            "ActiveDirectoryConfig": {
                "HostAccountConfig": {
                    "PortableCcgVersion": "1",
                    "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
                    "PluginInput": {
                        "CredentialArn": "arn:aws:secretsmanager:aws-region:111122223333:secret:MySecret"
                    }
                }
        ```

     1. *無網域 gMSA* 功能需要任務執行角色中的其他許可。請遵循步驟 [(選用) 無網域 gMSA 祕密](#linux-gmsa-domainless-secret)。

1. <a name="linux-gmsa-install"></a>

**設定執行個體並安裝 `credentials-fetcher` 常駐程式**

   您可以在 EC2 啟動範本中使用使用者資料指令碼來安裝 `credentials-fetcher` 常駐程式。以下範例示範兩種類型的使用者資料、`cloud-config` YAML 或 bash 指令碼。這些範例適用於 Amazon Linux 2023 (AL2023)。將 `MyCluster` 替換為您想要這些執行個體加入的 Amazon ECS 叢集的名稱。
   + <a name="linux-gmsa-install-yaml"></a>

**`cloud-config` YAML**

     ```
     Content-Type: text/cloud-config
     package_reboot_if_required: true
     packages:
       # prerequisites
       - dotnet
       - realmd
       - oddjob
       - oddjob-mkhomedir
       - sssd
       - adcli
       - krb5-workstation
       - samba-common-tools
       # https://github.com/aws/credentials-fetcher gMSA credentials management for containers
       - credentials-fetcher
     write_files:
     # configure the ECS Agent to join your cluster.
     # replace MyCluster with the name of your cluster.
     - path: /etc/ecs/ecs.config
       owner: root:root
       permissions: '0644'
       content: |
         ECS_CLUSTER=MyCluster
         ECS_GMSA_SUPPORTED=true
     runcmd:
     # start the credentials-fetcher daemon and if it succeeded, make it start after every reboot
     - "systemctl start credentials-fetcher"
     - "systemctl is-active credentials-fetcher && systemctl enable credentials-fetcher"
     ```
   + <a name="linux-gmsa-install-userdata"></a>

**bash 指令碼**

     如果您比較習慣 bash 指令碼，並且有多個要寫入 `/etc/ecs/ecs.config` 的變數，請使用以下 `heredoc` 格式。此格式會將開頭為 **cat** 和 `EOF` 之行間的所有項目寫入組態檔案。

     ```
     #!/usr/bin/env bash
     set -euxo pipefail
     
     # prerequisites
     timeout 30 dnf install -y dotnet realmd oddjob oddjob-mkhomedir sssd adcli krb5-workstation samba-common-tools
     # install https://github.com/aws/credentials-fetcher gMSA credentials management for containers
     timeout 30 dnf install -y credentials-fetcher
     
     # start credentials-fetcher
     systemctl start credentials-fetcher
     systemctl is-active credentials-fetcher && systemctl enable credentials-fetcher
     
     cat <<'EOF' >> /etc/ecs/ecs.config
     ECS_CLUSTER=MyCluster
     ECS_GMSA_SUPPORTED=true
     EOF
     ```

   選用組態變數適用於 `credentials-fetcher` 常駐程式，您可以在 `/etc/ecs/ecs.config` 中設定該變數。我們建議您在 YAML 區塊或與先前範例類似的 `heredoc` 內的使用者資料中設定變數。這樣做可防止多次編輯檔案時可能會發生的部分組態問題。如需有關 ECS 代理程式組態的詳細資訊，請參閱 GitHub 上的 [Amazon ECS 容器代理程式](https://github.com/aws/amazon-ecs-agent/blob/master/README.md#environment-variables)。
   + 或者，如果您變更 `credentials-fetcher` 常駐程式組態，將通訊端移至其他位置，您也可以使用變數 `CREDENTIALS_FETCHER_HOST`。

**設定許可和祕密**  
針對每個應用程式和每個任務定義執行下列步驟一次。我們建議您使用授予最低權限的最佳實務，並縮減政策中使用的許可。這樣一來，每個任務都只能讀取所需的祕密。

1. <a name="linux-gmsa-domainless-secret"></a>

**(選用) 無網域 gMSA 祕密**

   如果您使用執行個體未加入網域的無網域方法，請依照此步驟執行。

   您必須將以下許可作為內嵌政策新增至任務執行 IAM 角色。這樣做可讓 `credentials-fetcher` 常駐程式存取 Secrets Manager 的祕密。將 `MySecret` 替換為在 `Resource` 清單中含有祕密的 Amazon Resource Name (ARN) 的範例。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret-AbCdEf"
           }
       ]
   }
   ```

------
**注意**  
如果您使用自己的 KMS 金鑰來加密秘密，則必須將必要的許可新增至此角色，並將此角色新增至 AWS KMS 金鑰政策。

1. 

**決定您要使用 SSM 參數存放區或 S3 來存放 CredSpec**

   Amazon ECS 支援以下方法，在任務定義的 `credentialSpecs` 欄位中參考檔案路徑。

   如果您將執行個體加入單一網域，請在字串中在 ARN 開頭使用 `credentialspec:` 作為字首。如果您使用無網域 gMSA，請使用 `credentialspecdomainless:`。

   如需 CredSpec 的詳細資訊，請參閱 [憑證規格檔案](#linux-gmsa-credentialspec)。
   + <a name="linux-gmsa-credspec-s3"></a>

**Amazon S3 儲存貯體**

     將憑證規格新增至 Amazon S3 儲存貯體。然後，在任務定義的 `credentialSpecs` 欄位中參考 Amazon S3 儲存貯體的 Amazon Resource Name (ARN)。

     ```
     {
         "family": "",
         "executionRoleArn": "",
         "containerDefinitions": [
             {
                 "name": "",
                 ...
                 "credentialSpecs": [
                     "credentialspecdomainless:arn:aws:s3:::${BucketName}/${ObjectName}"
                 ],
                 ...
             }
         ],
         ...
     }
     ```

     若要讓您的任務能夠存取 S3 儲存貯體，請新增下列許可做為 Amazon ECS 任務執行 IAM 角色的內嵌政策。

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

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Statement": [
             {
                 "Sid": "VisualEditor",
                 "Effect": "Allow",
                 "Action": [
                     "s3:Get*",
                     "s3:List*"
                 ],
                 "Resource": [
                     "arn:aws:s3:::amzn-s3-demo-bucket",
                     "arn:aws:s3:::amzn-s3-demo-bucket/{object}"
                 ]
             }
         ]
     }
     ```

------
   + <a name="linux-gmsa-credspec-ssm"></a>

**SSM 參數存放區參數**

     將憑證規格新增至 SSM 參數存放區參數。然後，在任務定義的 `credentialSpecs` 欄位中參考 SSM 參數存放區參數的 Amazon Resource Name (ARN)。

     ```
     {
         "family": "",
         "executionRoleArn": "",
         "containerDefinitions": [
             {
                 "name": "",
                 ...
                 "credentialSpecs": [
                     "credentialspecdomainless:arn:aws:ssm:aws-region:111122223333:parameter/parameter_name"
                 ],
                 ...
             }
         ],
         ...
     }
     ```

     若要讓您的任務能夠存取 SSM 參數存放區參數，請新增下列許可做為 Amazon ECS 任務執行 IAM 角色的內嵌政策。

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

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "ssm:GetParameters"
                 ],
                 "Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/my-parameter"
             }
         ]
     }
     ```

------

## 憑證規格檔案
<a name="linux-gmsa-credentialspec"></a>

Amazon ECS 使用 Active Directory 憑證規格檔案 (*CredSpec*)。此檔案包含用於將 gMSA 帳戶內容傳播至容器 Linux 的 gMSA 中繼資料。您會產生 CredSpec，並在任務定義的 `credentialSpecs` 欄位中參考該檔案。CredSpec 檔案不包含任何祕密。

以下是範例 CredSpec 檔案。

```
{
    "CmsPlugins": [
        "ActiveDirectory"
    ],
    "DomainJoinConfig": {
        "Sid": "S-1-5-21-2554468230-2647958158-2204241789",
        "MachineAccountName": "WebApp01",
        "Guid": "8665abd4-e947-4dd0-9a51-f8254943c90b",
        "DnsTreeName": "example.com",
        "DnsName": "example.com",
        "NetBiosName": "example"
    },
    "ActiveDirectoryConfig": {
        "GroupManagedServiceAccounts": [
            {
                "Name": "WebApp01",
                "Scope": "example.com"
            }
        ],
        "HostAccountConfig": {
            "PortableCcgVersion": "1",
            "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
            "PluginInput": {
                "CredentialArn": "arn:aws:secretsmanager:aws-region:111122223333:secret:MySecret"
            }
        }
    }
}
```
<a name="linux-gmsa-credentialspec-create"></a>
**建立CredSpec**  
您可以在加入網域的 Windows 電腦上使用 CredSpec PowerShell 模組來建立 CredSpec。請依照 Microsoft Learn 網站上[建立憑證規格](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#create-a-credential-spec)中的步驟進行。

# 在 Fargate 上為 Linux 容器使用 gMSA
<a name="fargate-linux-gmsa"></a>

Amazon ECS 透過名為*群組受管服務帳戶* (gMSA) 的特殊類型服務帳戶，支援為 Fargate 上的 Linux 容器提供 Active Directory 身分驗證。

.NET Core 應用程式等以 Linux 為基礎的網路應用程式，可使用 Active Directory 來促進使用者和服務之間的身分驗證和授權管理。您可以透過設計與 Active Directory 整合並在加入網域的伺服器上執行的應用程式來使用此功能。但是，由於 Linux 容器無法加入網域，因此您需要設定 Linux 容器來執行 gMSA。

## 考量事項
<a name="fargate-linux-gmsa-considerations"></a>

在 Fargate 上為 Linux 容器使用 gMSA 之前，請考量以下事項：
+ 您必須執行平台版本 1.4 或更新版本。
+ 您可能需要加入網域的 Windows 電腦才能完成先決條件。例如，您可能需要加入網域的 Windows 電腦，才能在使用 PowerShell 的 Active Directory 中建立 gMSA。RSATActive Director PowerShell 工具僅適用於 Windows。如需詳細資訊，請參閱[安裝 Active Directory 管理工具](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_install_ad_tools.html)。
+ 您必須使用**無網域 gMSA**。

  Amazon ECS 使用 Active Directory 憑證規格檔案 (CredSpec)。此檔案包含用於將 gMSA 帳戶內容傳播至容器的 gMSA 中繼資料。您可以產生 CredSpec 檔案，然後將其儲存於 Amazon S3 儲存貯體中。
+ 一個任務只能支援一個 Active Directory。

## 先決條件
<a name="fargate-linux-gmsa-prerequisites"></a>

在搭配 Amazon ECS 使用 Linux 容器功能適用的 gMSA 之前，請先完成下列各項：
+ 您可以使用您希望容器存取的資源來設定 Active Directory 網域。Amazon ECS 支援下列設定：
  +  Directory Service Active Directory. Directory Service 是在 Amazon EC2 上託管的 AWS 受管 Active Directory。如需詳細資訊，請參閱《 *AWS Directory Service 管理指南*》中的 [AWS Managed Microsoft AD 入門](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)。
  + 內部部署 Active Directory。您必須確認 Amazon ECS Linux 容器執行個體可以加入網域。如需詳細資訊，請參閱[AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect-network-to-amazon.html)。
+ 您在 Active Directory 中有一個現存的 gMSA 帳戶，也有一個具備存取 gMSA 服務帳戶許可的使用者。如需詳細資訊，請參閱[建立無網域 gMSA 的 Active Directory 使用者](#fargate-linux-gmsa-initial-domainless)。
+ 您已有 Amazon S3 儲存貯體。如需詳細資訊，請參閱 *Amazon S3 User Guide* 中的 [Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)。

## 在 Amazon ECS 上設定能夠使用 gMSA 功能的 Linux 容器
<a name="fargate-linux-gmsa-setup"></a>
<a name="linux-gmsa-setup-infra"></a>
**準備基礎設施**  
下列步驟是執行一次的考量和設定。
+ <a name="fargate-linux-gmsa-initial-domainless"></a>

**建立無網域 gMSA 的 Active Directory 使用者**

  使用無網域 gMSA 時，容器不會加入網域。在容器上執行的其他應用程式無法使用該憑證存取網域。使用不同網域的任務可在同一容器上執行。您可以在 CredSpec 檔案中提供 AWS Secrets Manager 中的秘密名稱。祕密必須包含使用者名稱、密碼和要登入的網域。

  此功能與 *gMSA support for non-domain-joined container hosts* 功能類似。如需有關 Windows 功能的詳細資訊，請參閱 Microsoft Learn 網站上的 [gMSA 架構和改進](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements)。

  1. 在 Active Directory 網域中設定使用者。Active Directory 中的使用者必須具有存取您在任務中使用之 gMSA 服務帳戶的許可。

  1. 您擁有可以解析 Active Directory 網域的 VPC 和子網路。設定 VPC 時，需在 DHCP 選項中設定指向 Active Directory 服務名稱的網域名稱。如需有關為 VPC 設定 DHCP 選項的資訊，請參閱 *Amazon Virtual Private Cloud User Guide* 中的 [Work with DHCP option sets](https://docs.aws.amazon.com/vpc/latest/userguide/DHCPOptionSet.html)。

  1. 在 中建立秘密 AWS Secrets Manager。

  1. 建立憑證規格檔案。

**設定許可和祕密**  
針對每個應用程式與每項任務定義，執行下列步驟一次。我們建議您使用授予最低權限的最佳實務，並縮減政策中使用的許可。這樣一來，每個任務都只能讀取所需的祕密。

1. 在 Active Directory 網域中建立使用者。Active Directory 中的使用者必須具有存取您在任務中使用之 gMSA 服務帳戶的權限。

1. 成為 Active Directory 使用者之後，請在其中建立秘密 AWS Secrets Manager。如需詳細資訊，請參閱[建立 AWS Secrets Manager 祕密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)。

1. 將使用者的使用者名稱、密碼和網域分別輸入到名為 `username`、`password` 和 `domainName` 的 JSON 鍵值組中。

   ```
   {"username":"username","password":"passw0rd", "domainName":"example.com"}
   ```

1. <a name="fargate-linux-gmsa-domainless-secret"></a>您必須將以下許可作為內嵌政策新增至任務執行 IAM 角色。這樣做可讓 `credentials-fetcher` 常駐程式存取 Secrets Manager 的祕密。將 `MySecret` 替換為在 `Resource` 清單中含有祕密的 Amazon Resource Name (ARN) 的範例。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": [
               "arn:aws:secretsmanager:us-east-1:111122223333:secret:MySecret"
               ]
           }
       ]
   }
   ```

------
**注意**  
如果您使用自己的 KMS 金鑰來加密秘密，則必須將必要的許可新增至此角色，並將此角色新增至 AWS KMS 金鑰政策。

1. <a name="linux-gmsa-credspec-ssm"></a>將憑證規格新增至 Amazon S3 儲存貯體。然後，在任務定義的 `credentialSpecs` 欄位中參考 Amazon S3 儲存貯體的 Amazon Resource Name (ARN)。

   ```
   {
       "family": "",
       "executionRoleArn": "",
       "containerDefinitions": [
           {
               "name": "",
               ...
               "credentialSpecs": [
                   "credentialspecdomainless:arn:aws:s3:::${BucketName}/${ObjectName}"
               ],
               ...
           }
       ],
       ...
   }
   ```

   若要讓您的任務能夠存取 S3 儲存貯體，請新增下列許可作為 Amazon ECS 任務執行 IAM 角色的內嵌政策。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "VisualEditor",
               "Effect": "Allow",
               "Action": [
               "s3:GetObjectVersion",
               "s3:ListBucket"
               ],
               "Resource": [
                   "arn:aws:s3:::{bucket_name}",
                   "arn:aws:s3:::{bucket_name}/{object}"
               ]
           }
       ]
   }
   ```

------

## 憑證規格檔案
<a name="fargate-linux-gmsa-credentialspec"></a>

Amazon ECS 使用 Active Directory 憑證規格檔案 (*CredSpec*)。此檔案包含用於將 gMSA 帳戶內容傳播至容器 Linux 的 gMSA 中繼資料。您會產生 CredSpec，並在任務定義的 `credentialSpecs` 欄位中參考該檔案。CredSpec 檔案不包含任何祕密。

以下是範例 CredSpec 檔案。

```
{
    "CmsPlugins": [
        "ActiveDirectory"
    ],
    "DomainJoinConfig": {
        "Sid": "S-1-5-21-2554468230-2647958158-2204241789",
        "MachineAccountName": "WebApp01",
        "Guid": "8665abd4-e947-4dd0-9a51-f8254943c90b",
        "DnsTreeName": "example.com",
        "DnsName": "example.com",
        "NetBiosName": "example"
    },
    "ActiveDirectoryConfig": {
        "GroupManagedServiceAccounts": [
            {
                "Name": "WebApp01",
                "Scope": "example.com"
            }
        ],
        "HostAccountConfig": {
            "PortableCcgVersion": "1",
            "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
            "PluginInput": {
                "CredentialArn": "arn:aws:secretsmanager:aws-region:111122223333:secret:MySecret"
            }
        }
    }
}
```
<a name="fargate-linux-gmsa-credentialspec-create"></a>
**建立 CredSpec 並將其上傳至 Amazon S3**  
您可以在加入網域的 Windows 電腦上使用 CredSpec PowerShell 模組來建立 CredSpec。請依照 Microsoft Learn 網站上[建立憑證規格](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#create-a-credential-spec)中的步驟進行。

在建立憑證規格檔案之後，請將其上傳至 Amazon S3 儲存貯體。將 CredSpec 檔案複製至正在執行 AWS CLI 命令的電腦或環境中。

執行下列 AWS CLI 命令，將 CredSpec 上傳至 Amazon S3。將 `amzn-s3-demo-bucket` 取代為您的 Amazon S3 儲存貯體的名稱。您可以將檔案作為物件儲存在任何儲存貯體和位置，但必須在附加至任務執行角色的政策中允許存取該儲存貯體和位置。

對於 PowerShell，使用下列命令：

```
$ Write-S3Object -BucketName "amzn-s3-demo-bucket" -Key "ecs-domainless-gmsa-credspec" -File "gmsa-cred-spec.json"
```

下列 AWS CLI 命令使用 `sh`和相容 Shell 所使用的反斜線接續字元。

```
$ aws s3 cp gmsa-cred-spec.json \
s3://amzn-s3-demo-bucket/ecs-domainless-gmsa-credspec
```

# gMSA 使用 搭配無網域使用 Amazon ECS Windows 容器 AWS CLI
<a name="tutorial-gmsa-windows"></a>

以下教學課程示範如何建立一個執行 Windows 容器的 Amazon ECS 任務，此容器具有透過 AWS CLI存取 Active Directory 的憑證。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

**Topics**
+ [

## 先決條件
](#tutorial-gmsa-windows-prerequisites)
+ [

## 步驟 1：在 Active Directory Domain Services (AD DS) 上建立和設定 gMSA 帳戶
](#tutorial-gmsa-windows-step1)
+ [

## 步驟 2：將憑證上傳至 Secrets Manager
](#tutorial-gmsa-windows-step2)
+ [

## 步驟 3：修改您的 CredSpec JSON 以包含無網域 gMSA 資訊
](#tutorial-gmsa-windows-step3)
+ [

## 步驟 4：將 CredSpec 上傳至 Amazon S3
](#tutorial-gmsa-windows-step4)
+ [

## 步驟 5：(選用) 建立 Amazon ECS 叢集
](#tutorial-gmsa-windows-step5)
+ [

## 步驟 6：針對容器執行個體建立 IAM 角色
](#tutorial-gmsa-windows-step6)
+ [

## 步驟 7：建立自訂任務執行角色
](#tutorial-gmsa-windows-step7)
+ [

## 步驟 8：為 Amazon ECS Exec 建立任務角色
](#tutorial-gmsa-windows-step8)
+ [

## 步驟 9：註冊使用無網域 gMSA 的任務定義
](#tutorial-gmsa-windows-step9)
+ [

## 步驟 10：將 Windows 容器執行個體註冊至叢集
](#tutorial-gmsa-windows-step10)
+ [

## 步驟 11：驗證容器執行個體
](#tutorial-gmsa-windows-step11)
+ [

## 步驟 12：執行 Windows 任務
](#tutorial-gmsa-windows-step12)
+ [

## 步驟 13：驗證容器具有 gMSA 憑證
](#tutorial-gmsa-windows-step13)
+ [

## 步驟 14：清除
](#tutorial-gmsa-windows-step14)
+ [

## 偵錯 Windows 容器的 Amazon ECS 無網域 gMSA
](#tutorial-gmsa-windows-debugging)

## 先決條件
<a name="tutorial-gmsa-windows-prerequisites"></a>

本教學課程假設已完成下列先決條件：
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+  AWS CLI 已安裝並設定最新版本的 。如需安裝或升級 的詳細資訊 AWS CLI，請參閱[安裝 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
**注意**  
您可以使用雙堆疊服務端點，透過 IPv4 和 IPv6 AWS CLI從 、 SDKs 和 Amazon ECS API 與 Amazon ECS 互動。如需詳細資訊，請參閱[使用 Amazon ECS 雙堆疊端點](dual-stack-endpoint.md)。
+ 您可以使用您希望容器存取的資源來設定 Active Directory 網域。Amazon ECS 支援下列設定：
  +  Directory Service Active Directory. Directory Service 是在 Amazon EC2 上託管的 AWS 受管 Active Directory。如需詳細資訊，請參閱《 *AWS Directory Service 管理指南*》中的 [AWS Managed Microsoft AD 入門](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)。
  + 內部部署 Active Directory。您必須確認 Amazon ECS Linux 容器執行個體可以加入網域。如需詳細資訊，請參閱[AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect-network-to-amazon.html)。
+ 您擁有可以解析 Active Directory 網域的 VPC 和子網路。
+ 您可以選擇**無網域 gMSA** 或**將每個執行個體加入單一網域**。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

  然後，選擇 CredSpec 的資料儲存，也可以選擇無網域 gMSA 的 Active Directory 使用者憑證的資料儲存。

  Amazon ECS 使用 Active Directory 憑證規格檔案 (CredSpec)。此檔案包含用於將 gMSA 帳戶內容傳播至容器的 gMSA 中繼資料。您會產生 CredSpec 檔案，然後將其儲存在下表中特定於容器執行個體的作業系統的 CredSpec 儲存選項之一。若要使用無網域方法，CredSpec 檔案中的選擇性區段可以在下表中的 *domainless user credentials* 儲存選項之一中指定憑證 (特定於容器執行個體的作業系統)。    
<a name="gmsa-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonECS/latest/developerguide/tutorial-gmsa-windows.html)
+ （選用） AWS CloudShell 是一種工具，可為客戶提供命令列，而不需要建立自己的 EC2 執行個體。如需詳細資訊，請參閱*AWS CloudShell 《 使用者指南*》中的[什麼是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 步驟 1：在 Active Directory Domain Services (AD DS) 上建立和設定 gMSA 帳戶
<a name="tutorial-gmsa-windows-step1"></a>

在 Active Directory 網域上建立並設定 gMSA 帳戶。

**注意**  
此步驟會建立兩個不同的帳戶：為容器提供身分的群組受管服務帳戶 (gMSA)，以及用於網域身分驗證的一般使用者帳戶。這些帳戶的用途各不相同，因此應使用不同的名稱。

1. 

**產生金鑰分佈服務根金鑰**
**注意**  
如果您使用的是 Directory Service，則可以略過此步驟。

   KDS 根金鑰和 gMSA 許可是使用您 AWS 受管的 Microsoft AD 來設定。

   如果您尚未在網域中建立 gMSA 服務帳戶，則必須先產生金鑰分佈服務 (KDS) 根金鑰。KDS 負責建立、輪換和向授權主機發佈 gMSA 密碼。當 `ccg.exe` 需要擷取 gMSA 憑證時，將會聯絡 KDS 以擷取目前密碼。

   若要檢查是否已建立 KDS 根金鑰，請使用 `ActiveDirectory` PowerShell 模組，在網域控制器上以網域管理員權限執行下列 PowerShell cmdlet。如需有關此模組的詳細資訊，請參閱 Microsoft Learn 網站上的 [ActiveDirectory 模組](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps)。

   ```
   PS C:\> Get-KdsRootKey
   ```

   如果命令傳回金鑰 ID，您可以略過此步驟的其餘部分。否則，執行下列命令以建立 KDS 根金鑰：

   ```
   PS C:\> Add-KdsRootKey -EffectiveImmediately
   ```

   儘管命令的引數 `EffectiveImmediately` 意味著金鑰會立即生效，但您需要等待 10 小時才能複製 KDS 根金鑰並可在所有網域控制器上使用。

1. 

**建立 gMSA 帳戶**

   若要建立 gMSA 帳戶並允許 `ccg.exe` 擷取 gMSA 密碼，請從有權存取網域的 Windows 伺服器或用戶端執行下列 PowerShell 命令。將 `ExampleAccount` 取代為要用於 gMSA 帳戶的名稱，並將 `example-domain` 取代為 Active Directory 網域名稱 (例如：網域為 `contoso.com`，則使用 `contoso`)。

   1. 

      ```
      PS C:\> Install-WindowsFeature RSAT-AD-PowerShell
      ```

   1. 

      ```
      PS C:\> New-ADGroup -Name "ExampleAccount Authorized Hosts" -SamAccountName "ExampleAccountHosts" -GroupScope DomainLocal
      ```

   1. 

      ```
      PS C:\> New-ADServiceAccount -Name "ExampleAccount" -DnsHostName "example-domain" -ServicePrincipalNames "host/ExampleAccount", "host/example-domain" -PrincipalsAllowedToRetrieveManagedPassword "ExampleAccountHosts"
      ```

   1. 建立一個具有不會過期的永久密碼的使用者。這些登入資料會存放在 中， AWS Secrets Manager 並由每個任務用來加入網域。這是與前文建立的 gMSA 帳戶不同的使用者帳戶。將 `ExampleServiceUser` 取代為要用於該服務使用者帳戶的名稱。

      ```
      PS C:\> New-ADUser -Name "ExampleServiceUser" -AccountPassword (ConvertTo-SecureString -AsPlainText "Test123" -Force) -Enabled 1 -PasswordNeverExpires 1
      ```

   1. 

      ```
      PS C:\> Add-ADGroupMember -Identity "ExampleAccountHosts" -Members "ExampleServiceUser"
      ```

   1. 安裝用於在 Active Directory 中建立 CredSpec 物件的 PowerShell 模組並輸出 CredSpec JSON。

      ```
      PS C:\> Install-PackageProvider -Name NuGet -Force
      ```

      ```
      PS C:\> Install-Module CredentialSpec
      ```

   1. 

      ```
      PS C:\> New-CredentialSpec -AccountName ExampleAccount
      ```

1. 將上一個命令的 JSON 輸出複製到名為 `gmsa-cred-spec.json` 的檔案中。這是 CredSpec 檔案。其在步驟 3 [步驟 3：修改您的 CredSpec JSON 以包含無網域 gMSA 資訊](#tutorial-gmsa-windows-step3) 中使用。

## 步驟 2：將憑證上傳至 Secrets Manager
<a name="tutorial-gmsa-windows-step2"></a>

將 Active Directory 憑證複製至安全的憑證儲存系統中，以便每個任務都能擷取此憑證。這是無網域 gMSA 方法。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。
+ 執行下列 AWS CLI 命令並取代使用者名稱、密碼和網域名稱，以符合您的環境。使用服務使用者帳戶名稱 (而非 gMSA 帳戶名稱) 作為使用者名稱。預留密碼的 ARN 以在下一個步驟中使用，[步驟 3：修改您的 CredSpec JSON 以包含無網域 gMSA 資訊](#tutorial-gmsa-windows-step3)

  以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

  ```
  $ aws secretsmanager create-secret \
  --name gmsa-plugin-input \
  --description "Amazon ECS - gMSA Portable Identity." \
  --secret-string "{\"username\":\"ExampleServiceUser\",\"password\":\"Test123\",\"domainName\":\"contoso.com\"}"
  ```

## 步驟 3：修改您的 CredSpec JSON 以包含無網域 gMSA 資訊
<a name="tutorial-gmsa-windows-step3"></a>

在將 CredSpec 上傳至其中一個儲存選項之前，請使用上一個步驟中 Secrets Manager 中密碼的 ARN 將資訊新增至 CredSpec。如需詳細資訊，請參閱 Microsoft Learn 網站上的[未加入網域的容器主機使用案例的其他憑證規格組態](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#additional-credential-spec-configuration-for-non-domain-joined-container-host-use-case)。

1. 將下列資訊新增至 `ActiveDirectoryConfig` 內的 CredSpec 檔案。將 ARN 替換為上一個步驟 Secrets Manager 中的密碼。

   請注意，`PluginGUID` 值必須與下列範例程式碼片段中的 GUID 相符，且為必要值。

   ```
   "HostAccountConfig": {
         "PortableCcgVersion": "1",
         "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
         "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
   ```

   您也可以透過使用以下格式的 ARN，在 SSM 參數存放區中使用祕密：`\"arn:aws:ssm:aws-region:111122223333:parameter/gmsa-plugin-input\"`。

1. 修改 CredSpec 檔案之後，檔案應類似於以下範例：

   ```
   {
     "CmsPlugins": [
       "ActiveDirectory"
     ],
     "DomainJoinConfig": {
       "Sid": "S-1-5-21-4066351383-705263209-1606769140",
       "MachineAccountName": "ExampleAccount",
       "Guid": "ac822f13-583e-49f7-aa7b-284f9a8c97b6",
       "DnsTreeName": "example-domain",
       "DnsName": "example-domain",
       "NetBiosName": "example-domain"
     },
     "ActiveDirectoryConfig": {
       "GroupManagedServiceAccounts": [
         {
           "Name": "ExampleAccount",
           "Scope": "example-domain"
         },
         {
           "Name": "ExampleAccount",
           "Scope": "example-domain"
         }
       ],
       "HostAccountConfig": {
         "PortableCcgVersion": "1",
         "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
         "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
     }
   }
   ```

## 步驟 4：將 CredSpec 上傳至 Amazon S3
<a name="tutorial-gmsa-windows-step4"></a>



此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 將 CredSpec 檔案複製至正在執行 AWS CLI 命令的電腦或環境中。

1. 執行下列 AWS CLI 命令，將 CredSpec 上傳至 Amazon S3。將 `MyBucket` 取代為您的 Amazon S3 儲存貯體的名稱。您可以將檔案作為物件儲存在任何儲存貯體和位置，但必須在附加至任務執行角色的政策中允許存取該儲存貯體和位置。

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws s3 cp gmsa-cred-spec.json \
   s3://MyBucket/ecs-domainless-gmsa-credspec
   ```

## 步驟 5：(選用) 建立 Amazon ECS 叢集
<a name="tutorial-gmsa-windows-step5"></a>

預設情況下，您的帳戶會有一個名為 `default` 的 Amazon ECS 叢集。根據預設 AWS CLI，此叢集用於 、 SDKs和 CloudFormation。您可以使用其他叢集來分組和組織任務和基礎結構，並為某些組態指派預設值。

您可以從 AWS 管理主控台、 AWS CLI SDKs或 建立叢集 CloudFormation。叢集中的設定和組態不會影響 gMSA。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

```
$ aws ecs create-cluster --cluster-name windows-domainless-gmsa-cluster
```

**重要**  
如果您選擇建立自己的叢集，您必須在打算對該叢集使用的每個命令中指定 `--cluster clusterName`。

## 步驟 6：針對容器執行個體建立 IAM 角色
<a name="tutorial-gmsa-windows-step6"></a>

*容器執行個體*是在 ECS 任務中執行容器的主機電腦，例如 Amazon EC2 執行個體。每個容器執行個體都會註冊至 Amazon ECS 叢集。在您啟動 Amazon EC2 執行個體並將其註冊到叢集之前，您必須先為要使用的容器執行個體建立 IAM 角色。

若要建立容器執行個體角色，請參閱 [Amazon ECS 容器執行個體 IAM 角色](instance_IAM_role.md)。預設值 `ecsInstanceRole` 具有足夠的許可來完成此教學課程。

## 步驟 7：建立自訂任務執行角色
<a name="tutorial-gmsa-windows-step7"></a>

Amazon ECS 可針對啟動每個任務所需的許可使用不同的 IAM 角色，而不是容器執行個體角色。此角色是*任務執行角色*。我們建議您建立僅具有 ECS 執行任務所需許可的任務執行角色，也稱為*最低權限許可*。如需有關最低權限原則的詳細資訊，請參閱《AWS Well-Architected 的架構》**中的 [SEC03-BP02 授予最低權限存取權](https://docs.aws.amazon.com/wellarchitected/latest/framework/sec_permissions_least_privileges.html)。

1. 若要建立任務執行角色，請參閱 [建立任務執行角色](task_execution_IAM_role.md#create-task-execution-role)。預設許可允許容器執行個體從 Amazon Elastic Container Registry 中提取容器映像，並從應用程式中提取 `stdout` 和 `stderr` 並記錄到 Amazon CloudWatch Logs 中。

   由於角色需要本教學課程的自訂許可，因此您可以為該角色指定與 `ecsTaskExecutionRole` 不同的名稱。本教學課程將在後續步驟中使用 `ecsTaskExecutionRole`。

1. 建立自訂原則 (僅存在於此角色的內嵌政策或可重複使用的政策)，以新增下列許可。將第一個陳述式中 `Resource` 的 ARN 替換為 Amazon S3 儲存貯體和位置，並將第二個 `Resource` 替換為 Secrets Manager 中密碼的 ARN。

   如果您使用自訂金鑰在 Secrets Manager 中加密密碼，則也必須允許金鑰使用 `kms:Decrypt`。

   如果您使用 SSM 參數存放區而不是 Secrets Manager，您必須允許參數使用 `ssm:GetParameter`，而不是 `secretsmanager:GetSecretValue`。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::MyBucket/ecs-domainless-gmsa-credspec/gmsa-cred-spec.json"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:gmsa-plugin-AbCdEf"
           }
       ]
   }
   ```

------

## 步驟 8：為 Amazon ECS Exec 建立任務角色
<a name="tutorial-gmsa-windows-step8"></a>

本教學課程使用 Amazon ECS Exec，透過在執行中的任務內執行命令來驗證功能。若要使用 ECS Exec，服務或任務必須開啟 ECS Exec，且任務角色 (但不是任務執行角色) 必須具有 `ssmmessages` 許可。如需了解所需的 IAM 政策，請參閱[ECS Exec 許可](task-iam-roles.md#ecs-exec-required-iam-permissions)。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

若要使用 建立任務角色 AWS CLI，請遵循下列步驟。

1. 建立稱為 `ecs-tasks-trust-policy.json` 的檔案，其中具有以下內容：

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "ecs-tasks.amazonaws.com"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. 建立 IAM 角色。您可以替換名稱 `ecs-exec-demo-task-role`，但預留以下步驟的名稱。

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws iam create-role --role-name ecs-exec-demo-task-role \
   --assume-role-policy-document file://ecs-tasks-trust-policy.json
   ```

   您可以刪除檔案 `ecs-tasks-trust-policy.json`。

1. 建立稱為 `ecs-exec-demo-task-role-policy.json` 的檔案，其中具有以下內容：

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ssmmessages:CreateControlChannel",
                   "ssmmessages:CreateDataChannel",
                   "ssmmessages:OpenControlChannel",
                   "ssmmessages:OpenDataChannel"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 建立 IAM 政策並將其附加至上一個步驟中的角色。

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws iam put-role-policy \
       --role-name ecs-exec-demo-task-role \
       --policy-name ecs-exec-demo-task-role-policy \
       --policy-document file://ecs-exec-demo-task-role-policy.json
   ```

   您可以刪除檔案 `ecs-exec-demo-task-role-policy.json`。

## 步驟 9：註冊使用無網域 gMSA 的任務定義
<a name="tutorial-gmsa-windows-step9"></a>



此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 建立稱為 `windows-gmsa-domainless-task-def.json` 的檔案，其中具有以下內容：

   ```
   {
     "family": "windows-gmsa-domainless-task",
     "containerDefinitions": [
       {
         "name": "windows_sample_app",
         "image": "mcr.microsoft.com/windows/servercore/iis",
         "cpu": 1024,
         "memory": 1024,
         "essential": true,
         "credentialSpecs": [
                   "credentialspecdomainless:arn:aws:s3:::ecs-domainless-gmsa-credspec/gmsa-cred-spec.json"
         ],
         "entryPoint": [
           "powershell",
           "-Command"
         ],
         "command": [
           "New-Item -Path C:\\inetpub\\wwwroot\\index.html -ItemType file -Value '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p>' -Force ; C:\\ServiceMonitor.exe w3svc"
         ],
         "portMappings": [
           {
             "protocol": "tcp",
             "containerPort": 80,
             "hostPort": 8080
           }
         ]
       }
     ],
     "taskRoleArn": "arn:aws:iam::111122223333:role/ecs-exec-demo-task-role",
     "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole"
   }
   ```

1. 執行下列命令來註冊任務定義：

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws ecs register-task-definition \
   --cli-input-json file://windows-gmsa-domainless-task-def.json
   ```

## 步驟 10：將 Windows 容器執行個體註冊至叢集
<a name="tutorial-gmsa-windows-step10"></a>

啟動 Amazon EC2 Windows 執行個體並執行 ECS 容器代理程式，以將其註冊為叢集中的容器執行個體。ECS 會在已註冊至叢集 (任務在其中啟動) 的容器執行個體上執行任務。

1. 若要啟動在 中為 Amazon ECS 設定的 Amazon EC2 Windows 執行個體 AWS 管理主控台，請參閱 [啟動 Amazon ECS Windows 容器執行個體](launch_window-container_instance.md)。在*使用者資料*的步驟停止。

1. 若為 gMSA，使用者資料必須先設定環境變數 `ECS_GMSA_SUPPORTED`，才能啟動 ECS 容器代理程式。

   對於 ECS Exec，代理程式必須以引數 `-EnableTaskIAMRole` 開頭。

   若要防止任務到達 EC2 IMDS Web 服務以擷取角色憑證，以保護執行個體 IAM 角色，請新增引數 `-AwsvpcBlockIMDS`。這只適用於使用 `awsvpc` 網路模式的任務。

   ```
   <powershell>
   [Environment]::SetEnvironmentVariable("ECS_GMSA_SUPPORTED", $TRUE, "Machine")
   Import-Module ECSTools
   Initialize-ECSAgent -Cluster windows-domainless-gmsa-cluster -EnableTaskIAMRole -AwsvpcBlockIMDS
   </powershell>
   ```

1. 檢閱 **Summary** (摘要) 面板中執行個體組態的摘要，並在準備就緒時選擇 **Launch instance** (啟動執行個體)。

## 步驟 11：驗證容器執行個體
<a name="tutorial-gmsa-windows-step11"></a>

您可以使用 AWS 管理主控台驗證叢集中是否存在容器執行個體。但是，gMSA 需要指示為*屬性*的其他功能。這些屬性不會顯示在 中 AWS 管理主控台，因此本教學課程會使用 AWS CLI。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 列出叢集中的容器執行個體。容器執行個體的 ID 與 EC2 執行個體的 ID 不同。

   ```
   $ aws ecs list-container-instances
   ```

   輸出：

   ```
   {
       "containerInstanceArns": [
           "arn:aws:ecs:aws-region:111122223333:container-instance/default/MyContainerInstanceID"
       ]
   }
   ```

   例如，`526bd5d0ced448a788768334e79010fd` 是有效的容器執行個體 ID。

1. 使用上一個步驟中的容器執行個體 ID 來取得容器執行個體的詳細資訊。使用 ID 取代 `MyContainerInstanceID`。

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws ecs describe-container-instances \
        ----container-instances MyContainerInstanceID
   ```

   請注意，輸出內容非常長。

1. 驗證 `attributes` 清單中是否存在一個索引鍵為 `name` 且值為 `ecs.capability.gmsa-domainless` 的物件。下列為物件的範例。

   輸出：

   ```
   {
       "name": "ecs.capability.gmsa-domainless"
   }
   ```

## 步驟 12：執行 Windows 任務
<a name="tutorial-gmsa-windows-step12"></a>

執行 Amazon ECS 任務。如果叢集中只有 1 個容器執行個體，您可以使用 `run-task`。如果有許多不同的容器執行個體，則相較於將置放條件限制新增至任務定義，以控制要執行此任務的容器執行個體類型，使用 `start-task` 並指定要在其上執行任務的容器執行個體 ID 可能會更為容易。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   aws ecs run-task --task-definition windows-gmsa-domainless-task \
       --enable-execute-command --cluster windows-domainless-gmsa-cluster
   ```

   請注意，任務 ID 是由命令傳回。

1. 執行下列命令，以驗證任務已開始。這個命令會等待，直到任務開始時才傳回 Shell 提示字元。使用前一步驟中的任務 ID，取代 `MyTaskID`。

   ```
   $ aws ecs wait tasks-running --task MyTaskID
   ```

## 步驟 13：驗證容器具有 gMSA 憑證
<a name="tutorial-gmsa-windows-step13"></a>

驗證任務中的容器具有 Kerberos 權杖。gMSA

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws ecs execute-command \
   --task MyTaskID \
   --container windows_sample_app \
   --interactive \
   --command powershell.exe
   ```

   輸出將是 PowerShell 提示字元。

1. 在容器內的 PowerShell 終端中執行以下命令。

   ```
   PS C:\> klist get ExampleAccount$
   ```

   在輸出中，請注意 `Principal` 是您先前所建立的項目。

## 步驟 14：清除
<a name="tutorial-gmsa-windows-step14"></a>

完成此教學課程時，建議您清除相關聯的資源，以免未使用的資源產生費用。

此步驟使用 AWS CLI。您可以在預設 Shell (即 `bash`) 的 AWS CloudShell 中執行這些命令。

1. 停止任務。使用步驟 12 中的任務 ID [步驟 12：執行 Windows 任務](#tutorial-gmsa-windows-step12) 取代 `MyTaskID`。

   ```
   $ aws ecs stop-task --task MyTaskID
   ```

1. 終止 Amazon EC2 執行個體。之後，叢集中的容器執行個體將會在一小時後自動刪除。

   您可以使用 Amazon EC2 主控台來尋找和終止執行個體。或者，您可以執行下列命令。若要執行命令，請在步驟 1 [步驟 11：驗證容器執行個體](#tutorial-gmsa-windows-step11) 的 `aws ecs describe-container-instances` 命令輸出中尋找 EC2 執行個體識別碼。i-10a64379 是 EC2 執行個體 ID 的範例。

   ```
   $ aws ec2 terminate-instances --instance-ids MyInstanceID
   ```

1. 刪除 Amazon S3 中的 CredSpec 檔案。將 `MyBucket` 取代為您的 Amazon S3 儲存貯體的名稱。

   ```
   $ aws s3api delete-object --bucket MyBucket --key ecs-domainless-gmsa-credspec/gmsa-cred-spec.json
   ```

1. 從 Secrets Manager 中刪除密碼。如果您改用 SSM 參數存放區，請刪除參數。

   以下命令使用由 `sh` 和相容 shell 所使用的反斜線接續字元。此命令與 PowerShell 不相容。您必須修改命令才能將其與 PowerShell 搭配使用。

   ```
   $ aws secretsmanager delete-secret --secret-id gmsa-plugin-input \
        --force-delete-without-recovery
   ```

1. 取消註冊並刪除任務定義。透過取消註冊任務定義，您可以將其標記為非作用中狀態，以便無法用於啟動新任務。然後，您可以刪除任務定義。

   1. 透過指定版本取消註冊任務定義。ECS 會自動建立任務定義的版本，編號從 1 開始。您引用的版本與容器映像上的標籤格式相同，例如 `:1`。

      ```
      $ aws ecs deregister-task-definition --task-definition windows-gmsa-domainless-task:1
      ```

   1. 刪除任務定義。

      ```
      $ aws ecs delete-task-definitions --task-definition windows-gmsa-domainless-task:1
      ```

1. (選用) 如果您已建立叢集，請刪除 ECS 叢集。

   ```
   $ aws ecs delete-cluster --cluster windows-domainless-gmsa-cluster
   ```

## 偵錯 Windows 容器的 Amazon ECS 無網域 gMSA
<a name="tutorial-gmsa-windows-debugging"></a>



Amazon ECS 任務狀態  
ECS 會嘗試僅啟動一次任務。任何有問題的任務均會停止，並設定為狀態 `STOPPED`。任務有兩種常見的問題類型。首先是無法啟動的任務。其次是應用程式已在容器之一內停止的任務。在 中 AWS 管理主控台，查看任務的**停止原因**欄位，了解任務停止的原因。在 AWS CLI中，描述任務並查看 `stoppedReason`。如需 AWS 管理主控台 和 中的步驟 AWS CLI，請參閱 [檢視 Amazon ECS 已停止任務錯誤](stopped-task-errors.md)。

Windows 事件  
容器中 gMSA 的 Windows 事件記錄在 `Microsoft-Windows-Containers-CCG` 日誌中，您可以在 `Logs\Microsoft\Windows\Containers-CCG\Admin`「應用程式和服務」區段的「事件檢視器」中找到。如需詳細的偵錯提示，請參閱 Microsoft Learn 網站上的 [ Windows 容器 gMSA 故障排除](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/gmsa-troubleshooting#non-domain-joined-container-hosts-use-event-logs-to-identify-configuration-issues)。

ECS 代理程式 gMSA 外掛程式  
Windows 容器執行個體上 ECS 代理程式的 gMSA 外掛程式記錄位於下列目錄 `C:/ProgramData/Amazon/gmsa-plugin/` 中。查看此日誌，查看是否已從儲存位置 (例如 Secrets Manager) 下載無網域使用者憑證，以及是否正確讀取憑證格式。

# 了解如何在 Amazon ECS 上為 EC2 Windows 容器使用 gMSA
<a name="windows-gmsa"></a>

Amazon ECS 透過名為*群組受管服務帳戶* (gMSA) 的特殊類型的服務帳戶，支援對 Windows 容器的 Active Directory 身分驗證。

.NET 應用程式之類的以 Windows 為基礎的網路應用程式通常會使用 Active Directory 來促進使用者和服務之間的身分驗證和授權管理。開發人員通常會針對此目的設計其應用程式，以與 Active Directory 整合，並在已加入網域的伺服器上執行。由於以 Windows 為基礎的容器無法加入網域，因此您必須將 Windows 容器設定為與 gMSA 搭配執行。

使用 gMSA 執行的 Windows 容器依賴其主機 Amazon EC2 執行個體，以從 Active Directory 網域控制站擷取 gMSA 登入資料，並將這些資料提供給容器執行個體。如需詳細資訊，請參閱 [為 Windows 容器建立 gMSA](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts)。

**注意**  
Fargate 上的 Windows 容器不支援此功能。

**Topics**
+ [

## 考量事項
](#windows-gmsa-considerations)
+ [

## 先決條件
](#windows-gmsa-prerequisites)
+ [

## 在 Amazon ECS 上設定 Windows 容器的 gMSA
](#windows-gmsa-setup)

## 考量事項
<a name="windows-gmsa-considerations"></a>

針對 Windows 容器使用 gMSA 時，應考慮下列事項：
+ 針對您的容器執行個體使用 Amazon ECS 最佳化 Windows Server 2016 Full AMI 時，容器主機名稱必須與登入資料規格檔案中定義的 gMSA 帳戶名稱相同。若要指定容器的主機名稱，請使用 `hostname` 容器定義參數。如需詳細資訊，請參閱[網路設定](task_definition_parameters.md#container_definition_network)。
+ 您可以選擇**無網域 gMSA** 或**將每個執行個體加入單一網域**。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

  然後，選擇 CredSpec 的資料儲存，也可以選擇無網域 gMSA 的 Active Directory 使用者憑證的資料儲存。

  Amazon ECS 使用 Active Directory 憑證規格檔案 (CredSpec)。此檔案包含用於將 gMSA 帳戶內容傳播至容器的 gMSA 中繼資料。您會產生 CredSpec 檔案，然後將其儲存在下表中特定於容器執行個體的作業系統的 CredSpec 儲存選項之一。若要使用無網域方法，CredSpec 檔案中的選擇性區段可以在下表中的 *domainless user credentials* 儲存選項之一中指定憑證 (特定於容器執行個體的作業系統)。    
<a name="gmsa-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonECS/latest/developerguide/windows-gmsa.html)

## 先決條件
<a name="windows-gmsa-prerequisites"></a>

在搭配 Amazon ECS 使用 Windows 容器功能適用的 gMSA 之前，請先完成下列各項：
+ 您可以使用您希望容器存取的資源來設定 Active Directory 網域。Amazon ECS 支援下列設定：
  +  Directory Service Active Directory. Directory Service 是在 Amazon EC2 上託管的 AWS 受管 Active Directory。如需詳細資訊，請參閱《 *AWS Directory Service 管理指南*》中的 [AWS Managed Microsoft AD 入門](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)。
  + 內部部署 Active Directory。您必須確認 Amazon ECS Linux 容器執行個體可以加入網域。如需詳細資訊，請參閱[AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect-network-to-amazon.html)。
+ 您在 Active Directory 中擁有現有的 gMSA 帳戶。如需詳細資訊，請參閱 [為 Windows 容器建立 gMSA](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts)。
+ **您已選擇使用*無網域 gMSA* 或託管 Amazon ECS 任務的 Amazon ECS Windows 容器執行個體必須是加入 *Active Directory 的網域*，並且是具有 gMSA 帳戶存取權的 Active Directory 安全群組成員。**

  使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。
+ 您已新增必要的 IAM 許可 所需的許可取決於您為初始憑證選擇的方法以及儲存憑證規格的方法：
  + 如果您使用*無網域gMSA*做為初始登入資料，Amazon EC2 執行個體角色 AWS Secrets Manager 需要 的 IAM 許可。
  + 如果您將憑證規格存放在 SSM 參數存放區中，則任務執行角色需要 Amazon EC2 Systems Manager 參數存放區的 IAM 許可。
  + 如果您將憑證規格存放在 Amazon S3 中，則任務執行角色需要 Amazon Simple Storage Service 的 IAM 許可。

## 在 Amazon ECS 上設定 Windows 容器的 gMSA
<a name="windows-gmsa-setup"></a>

若要在 Amazon ECS 上設定 Windows 容器的 gMSA，您可以遵循包含設定先決條件 [gMSA 使用 搭配無網域使用 Amazon ECS Windows 容器 AWS CLI](tutorial-gmsa-windows.md) 的完整教學課程。

以下章節詳細介紹了 CredSpec 組態。

**Topics**
+ [

### 範例 CredSpec
](#windows-gmsa-example)
+ [

### 無網域 gMSA 設定
](#windows-gmsa-domainless)
+ [

### 在任務定義中參考登入資料規格檔案
](#windows-gmsa-credentialspec)

### 範例 CredSpec
<a name="windows-gmsa-example"></a>

Amazon ECS 使用憑證規格檔案，其中包含將 gMSA 帳戶內容傳播到 Windows 容器所用的 gMSA 中繼資料。您可以產生登入資料規格檔案，並在任務定義的 `credentialSpec` 欄位中參考該檔案。登入資料規格檔案不包含任何秘密。

以下是範例登入資料規格檔案：

```
{
    "CmsPlugins": [
        "ActiveDirectory"
    ],
    "DomainJoinConfig": {
        "Sid": "S-1-5-21-2554468230-2647958158-2204241789",
        "MachineAccountName": "WebApp01",
        "Guid": "8665abd4-e947-4dd0-9a51-f8254943c90b",
        "DnsTreeName": "contoso.com",
        "DnsName": "contoso.com",
        "NetBiosName": "contoso"
    },
    "ActiveDirectoryConfig": {
        "GroupManagedServiceAccounts": [
            {
                "Name": "WebApp01",
                "Scope": "contoso.com"
            }
        ]
    }
}
```

### 無網域 gMSA 設定
<a name="windows-gmsa-domainless"></a>

我們建議使用無網域 gMSA，而不是將容器執行個體加入至單一網域。使用無網域 gMSA 時，容器執行個體不會加入網域，執行個體上的其他應用程式無法使用憑證來存取網域，而加入不同網域的任務則可在相同的執行個體上執行。

1. 在將 CredSpec 上傳至其中一個儲存選項之前，請使用 Secrets Manager 或 SSM 參數存放區中祕密的 ARN 將資訊新增 CredSpec。如需詳細資訊，請參閱 Microsoft Learn 網站上的[未加入網域的容器主機使用案例的其他憑證規格組態](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#additional-credential-spec-configuration-for-non-domain-joined-container-host-use-case)。

**無網域 gMSA 憑證格式**  
以下是您 Active Directory 的無網域 gMSA 憑證的 JSON 格式。將憑證儲存在 Secrets Manager 或 SSM 參數存放區中。

   ```
   {
       "username":"WebApp01",
       "password":"Test123!",
       "domainName":"contoso.com"
   }
   ```

1. 將下列資訊新增至 `ActiveDirectoryConfig` 內的 CredSpec 檔案。將 ARN 替代為 Secrets Manager 或 SSM 參數存放區中的祕密。

   請注意，`PluginGUID` 值必須與下列範例程式碼片段中的 GUID 相符，且為必要值。

   ```
       "HostAccountConfig": {
           "PortableCcgVersion": "1",
           "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
           "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
   ```

   您也可以透過使用以下格式的 ARN，在 SSM 參數存放區中使用祕密：`\"arn:aws:ssm:aws-region:111122223333:parameter/gmsa-plugin-input\"`。

1. 修改 CredSpec 檔案之後，檔案應類似於以下範例：

   ```
   {
     "CmsPlugins": [
       "ActiveDirectory"
     ],
     "DomainJoinConfig": {
       "Sid": "S-1-5-21-4066351383-705263209-1606769140",
       "MachineAccountName": "WebApp01",
       "Guid": "ac822f13-583e-49f7-aa7b-284f9a8c97b6",
       "DnsTreeName": "contoso",
       "DnsName": "contoso",
       "NetBiosName": "contoso"
     },
     "ActiveDirectoryConfig": {
       "GroupManagedServiceAccounts": [
         {
           "Name": "WebApp01",
           "Scope": "contoso"
         },
         {
           "Name": "WebApp01",
           "Scope": "contoso"
         }
       ],
       "HostAccountConfig": {
         "PortableCcgVersion": "1",
         "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
         "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
     }
   }
   ```

### 在任務定義中參考登入資料規格檔案
<a name="windows-gmsa-credentialspec"></a>

Amazon ECS 支援以下方法，在任務定義的 `credentialSpecs` 欄位中參考檔案路徑。根據您是將容器執行個體加入單一網域，還是分別使用無網域 gMSA，您都可以針對這些選項提供 `credentialspec:` 或 `domainlesscredentialspec:`。

#### Amazon S3 儲存貯體
<a name="gmsa-credspec-s3"></a>

將憑證規格新增到 Amazon S3 儲存貯體，然後在任務定義的 `credentialSpecs` 欄位中參考 Amazon S3 儲存貯體的 Amazon Resource Name (ARN)。

```
{
    "family": "",
    "executionRoleArn": "",
    "containerDefinitions": [
        {
            "name": "",
            ...
            "credentialSpecs": [
                "credentialspecdomainless:arn:aws:s3:::${BucketName}/${ObjectName}"
            ],
            ...
        }
    ],
    ...
}
```

您也必須新增下列許可做為 Amazon ECS 任務執行 IAM 角色的內嵌政策，讓任務能夠存取 Amazon S3 儲存貯體。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor",
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::{bucket_name}",
                "arn:aws:s3:::{bucket_name}/{object}"
            ]
        }
    ]
}
```

------

#### SSM 參數存放區參數
<a name="gmsa-credspec-ssm"></a>

將憑證規格新增至 SSM 參數存放區參數，然後在任務定義的 `credentialSpecs` 欄位中參考 SSM 參數存放區參數的 Amazon Resource Name (ARN)。

```
{
    "family": "",
    "executionRoleArn": "",
    "containerDefinitions": [
        {
            "name": "",
            ...
            "credentialSpecs": [
                "credentialspecdomainless:arn:aws:ssm:region:111122223333:parameter/parameter_name"
            ],
            ...
        }
    ],
    ...
}
```

您也必須新增下列許可做為 Amazon ECS 任務執行 IAM 角色的內嵌政策，讓任務能夠存取 SSM 參數存放區參數。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameters"
            ],
            "Resource": "arn:aws:ssm:*:111122223333:parameter/example*"
        }
    ]
}
```

------

#### 本機檔案
<a name="gmsa-credspec-file"></a>

使用本機檔案中的登入資料規格詳細資訊，在任務定義的 `credentialSpecs` 欄位中參考檔案路徑。參照的檔案路徑必須相對於 `C:\ProgramData\Docker\CredentialSpecs` 目錄，並使用反斜線 (「\$1」) 作為檔案路徑分隔符號。

```
{
    "family": "",
    "executionRoleArn": "",
    "containerDefinitions": [
        {
            "name": "",
            ...
            "credentialSpecs": [
                "credentialspec:file://CredentialSpecDir\CredentialSpecFile.json"
            ],
            ...
        }
    ],
    ...
}
```

# 透過 EC2 Image Builder 建置自訂的 Amazon ECS 最佳化 AMI
<a name="image-builder-tutorial"></a>

AWS 建議您使用 Amazon ECS 最佳化 AMIs因為它們已預先設定執行容器工作負載的需求和建議。在某些情況下，您可能需要自訂 AMI 來新增額外軟體。您可以透過 EC2 Image Builder 來建立、管理與部署伺服器映像。您將保留帳戶中所建立自訂映像的所有權。您可透過 EC2 Image Builder 管道，自動化執行映像的更新與系統修補作業；也可以使用獨立命令，建立包含所定義組態資源的映像。

您需要為映像建立一份配方。該配方包含父映像以及任何額外元件。您也需要建立一個用於分發自訂 AMI 的管道。

您需要為映像建立一份配方。Image Builder 映像配方是一個文件，用於定義基礎映像與要套用至基礎映像的元件，以便產生輸出 AMI 映像所需的組態。您也需要建立一個用於分發自訂 AMI 的管道。如需詳細資訊，請參閱 *EC2 Image Builder User Guide* 中的 [How EC2 Image Builder works](https://docs.aws.amazon.com/imagebuilder/latest/userguide/how-image-builder-works.html)。

建議使用下列任一 Amazon ECS 最佳化 AMI 作為 EC2 Image Builder 中的「父映像」：
+ Linux
  + Amazon ECS 最佳化 AL2023 x86
  + Amazon ECS 最佳化 Amazon Linux 2023 (arm64) AMI
  + Amazon ECS 最佳化 Amazon Linux 2 核心 5 AMI
  + Amazon ECS 最佳化 Amazon Linux 2 x86 AMI
+ Windows
  + Amazon ECS 最佳化 Windows 2022 Full x86
  + Amazon ECS 最佳化 Windows 2022 Core x86
  + Amazon ECS 最佳化 Windows 2019 Full x86
  + Amazon ECS 最佳化 Windows 2019 Core x86
  + Amazon ECS 最佳化 Windows 2016 Full x86

我們也建議選取「使用最新可用的作業系統版本」。該管道將對父映像採用語意版本控制，此舉有助於在自動排程任務中偵測相依性更新。如需詳細資訊，請參閱 *EC2 Image Builder User Guide* 中的 [Semantic versioning](https://docs.aws.amazon.com/imagebuilder/latest/userguide/ibhow-semantic-versioning.html)。

AWS 會使用安全性修補程式和新的容器代理程式版本定期更新 Amazon ECS 最佳化 AMI 映像。在映像配方中使用 AMI ID 作為父映像時，需定期檢查是否有父映像的更新。若有更新，必須使用更新後的 AMI 建立新的配方版本。此舉可確保自訂映像包含最新版本的父映像。如需有關如何建立工作流程來使用新建立的 AMI 自動更新 Amazon ECS 叢集中 EC2 執行個體的資訊，請參閱 [How to create an AMI hardening pipeline and automate updates to your ECS instance fleet](https://aws.amazon.com/blogs/security/how-to-create-an-ami-hardening-pipeline-and-automate-updates-to-your-ecs-instance-fleet/)。

您也可以指定透過受管 EC2 Image Builder 管道發布之父映像的 Amazon Resource Name (ARN)。Amazon 會透過受管管道，定期發布 Amazon ECS 最佳化 AMI 映像。這些映像可公開存取。您必須具備正確的許可，才能存取映像。在 Image Builder 配方中使用映像 ARN 而非 AMI 時，管道會在每次執行時自動使用最新版本的父映像。此方法可免除每次更新時手動建立新配方版本的需求。

## 清理 Amazon ECS 最佳化 AMI
<a name="cleanup-ecs-optimized-ami"></a>

使用 Amazon ECS 最佳化 AMI 作為父映像時，必須清理該映像，以防止暫時性問題。Amazon ECS 最佳化 AMI 已預先設定，可讓 Amazon ECS 代理程式自動啟動，並作為容器執行個體向 Amazon ECS 註冊。若未適當清理就將其用作基礎映像，可能會導致自訂 AMI 出現問題。

若要清理該映像以供日後使用，請建立執行下列命令的元件，停止 ECS-init 套件和 Docker 程序：

```
sudo systemctl stop ecs
sudo systemctl stop docker
```

從目前的執行個體中移除所有日誌檔案，避免在儲存映像時預留這些檔案。使用 [Security best practices for EC2 Image Builder](https://docs.aws.amazon.com/imagebuilder/latest/userguide/security-best-practices.html) 中的範例指令碼，從執行個體清理各種檔案。

若要清理 Amazon ECS 特定資料，請執行下列命令：

```
sudo rm -rf /var/log/ecs/*
sudo rm /var/lib/ecs/data/agent.db
```

如需建立自訂 Amazon ECS 最佳化 AMIs 的詳細資訊，請參閱 AWS 知識中心的[如何從 Amazon ECS 最佳化 AMI 建立自訂 AMI？](https://forums.aws.amazon.com/knowledge-center/ecs-create-custom-amis/)。

## 在基礎結構即程式碼 (IaC) 中使用映像 ARN
<a name="infrastructure-as-code-arn"></a>

您可以使用 EC2 Image Builder 主控台或基礎設施做為程式碼 （例如 CloudFormation) 或 AWS SDK 來設定配方。當您在配方中指定父系映像時，您可以指定 EC2 AMI ID、映像建置器映像 ARN、 AWS Marketplace 產品 ID 或容器映像。 AWS 會公開發佈 Amazon ECS 最佳化 AMI 的 AMI IDs 和映像建置器映像 AMIs ARNs。映像 ARN 的格式如下：

```
arn:${Partition}:imagebuilder:${Region}:${Account}:image/${ImageName}/${ImageVersion}
```

`ImageVersion` 採用下列格式。將 *major*、*minor* 與 *patch* 分別取代為最新值。

```
<major>.<minor>.<patch>
```

您可以將 `major`、`minor` 與 `patch` 取代為特定值，也可以使用映像的無版本 ARN，如此一來，管道就能總是與父映像的最新版本保持同步。無版本 ARN 使用萬用字元格式 ‘x.x.x’ 來表示映像版本。此方法可讓 Image Builder 服務自動解析至映像的最新版本。使用無版本 ARN 可確保參考一律指向可用的最新映像，簡化在部署中維護最新映像的程序。透過主控台建立配方時，EC2 Image Builder 會自動識別父映像的 ARN。透過基礎結構即程式碼 (IaC) 建立配方時，必須自行識別 ARN，並選取所需的映像版本，或使用無版本 ARN 指定可用的最新映像。建議您建立自動化指令碼來篩選並僅顯示符合條件的映像。下列 Python 指令碼示範如何擷取 Amazon ECS 最佳化 AMI 的清單。

指令碼接受兩個選用引數：`owner` 與 `platform`，預設值分別為 "Amazon" 與 "Windows"。owner 引數的有效值包括：`Self`、`Amazon`、`Shared` 與 `ThirdParty`。platform 引數的有效值為 `Windows` 與 `Linux`。例如，若執行指令碼時，將 `owner` 引數設定為 `Amazon`、`platform` 引數設定為 `Linux`，該指令碼會產生一份由 Amazon 發布的映像清單，內含 Amazon ECS 最佳化映像。

```
import boto3
import argparse

def list_images(owner, platform):
    # Create a Boto3 session
    session = boto3.Session()
    
    # Create an EC2 Image Builder client
    client = session.client('imagebuilder')

    # Define the initial request parameters
    request_params = {
        'owner': owner,
        'filters': [
            {
                'name': 'platform',
                'values': [platform]
            }
        ]
    }

    # Initialize the results list
    all_images = []

    # Get the initial response with the first page of results
    response = client.list_images(**request_params)

    # Extract images from the response
    all_images.extend(response['imageVersionList'])

    # While 'nextToken' is present, continue paginating
    while 'nextToken' in response and response['nextToken']:
        # Update the token for the next request
        request_params['nextToken'] = response['nextToken']

        # Get the next page of results
        response = client.list_images(**request_params)

        # Extract images from the response
        all_images.extend(response['imageVersionList'])

    return all_images

def main():
    # Initialize the parser
    parser = argparse.ArgumentParser(description="List AWS images based on owner and platform")
    
    # Add the parameters/arguments
    parser.add_argument("--owner", default="Amazon", help="The owner of the images. Default is 'Amazon'.")
    parser.add_argument("--platform", default="Windows", help="The platform type of the images. Default is 'Windows'.")

    # Parse the arguments
    args = parser.parse_args()

    # Retrieve all images based on the provided owner and platform
    images = list_images(args.owner, args.platform)

    # Print the details of the images
    for image in images:
        print(f"Name: {image['name']}, Version: {image['version']}, ARN: {image['arn']}")

if __name__ == "__main__":
    main()
```

## 搭配 使用映像 ARN CloudFormation
<a name="arn-with-cloudformation"></a>

Image Builder 映像配方是一份藍圖，其中指定了實現輸出映像的目標組態所需的父映像與元件。您需要使用 `AWS::ImageBuilder::ImageRecipe` 資源。將 `ParentImage` 值設定為映像 ARN。請使用目標映像的無版本 ARN，確保管道一律使用最新版本的映像。例如 `arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x`。下列 `AWS::ImageBuilder::ImageRecipe` 資源定義使用 Amazon 受管映像 ARN：

```
ECSRecipe:
    Type: AWS::ImageBuilder::ImageRecipe
    Properties:
      Name: MyRecipe
      Version: '1.0.0'
      Components:
        - ComponentArn: [<The component arns of the image recipe>]
      ParentImage: "arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x"
```

如需有關 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html) 資源的詳細資訊，請參閱 *AWS CloudFormation User Guide*。

您可以透過設定 `AWS::ImageBuilder::ImagePipeline` 資源的 `Schedule` 屬性，在管道中自動建立新映像。排程包含開始條件與 Cron 表達式。如需詳細資訊，請參閱《AWS CloudFormation 使用者指南》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html)。

 下列 `AWS::ImageBuilder::ImagePipeline` 範例中，管道會於每日協調世界時 (UTC) 上午 10:00 執行一次建置作業。設定下列 `Schedule` 值：
+ 將 `PipelineExecutionStartCondition` 設定為 `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`。僅當父映像、元件等依賴資源 (其語意版本中使用萬用字元 ‘x’) 發生更新時，才會啟動建置作業。此設定可確保建置作業包含這些資源的最新更新。
+ 將 ScheduleExpression 設定為 Cron 表達式 `(0 10 * * ? *)`。

```
ECSPipeline:
    Type: AWS::ImageBuilder::ImagePipeline
    Properties:
      Name: my-pipeline
      ImageRecipeArn: <arn of the recipe you created in previous step>
      InfrastructureConfigurationArn: <ARN of the infrastructure configuration associated with this image pipeline>
      Schedule:
        PipelineExecutionStartCondition: EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE
        ScheduleExpression: 'cron(0 10 * * ? *)'
```

## 在 Terraform 中使用映像 ARN
<a name="arn-with-terraform"></a>

在 Terraform 中指定管道父映像及排程的方法，與 AWS CloudFormation中的方法一致。您需要使用 `aws_imagebuilder_image_recipe` 資源。將 `parent_image` 值設定為映像 ARN。請使用目標映像的無版本 ARN，確保管道一律使用最新版本的映像。如需詳細資訊，請參閱 Terraform 文件中的 [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference)。

在 `aws_imagebuilder_image_pipeline resource` 的排程組態區塊中，將 `schedule_expression` 引數值設定為您選擇的 Cron 表達式 (用於指定管道的執行頻率)，並將 `pipeline_execution_start_condition` 設定為 `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`。如需詳細資訊，請參閱 Terraform 文件中的 [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference)。

# 在 Amazon ECS 上使用 AWS 深度學習容器
<a name="deep-learning-containers"></a>

AWS 深度學習容器提供一組 Docker 影像，用於在 Amazon ECS 的 TensorFlow 和 Apache MXNet （培養） 中訓練和提供模型。Deep Learning Containers 實現最佳化環境與 TensorFlow、Nvidia CUDA (適用於 GPU 執行個體) 和 Intel MKL (適用於 CPU 執行個體) 程式庫。Amazon ECR 中提供適用於 Deep Learning Containers 的容器映像，以便在 Amazon ECS 任務定義中進行參考。您可以使用 Deep Learning Containers 和 Amazon Elastic Inference 來降低推論成本。

若要開始在 Amazon ECS 上使用 Deep Learning Containers (不搭配 Elastic Inference)，請參閱 *AWS 深度學習 AMIs Developer Guide* 中的 [Amazon ECS setup](https://docs.aws.amazon.com/deep-learning-containers/latest/devguide/deep-learning-containers-ecs-setup.html)。

# 教學課程：使用藍/綠部署建立服務
<a name="create-blue-green"></a>

Amazon ECS 已將藍/綠部署整合至 Amazon ECS 主控台內的建立服務精靈。如需詳細資訊，請參閱[建立 Amazon ECS 滾動更新部署](create-service-console-v2.md)。

以下教學課程說明如何在 AWS CLI透過使用藍/綠部署類型的 Fargate 任務建立 Amazon ECS 服務。

**注意**  
已為 CloudFormation新增對於執行藍/綠部署的支援。如需詳細資訊，請參閱 *AWS CloudFormation 使用者指南*中的[使用 CloudFormation透過 CodeDeploy 執行 Amazon ECS 藍/綠部署](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/blue-green.html)。

## 先決條件
<a name="create-blue-green-prereqs"></a>

本教學課程假設已完成下列先決條件：
+  AWS CLI 已安裝並設定最新版本的 。如需安裝或升級 的詳細資訊 AWS CLI，請參閱[安裝 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)。
+ 已完成「[設定以使用 Amazon ECS。](get-set-up-for-amazon-ecs.md)」中的步驟。
+ 您的 IAM 使用者擁有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 政策範例中指定的所需許可。
+ 您已建立 VPC 和安全群組。如需詳細資訊，請參閱[建立 Virtual Private Cloud](get-set-up-for-amazon-ecs.md#create-a-vpc)。
+ 已建立 Amazon ECS CodeDeploy IAM 角色。如需詳細資訊，請參閱[Amazon ECS CodeDeploy IAM 角色](codedeploy_IAM_role.md)。

## 步驟 1：建立 Application Load Balancer
<a name="create-blue-green-loadbalancer"></a>

使用藍/綠部署類型的 Amazon ECS 服務需要使用 Application Load Balancer 或 Network Load Balancer。本教學課程會使用 Application Load Balancer。

**建立 Application Load Balancer**

1. 使用 [create-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-load-balancer.html) 命令來建立 Application Load Balancer。指定並非來自與安全群組相同可用區域的兩個子網路。

   ```
   aws elbv2 create-load-balancer \
        --name bluegreen-alb \
        --subnets subnet-abcd1234 subnet-abcd5678 \
        --security-groups sg-abcd1234 \
        --region us-east-1
   ```

   其輸出將包含負載平衡器的 Amazon Resource Name (ARN)，格式如下：

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642
   ```

1. 使用 [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) 命令建立目標群組。此目標群組會將流量路由到服務中的原始任務集。

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget1 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id vpc-abcd1234 \
        --region us-east-1
   ```

   其輸出將包含目標群組的 ARN，格式如下：

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4
   ```

1. 使用 [create-listener](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-listener.html) 命令建立具有預設規則以將請求轉送至目標群組的負載平衡接聽程式。

   ```
   aws elbv2 create-listener \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --protocol HTTP \
        --port 80 \
        --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   其輸出將包含接聽程式的 ARN，格式如下：

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4
   ```

## 步驟 2：建立 Amazon ECS 叢集
<a name="create-blue-green-cluster"></a>

使用 [create-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-cluster.html) 命令來建立要使用之名為 `tutorial-bluegreen-cluster` 的叢集。

```
aws ecs create-cluster \
     --cluster-name tutorial-bluegreen-cluster \
     --region us-east-1
```

其輸出將包含叢集的 ARN，格式如下：

```
arn:aws:ecs:region:aws_account_id:cluster/tutorial-bluegreen-cluster
```

## 步驟 3：註冊任務定義
<a name="create-blue-green-taskdef"></a>

使用 [register-task-definition](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html) 命令來註冊與 Fargate 相容的任務定義。這需要使用 `awsvpc` 網路模式。以下是用於此教學課程的任務定義範例。

首先，建立名為 `fargate-task.json` 且具有下列內容的檔案。確保您使用的是任務執行角色的 ARN。如需詳細資訊，請參閱[Amazon ECS 任務執行 IAM 角色](task_execution_IAM_role.md)。

```
{
    "family": "sample-fargate", 
    "networkMode": "awsvpc", 
    "containerDefinitions": [
        {
            "name": "sample-app", 
            "image": "public.ecr.aws/docker/library/httpd:latest", 
            "portMappings": [
                {
                    "containerPort": 80, 
                    "hostPort": 80, 
                    "protocol": "tcp"
                }
            ], 
            "essential": true, 
            "entryPoint": [
                "sh",
		"-c"
            ], 
            "command": [
                "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
            ]
        }
    ], 
    "requiresCompatibilities": [
        "FARGATE"
    ], 
    "cpu": "256", 
    "memory": "512"
}
```

接下來，使用您建立的 `fargate-task.json` 檔案註冊任務定義。

```
aws ecs register-task-definition \
     --cli-input-json file://fargate-task.json \
     --region us-east-1
```

## 步驟 4：建立 Amazon ECS 服務
<a name="create-blue-green-service"></a>

使用 [create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html) 命令來建立服務。

首先，建立名為 `service-bluegreen.json` 且具有下列內容的檔案。

```
{
    "cluster": "tutorial-bluegreen-cluster",
    "serviceName": "service-bluegreen",
    "taskDefinition": "tutorial-task-def",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4",
            "containerName": "sample-app",
            "containerPort": 80
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-abcd1234" ],
          "subnets": [ "subnet-abcd1234", "subnet-abcd5678" ]
       }
    },
    "desiredCount": 1
}
```

接下來，使用您建立的 `service-bluegreen.json` 檔案建立服務。

```
aws ecs create-service \
     --cli-input-json file://service-bluegreen.json \
     --region us-east-1
```

其輸出將包含服務的 ARN，格式如下：

```
arn:aws:ecs:region:aws_account_id:service/service-bluegreen
```

## 步驟 5：建立 AWS CodeDeploy 資源
<a name="create-blue-green-codedeploy"></a>

請依照下列步驟建立 CodeDeploy 應用程式、CodeDeploy 部署群組的 Application Load Balancer 目標群組，以及 CodeDeploy 部署群組。

**建立 CodeDeploy 資源**

1. 使用 [create-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-application.html) 命令建立 CodeDeploy 應用程式。指定 `ECS` 運算平台。

   ```
   aws deploy create-application \
        --application-name tutorial-bluegreen-app \
        --compute-platform ECS \
        --region us-east-1
   ```

   其輸出將包含應用程式 ID，格式如下：

   ```
   {
       "applicationId": "b8e9c1ef-3048-424e-9174-885d7dc9dc11"
   }
   ```

1. 使用 [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) 命令建立第二個 Application Load Balancer 目標群組，該群組會在您建立 CodeDeploy 部署群組時用到。

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget2 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id "vpc-0b6dd82c67d8012a1" \
        --region us-east-1
   ```

   其輸出將包含目標群組的 ARN，格式如下：

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc
   ```

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

   首先，建立名為 `tutorial-deployment-group.json` 且具有下列內容的檔案。此範例會使用您建立的資源。對於 `serviceRoleArn`，請指定 Amazon ECS CodeDeploy IAM 角色的 ARN。如需詳細資訊，請參閱[Amazon ECS CodeDeploy IAM 角色](codedeploy_IAM_role.md)。

   ```
   {
      "applicationName": "tutorial-bluegreen-app",
      "autoRollbackConfiguration": {
         "enabled": true,
         "events": [ "DEPLOYMENT_FAILURE" ]
      },
      "blueGreenDeploymentConfiguration": {
         "deploymentReadyOption": {
            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
            "waitTimeInMinutes": 0
         },
         "terminateBlueInstancesOnDeploymentSuccess": {
            "action": "TERMINATE",
            "terminationWaitTimeInMinutes": 5
         }
      },
      "deploymentGroupName": "tutorial-bluegreen-dg",
      "deploymentStyle": {
         "deploymentOption": "WITH_TRAFFIC_CONTROL",
         "deploymentType": "BLUE_GREEN"
      },
      "loadBalancerInfo": {
         "targetGroupPairInfoList": [
           {
             "targetGroups": [
                {
                    "name": "bluegreentarget1"
                },
                {
                    "name": "bluegreentarget2"
                }
             ],
             "prodTrafficRoute": {
                 "listenerArns": [
                     "arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4"
                 ]
             }
           }
         ]
      },
      "serviceRoleArn": "arn:aws:iam::aws_account_id:role/ecsCodeDeployRole",
      "ecsServices": [
          {
              "serviceName": "service-bluegreen",
              "clusterName": "tutorial-bluegreen-cluster"
          }
      ]
   }
   ```

   接著建立 CodeDeploy 部署群組。

   ```
   aws deploy create-deployment-group \
        --cli-input-json file://tutorial-deployment-group.json \
        --region us-east-1
   ```

   其輸出將包含部署群組 ID，格式如下：

   ```
   {
       "deploymentGroupId": "6fd9bdc6-dc51-4af5-ba5a-0a4a72431c88"
   }
   ```

## 步驟 6：建立與監控 CodeDeploy 部署
<a name="create-blue-green-verify"></a>

使用以下步驟來建立和上傳應用程式規格檔案 (AppSpec 檔案) 和 CodeDeploy 部署。

**建立和監控 CodeDeploy 部署**

1. 使用以下步驟來建立和上傳 AppSpec 檔案。

   1. 建立名為 `appspec.yaml` 並具有 CodeDeploy 部署群組內容的檔案。此範例會使用您先前在教學課程中建立的資源。

      ```
      version: 0.0
      Resources:
        - TargetService:
            Type: AWS::ECS::Service
            Properties:
              TaskDefinition: "arn:aws:ecs:region:aws_account_id:task-definition/first-run-task-definition:7"
              LoadBalancerInfo:
                ContainerName: "sample-app"
                ContainerPort: 80
              PlatformVersion: "LATEST"
      ```

   1. 使用 [s3 mb](https://docs.aws.amazon.com/cli/latest/reference/s3/mb.html) 命令為 AppSpec 檔案建立 Amazon S3 儲存貯體。

      ```
      aws s3 mb s3://tutorial-bluegreen-bucket
      ```

   1. 使用 [s3 cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) 命令來將 AppSpec 檔案上傳至 Amazon S3 儲存貯體。

      ```
      aws s3 cp ./appspec.yaml s3://tutorial-bluegreen-bucket/appspec.yaml
      ```

1. 使用下列步驟來建立 CodeDeploy 部署。

   1. 建立名為 `create-deployment.json` 並具有 CodeDeploy 部署內容的檔案。此範例會使用您先前在教學課程中建立的資源。

      ```
      {
          "applicationName": "tutorial-bluegreen-app",
          "deploymentGroupName": "tutorial-bluegreen-dg",
          "revision": {
              "revisionType": "S3",
              "s3Location": {
                  "bucket": "tutorial-bluegreen-bucket",
                  "key": "appspec.yaml",
                  "bundleType": "YAML"
              }
          }
      }
      ```

   1. 使用 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html) 命令來建立部署。

      ```
      aws deploy create-deployment \
           --cli-input-json file://create-deployment.json \
           --region us-east-1
      ```

      其輸出將包含部署 ID，格式如下：

      ```
      {
          "deploymentId": "d-RPCR1U3TW"
      }
      ```

   1. 使用 [get-deployment-target](https://docs.aws.amazon.com/cli/latest/reference/deploy/get-deployment-target.html) 命令，並從先前的輸出中指定 `deploymentId` 來取得部署的詳細資訊。

      ```
      aws deploy get-deployment-target \
           --deployment-id "d-IMJU3A8TW" \
           --target-id tutorial-bluegreen-cluster:service-bluegreen \
           --region us-east-1
      ```

      繼續擷取狀態變為 `Succeeded` 前的部署詳細資訊，如下列輸出所示。

      ```
      {
          "deploymentTarget": {
              "deploymentTargetType": "ECSTarget",
              "ecsTarget": {
                  "deploymentId": "d-RPCR1U3TW",
                  "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
                  "targetArn": "arn:aws:ecs:region:aws_account_id:service/service-bluegreen",
                  "lastUpdatedAt": 1543431490.226,
                  "lifecycleEvents": [
                      {
                          "lifecycleEventName": "BeforeInstall",
                          "startTime": 1543431361.022,
                          "endTime": 1543431361.433,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "Install",
                          "startTime": 1543431361.678,
                          "endTime": 1543431485.275,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterInstall",
                          "startTime": 1543431485.52,
                          "endTime": 1543431486.033,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "BeforeAllowTraffic",
                          "startTime": 1543431486.838,
                          "endTime": 1543431487.483,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AllowTraffic",
                          "startTime": 1543431487.748,
                          "endTime": 1543431488.488,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterAllowTraffic",
                          "startTime": 1543431489.152,
                          "endTime": 1543431489.885,
                          "status": "Succeeded"
                      }
                  ],
                  "status": "Succeeded",
                  "taskSetsInfo": [
                      {
                          "identifer": "ecs-svc/9223370493425779968",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "ACTIVE",
                          "trafficWeight": 0.0,
                          "targetGroup": {
                              "name": "bluegreentarget1"
                          }
                      },
                      {
                          "identifer": "ecs-svc/9223370493423413672",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "PRIMARY",
                          "trafficWeight": 100.0,
                          "targetGroup": {
                              "name": "bluegreentarget2"
                          }
                      }
                  ]
              }
          }
      }
      ```

## 步驟 7：清除
<a name="create-blue-green-cleanup"></a>

完成此教學課程時，清除與其相關的資源，以免未使用的資源產生費用。

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

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 tutorial-bluegreen-app \
        --deployment-group-name tutorial-bluegreen-dg \
        --region us-east-1
   ```

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

   ```
   aws deploy delete-application \
        --application-name tutorial-bluegreen-app \
        --region us-east-1
   ```

1. 使用 [delete-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-service.html) 命令來刪除 Amazon ECS 服務。使用 `--force` 旗標可讓您即使在服務未縮減為零個任務時仍能將其刪除。

   ```
   aws ecs delete-service \
        --service arn:aws:ecs:region:aws_account_id:service/service-bluegreen \
        --force \
        --region us-east-1
   ```

1. 使用 [delete-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-cluster.html) 命令來刪除 Amazon ECS 叢集。

   ```
   aws ecs delete-cluster \
        --cluster tutorial-bluegreen-cluster \
        --region us-east-1
   ```

1. 使用 [s3 rm](https://docs.aws.amazon.com/cli/latest/reference/s3/rm.html) 命令來將 AppSpec 檔案從 Amazon S3 儲存貯體中刪除。

   ```
   aws s3 rm s3://tutorial-bluegreen-bucket/appspec.yaml
   ```

1. 使用 [s3 rb](https://docs.aws.amazon.com/cli/latest/reference/s3/rb.html) 命令來刪除 Amazon S3 儲存貯體。

   ```
   aws s3 rb s3://tutorial-bluegreen-bucket
   ```

1. 使用 [delete-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-load-balancer.html) 命令刪除 Application Load Balancer。

   ```
   aws elbv2 delete-load-balancer \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --region us-east-1
   ```

1. 使用 [delete-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-target-group.html) 命令，刪除兩個 Application Load Balancer 目標群組。

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc \
        --region us-east-1
   ```