

# 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)  | 

以下のチュートリアルのいずれかを使用すると、AWS CLI を使用して Amazon ECS にタスクをデプロイできます。


| チュートリアルの概要 | 詳細情報 | 
| --- | --- | 
|  Fargate 用の Linux タスクを作成する。  |  [AWS CLI を使用して、Fargate 用の Amazon ECS Linux タスクを作成する](ECS_AWSCLI_Fargate.md)  | 
|  Fargate 用の Windows タスクを作成する。  |  [AWS CLI を使用して、Fargate 用の Amazon ECS Windows タスクを作成する](ECS_AWSCLI_Fargate_windows.md)  | 
|  EC2 用の Linux タスクを作成する。  |  [AWS CLI を使用して、EC2 用の Amazon ECS タスクを作成する](ECS_AWSCLI_EC2.md)  | 

以下のチュートリアルのいずれかを使用すると、モニタリングとログ記録の詳細を確認できます。


| チュートリアルの概要 | 詳細情報 | 
| --- | --- | 
|  タスクイベントをリッスンし、CloudWatch Logs ログストリームに書き込むシンプルな Lambda 関数を設定します。  |  [CloudWatch Events イベントをリッスンするように Amazon ECS を設定する](ecs_cwet.md)  | 
|  重要なコンテナのいずれかが終了したことにより、タスクの実行が停止したタスクイベントのみをキャプチャする Amazon EventBridge イベントルールを設定します。  |  [Amazon ECS タスク停止イベントに関する Amazon Simple Notification Service アラートの送信](ecs_cwet2.md)  | 
|  もともと 1 つのコンテキストに属していたが、複数のレコードまたはログ行に分割されたログメッセージを連結します。  |  [複数行またはスタックトレースの 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 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)  | 
|  ドメインレスグループの Managed Service Account を使用して、Active Directory にアクセスするための認証情報を持つ Windows コンテナを実行するタスクを作成します。  |  [AWS CLI を使用するドメインレス gMSA で Amazon ECS Windows コンテナを使用する](tutorial-gmsa-windows.md)  | 

# AWS CLI を使用して、Fargate 用の Amazon ECS Linux タスクを作成する
<a name="ECS_AWSCLI_Fargate"></a>

次のステップでは、AWS CLI を使って Amazon ECS でクラスターのセットアップ、タスク定義の登録、Linux タスクの実行、その他の一般的なシナリオを実行するために役立ちます。AWS CLI の最新バージョンを使用する。最新のバージョンにアップグレードする方法については、「[AWS CLI の最新バージョンをインストールまたは更新](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」を参照してください。

**注記**  
デュアルスタックサービスエンドポイントを使用することで、IPv4 と IPv6 の両方を介して AWS CLI、SDK、および 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 パブリックにホストされているコンテナ画像を使用するため、タスクではインターネットアクセスが必要になります。タスクでインターネットへのルートを設定するには、以下のいずれかのオプションを使用します。
  + Elastic IP アドレスが割り当てられた NAT ゲートウェイでプライベートサブネットを使用する。
  + パブリックサブネットを使用してタスクにパブリック IP アドレスを割り当てる。

  詳細については、「[仮想プライベートクラウドを作成する](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 を使用してコンテナを直接操作し、デプロイをテストできます。ECS Exec を使用するには、タスク IAM ロールを作成する必要があります。タスク IAM ロールおよびその他の前提条件の詳細については、「[ECS Exec を使用して Amazon ECS コンテナをモニタリングする](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html)」を参照してください。
+ (任意) AWS CloudShell は、お客様が独自の EC2 インスタンスを作成する必要なく、コマンドラインを提供するツールです。詳細については、「*AWS CloudShell ユーザーガイド*」の「[What is 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 クラスターでタスクを実行する前に、タスク定義を登録する必要があります。タスク定義とは、1 つにグループ化されたコンテナのリストです。以下の例は、Docker Hub でホストされている httpd コンテナイメージを使用して PHP ウェブアプリケーションを作成するシンプルなタスク定義です。使用できるタスク定義パラメータの詳細については、「[Amazon ECS のタスク定義](task_definitions.md)」を参照してください。このチュートリアルでは、プライベート サブネットにタスクをデプロイし、そのデプロイメントをテストする場合にのみ `taskRoleArn` が必要になります。`taskRoleArn` を、[前提条件](#ECS_AWSCLI_Fargate_prereq) で説明した 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** コマンドを使用して、いつでもアカウントのタスク定義をリスト表示できます。このコマンドの出力は、**run-task** または **start-task** をコールするときに一緒に使用する、`family` 値および `revision` 値を表示します。

```
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` タスク定義の 1 つのインスタンスを使用して、クラスターで実行されるサービスを作成します。このタスクにはインターネットへのルートが必要であり、そのために 2 つの方法のいずれかを使用します。1 つの方法は、パブリックサブネットに Elastic IP アドレスを持つ NAT ゲートウェイで構成されたプライベートサブネットを使用することです。もう 1 つの方法は、パブリックサブネットを使用してパブリック IP アドレスをタスクに割り当てることです。両方の例を以下に示します。

プライベートサブネットを使用した例。Amazon ECS Exec を使用するには ` 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]}" --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>

タスクの Elastic Network Interface (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 を見つけます。`tasks` パラメータにはタスク ARN を使用します。

```
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"
                        },
                    ]
                }
…
}
```

パブリック IP アドレスを取得するには ENI を記述します。

```
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"
            },
…
}
```

ウェブブラウザにパブリック 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` が実行されていることを確認した後、次のコマンドを実行して、タスク内のコンテナ上で対話的なシェルを実行できます。

```
  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"
```

 対話的なシェルの実行後、次のコマンドを実行して cURL をインストールします。

```
apt update 
```

```
apt install curl 
```

 cURL をインストール後、先ほど取得したプライベート IP アドレスを使用して次のコマンドを実行します。

```
 curl 10.0.143.156 
```

 **Amazon ECS** サンプルアプリケーションの Web ページと同等の 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
```

# AWS CLI を使用して、Fargate 用の Amazon ECS Windows タスクを作成する
<a name="ECS_AWSCLI_Fargate_windows"></a>

次のステップでは、AWS CLI を使って Amazon ECS でクラスターのセットアップ、タスク定義の登録、Windows タスクの実行、その他の一般的なシナリオを実行するために役立ちます。最新バージョンの AWS CLI を使用していることを確認してください。最新のバージョンにアップグレードする方法については、「[AWS CLI の最新バージョンをインストールまたは更新](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」を参照してください。

**注記**  
デュアルスタックサービスエンドポイントを使用することで、IPv4 と IPv6 の両方を介して AWS CLI、SDK、および 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 でホストされているコンテナイメージを使用するため、タスクではインターネットにアクセスできる必要があります。タスクでインターネットへのルートを設定するには、以下のいずれかのオプションを使用します。
  + Elastic IP アドレスが割り当てられた NAT ゲートウェイでプライベートサブネットを使用する。
  + パブリックサブネットを使用してタスクにパブリック IP アドレスを割り当てる。

  詳細については、「[仮想プライベートクラウドを作成する](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 ユーザーガイド*」の「[What is 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 タスクを実行する前に、タスク定義を登録する必要があります。タスク定義とは、1 つにグループ化されたコンテナのリストです。次の例では、ウェブアプリを作成する単純なタスク定義です。使用できるタスク定義パラメータの詳細については、「[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 例は次の 2 通りの方法で AWS CLI に渡すことができます。1 番目はタスク定義 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** コマンドを使用して、いつでもアカウントのタスク定義をリスト表示できます。このコマンドの出力は、**run-task** または **start-task** をコールするときに一緒に使用する、`family` 値および `revision` 値を表示します。

```
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` タスク定義の 1 つのインスタンスを使用して、クラスターで実行されるサービスを作成します。このタスクにはインターネットへのルートが必要であり、そのために 2 つの方法のいずれかを使用します。1 つの方法は、パブリックサブネットに Elastic IP アドレスを持つ NAT ゲートウェイで構成されたプライベートサブネットを使用することです。もう 1 つの方法は、パブリックサブネットを使用してパブリック 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
```

# AWS CLI を使用して、EC2 用の Amazon ECS タスクを作成する
<a name="ECS_AWSCLI_EC2"></a>

次のステップでは、AWS CLI を使って Amazon ECS でクラスターのセットアップ、タスク定義の登録、タスクの実行、その他の一般的なシナリオを実行するために役立ちます。AWS CLI の最新バージョンを使用する。最新のバージョンにアップグレードする方法については、「[AWS CLI の最新バージョンをインストールまたは更新](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」を参照してください。

**注記**  
デュアルスタックサービスエンドポイントを使用することで、IPv4 と IPv6 の両方を介して AWS CLI、SDK、および 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)
+ [ウェブサーバーをテストする。](#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 が作成されています。詳細については、「[仮想プライベートクラウドを作成する](get-set-up-for-amazon-ecs.md#create-a-vpc)」を参照してください。
+ (任意) AWS CloudShell は、お客様が独自の EC2 インスタンスを作成する必要なく、コマンドラインを提供するツールです。詳細については、「*AWS CloudShell ユーザーガイド*」の「[What is 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 Parameter Store を使用して最新の 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 アクセスとウェブサーバーの 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 アクセスを許可するようになりました。本番環境では、特定の IP アドレスへの SSH アクセスを制限し、必要に応じて 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"
           }
       ]
   }
   ```

   ユーザーデータスクリプトは、インスタンスを `MyCluster` に登録するように Amazon ECS エージェントを設定します。インスタンスは、エージェントに必要なアクセス許可を提供する `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 コンソールまたは **aws ec2 describe-instances --instance-id *instance\$1id*** コマンドを使用して、インスタンスのモニタリングに使用できる Amazon EC2 インスタンス ID も検索することもできます。

## タスク定義を登録する
<a name="AWSCLI_EC2_register_task_definition"></a>

Amazon ECS クラスターにタスクを実行する前に、タスク定義を登録する必要があります。タスク定義とは、1 つにグループ化されたコンテナのリストです。次の例は、`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 例は次の 2 通りの方法で AWS CLI に渡すことができます。1 番目はタスク定義 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** コマンドを使用して、いつでもアカウントのタスク定義をリスト表示できます。このコマンドの出力は、 または **create-service** をコールするときに一緒に使用する、`family` 値および `revision` 値を表示します。

```
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` タスク定義のインスタンスを 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"
        }
    ]
}
```

## ウェブサーバーをテストする。
<a name="AWSCLI_EC2_test_web_server"></a>

**ウェブサーバーをテストするには**

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"
       }
   }
   ```

# CloudWatch Events イベントをリッスンするように Amazon ECS を設定する
<a name="ecs_cwet"></a>

タスクイベントをリッスンし、それを CloudWatch Logs ログストリームに書き込むシンプルな Lambda 関数を設定する方法について説明します。

## 前提条件: テストクラスターを設定する
<a name="cwet_step_1"></a>

イベントをキャプチャする実行中のクラスターがなければ、[Fargate ワークロード用の Amazon ECS クラスターを作成する](create-cluster-console-v2.md) のステップに従ってクラスターを作成します。このチュートリアルの最後に、このクラスターでタスクを実行して Lambda 関数が正しく設定されていることをテストします。

## ステップ 1: Lambda 関数を作成する
<a name="cwet_step_2"></a>

この手順では、Amazon ECS イベントストリームメッセージのターゲットとなるシンプルな Lambda 関数を作成します。

1. AWS Lambda コンソールの [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) を開いてください。

1. [**関数の作成**] を選択してください。

1. [**Author from scratch**] 画面で、次の操作を行います。

   1. [**名前**] に値を入力します。

   1. **[Runtime]** (ランタイム) で、Python のバージョン (**Python 3.9** など) を選択します。

   1. [**Role**] で、[**Create a new role with basic Lambda permissions**] を選択します。

1. **[Create function]** を選択します。

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))
   ```

   これは、Amazon ECS から送信されたイベントを出力するシンプルな Python 3.9 関数です。すべてが正しく設定されると、このチュートリアルの最後に、この Lambda 関数に関連付けられている CloudWatch Logs ログストリームにイベントの詳細が表示されます。

1. **[保存]** を選択します。

## ステップ 2: イベントルールを登録する
<a name="cwet_step_3"></a>

 次に、Amazon ECS クラスターから送信されるタスクイベントをキャプチャする CloudWatch Events イベントルールを作成します。このルールでは、それが定義されているアカウント内のすべてのクラスターから送信されるすべてのイベントがキャプチャされます。タスクメッセージ自体内に、イベントソースに関する情報 (イベントソースがあるクラスターの情報など) が含まれており、この情報を使用してプログラムでイベントをフィルタしてソートできます。

**注記**  
AWS マネジメントコンソール を使用してイベントルールを作成すると、コンソールが CloudWatch Eventsに Lambda 関数を呼び出す権限を付与するために必要な IAM 権限を自動的に追加します。AWS CLI を使用してイベントルールを作成する場合は、この権限を明示的に付与する必要があります。詳細については、「*Amazon EventBridge ユーザーガイド*」の「[Amazon EventBridge イベント](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html)」と「[Amazon EventBridge のイベントパターン](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html)」を参照してください。

**Lambda 関数にイベントをルートするには**

1. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) を開いてください。

1. ナビゲーションペインで、[**Events**]、[**Rules**]、[**Create rule**] の順に選択します。

1. [**Event Source**] で、イベントソースとして [**ECS**] を選択します。デフォルトでは、ルールはすべての Amazon ECS グループのすべての Amazon ECS イベントに適用されます。または、特定のイベントや特定の Amazon ECS グループを選択することもできます。

1. **[ターゲット]** に **[ターゲットの追加]** を選択し、**[ターゲットの種類]** に **[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. ナビゲーションペインで、**[タスク定義]** を選択します。

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>

 最後に、Amazon ECS クラスターから送信されるタスクイベントをキャプチャする CloudWatch Events イベントルールを作成します。このルールでは、それが定義されているアカウント内のすべてのクラスターから送信されるすべてのイベントがキャプチャされます。タスクメッセージ自体内に、イベントソースに関する情報 (イベントソースがあるクラスターの情報など) が含まれており、この情報を使用してプログラムでイベントをフィルタしてソートできます。

**ルールをテストするには**

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]** (クラスター) で [default] (デフォルト) を選択し、**[Deploy]** (デプロイ) を選択します。

1. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) を開いてください。

1. ナビゲーションペインで、**ログ** を選択して 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)」を参照し、さらに、次の表から選択するオプションを決定します。


| オプション | 値 | 
| --- | --- | 
|  タイプ  | 標準 | 
| 名前 |  TaskStoppedAlert  | 
| プロトコル | E メール | 
| Endpoint |  現在アクセスできる E メールアドレス  | 

## ステップ 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)」を参照し、次の表を使用して、選択するオプションを決定します。


| オプション | 値 | 
| --- | --- | 
|  ルールタイプ  |  イベントパターンを持つルール  | 
| イベントソース | 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> | 
| 対象タイプ |  AWS サービス  | 
| ターゲット | SNS トピック | 
| Topic |  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. ナビゲーションペインで、**タスクの定義** を選択します。

1. **[Create new task definition]** (新しいタスク定義の作成)、**[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>

Fluent Bit バージョン 2.22.0 以降の AWS では、複数行フィルターが含まれています。複数行フィルターは、もともと 1 つのコンテキストに属していても、複数のレコードまたはログ行に分割されたログメッセージを連結するのに役立ちます。複数行フィルターの詳細については、「[Fluent Bit documentation](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)」(Fluent Bit ドキュメント) を参照してください。

以下は、分割されたログメッセージの一般的な例です。
+ スタックトレース 
+ 複数の行にログを出力するアプリケーション。
+ 指定されたランタイムの最大バッファサイズを超過した場合に、ログメッセージが分割されます GitHub の例、「[FireLens Example: Concatenate Partial/Split Container Logs](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/filter-multiline-partial-message-mode)」(FireLens の例:部分/分割コンテナログの連結) に従い、コンテナランタイムによって分割されたログメッセージを連結することができます。

## 必要な IAM 許可
<a name="iam-permissions"></a>

コンテナエージェントが Amazon ECR からコンテナイメージをプルし、コンテナがログを CloudWatch Logs にルーティングするために必要なIAM 許可を持っていることを確認する必要があります。

これらの許可には、次のロールが必要です。
+ タスク 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>

ログを解析し、改行によって分割された行を連結するには、以下の 2 つのオプションのいずれかを使用します。
+ 同じメッセージに属する行を解析および連結するルールを含む独自のパーサーファイルを作成します。
+ 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"
      ```

      正規表現パターンをカスタマイズするときは、正規表現エディタを使用して式をテストすることをお勧めします。

   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 イメージをビルドします。
**注記**  
このファイルパスが FireLens によって使用される `/fluent-bit/etc/fluent-bit.conf` の場合を除いて、Dockerイメージの任意の場所にパーサーファイルと構成ファイルを配置できます。

   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 Container Registry にアップロードします。

   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. 前のステップの `docker tag fluent-bit-multiline-image repositoryUri` の値で `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. 前のステップの `docker tag multiline-app-image repositoryUri` の値で `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 コンソールに移動します。**ロール**を選択し、作成した `ecs-task-role-for-firelens` タスクロールを検索します。ロールを選択し、**概要**セクションに表示される **ARN** をコピーします。

   1. `execution role ARN`

      実行ロールの ARN を検索するには、IAM コンソールに移動します。**ロール**を選択し、`ecsTaskExecutionRole` ロールを検索します。ロールを選択し、**概要**セクションに表示される **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. ナビゲーションペインで、[**タスク定義**] を選択し、上記のタスク定義の最初の行でタスク定義をこのファミリに登録したため、`firelens-example-multiline` ファミリを選択します。

1. 最新バージョンを選択します。

1. **[デプロイ]**、**[タスクを実行]** を選択します。

1. **[タスクを実行]** ページの **[クラスター]** でクラスターを選択し、**[ネットワーク]** の **[サブネット]** で、タスクに使用できるサブネットを選択します。

1. **[作成]** を選択します。

**Amazon CloudWatch の複数行のログメッセージが連結されて表示されることを確認する**

1. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) を開いてください。

1. ナビゲーションペインで、[**Logs (ログ)**] を展開して、[**Log groups (ロググループ)**] を選択します。

1. `multiline-test/applicatio` ロググループを選択します。

1. ログを選択します。メッセージを表示します。パーサーファイル内のルールに一致する行は連結され、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 コンテナを実行する場合に、同じメッセージが 1 行でどのように表示されるかを示しています。

   ```
   {
       "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 イメージをビルドします。
**注記**  
このファイルパスが FireLens によって使用される `/fluent-bit/etc/fluent-bit.conf` の場合を除いて、Docker イメージの任意の場所に設定ファイルを配置できます。

   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 Container Registry にアップロードします。

   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. 前のステップの `docker tag fluent-bit-multiline-image repositoryUri` の値で `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. 前のステップの `docker tag multiline-app-image repositoryUri` の値で `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 コンソールに移動します。**ロール**を選択し、作成した `ecs-task-role-for-firelens` タスクロールを検索します。ロールを選択し、**概要**セクションに表示される **ARN** をコピーします。

   1. `execution role ARN`

      実行ロールの ARN を検索するには、IAM コンソールに移動します。**ロール**を選択し、`ecsTaskExecutionRole` ロールを検索します。ロールを選択し、**概要**セクションに表示される **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. ナビゲーションペインで、[**タスク定義**] を選択し、上記のタスク定義の最初の行でタスク定義をこのファミリに登録したため、`firelens-example-multiline` ファミリを選択します。

1. 最新バージョンを選択します。

1. **[デプロイ]**、**[タスクを実行]** を選択します。

1. **[タスクを実行]** ページの **[クラスター]** でクラスターを選択し、**[ネットワーク]** の **[サブネット]** で、タスクに使用できるサブネットを選択します。

1. **[作成]** を選択します。

**Amazon CloudWatch の複数行のログメッセージが連結されて表示されることを確認する**

1. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) を開いてください。

1. ナビゲーションペインで、[**Logs (ログ)**] を展開して、[**Log groups (ロググループ)**] を選択します。

1. `multiline-test/applicatio` ロググループを選択します。

1. ログを選択し、メッセージを表示します。パーサーファイル内のルールに一致する行は連結され、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 コンテナを実行する場合に、同じイベントがどのように表示されるかを示しています。ログフィールドには 1 行が含まれます。

   ```
   {
       "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"
   ```

**注記**  
ログが標準出力ではなくログファイルに移動する場合は、フィルターではなく [Tail 入力プラグイン](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 とは、さまざまなオペレーティングシステムでサポートされている高速で柔軟なログプロセッサおよびルーターです。Amazon CloudWatch Logs、Firehose Amazon S3、Amazon OpenSearch Service など、さまざまな AWS の宛先にログをルーティングするために使用できます。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 の 1 つのインスタンスが常にクラスター内のコンテナインスタンス上で実行されるようになります。
  + 転送入力プラグインを使用して、ポート 24224 でリッスンします。
  + Docker ランタイムがこの公開ポートを使用して Fluent Bit にログを送信できるように、ポート 24224 をホストに公開します。
  + Fluent Bit がログレコードを指定された宛先に送信できるようにする設定があります。
+ fluentd ロギングドライバーを使用して、その他すべての Amazon ECS タスクコンテナを起動します。詳細については、Docker ドキュメントのウェブサイトの「[Fluentd ロギングドライバー](https://docs.docker.com/engine/logging/drivers/fluentd/)」を参照してください。
  + Docker は、ホスト名前空間内のローカルホスト上の TCP ソケット 24224 に接続します。
  + Amazon ECS エージェントは、クラスター名、タスク定義ファミリー名、タスク定義リビジョン番号、タスク ARN、およびコンテナ名を含むラベルをコンテナに追加します。fluentd docker ロギングドライバーの labels オプションを使用して、同じ情報がログレコードに追加されます。詳細については、Docker ドキュメントのウェブサイトの「[ラベル、labels-regex、env、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、タスクコンテナ名、タスク定義ファミリー、タスク定義リビジョン番号などのを含むメタデータを各ログエントリに追加します。

  例えば、`container_1` と `container_2` のある `task_1` および `container_3` のある t`ask_2` の場合、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、SDK、および 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: デーモンスケジューリング戦略を使用して `ecs-windows-fluent-bit` タスク定義を Amazon ECS サービスとして実行する](#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 の最新バージョンがインストールされ、設定されていること。詳細については、「[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]** です。
+ EC2 インスタンスを起動するパブリックサブネットを持つ VPC があります。デフォルトの VPC を使用できます。Amazon CloudWatch エンドポイントがサブネットに到達できるようにするプライベートサブネットを使用することもできます。Amazon CloudWatch エンドポイントの詳細については、「*AWS 全般のリファレンス*」の「[Amazon CloudWatch のエンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/cw_region.html)」を参照してください。Amazon VPC ウィザードを使用して VPC を作成する方法の詳細については、「[仮想プライベートクラウドを作成する](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. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

   1. ナビゲーションバーから、使用するリージョンを選択します。

   1. **EC2 ダッシュボード**から、[**Launch Instance**] を選択します。

   1. [**Name (名前)**] に一意の名前を入力します。

   1. **[Application and OS Images (Amazon Machine Image)]** (アプリケーションおよび OS イメージ (Amazon マシンイメージ)) で、最初の手順で取得した 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. 準備ができたら、確認フィールドを選択してから、[**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 で提供されている他のデフォルト設定を使用することもできます。詳細については、`aws-for-fluent-bit` Github ウェブサイトの「[Windows イメージのエントリポイントのオーバーライド](https://github.com/aws/aws-for-fluent-bit/tree/mainline/ecs_windows_forward_daemon#overriding-the-entrypoint-for-the-windows-image)」を参照してください。

デフォルトの Amazon CloudWatch Fluent Bit 設定を以下に示します。

以下の変数を置き換えます。
+ *region* を、Amazon CloudWatch ログを送信したいリージョンで置き換えます。

```
[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 の内部パイプラインは、Match regex を使用してログエントリをルーティングし、フィルターを変更します。このフィルターは、ログレコード JSON のキーを Fluent Bit が使用できる形式に置き換えます。
+ 変更されたログエントリは、その後 rewrite\$1tag フィルターによって使用されます。このフィルターは、ログレコードのタグを out.*TASK\$1ID*。*CONTAINER\$1NAME* 形式に変更します。
+ 新しいタグは、CloudWatch 出力プラグインの `log_group_template` オプションおよび `log_stream_prefix` オプションを使用して前述のようにロググループとストリームを作成する出力 cloudwatch\$1logs プラグインにルーティングされます。追加情報については、「*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 リソースネーム (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: デーモンスケジューリング戦略を使用して `ecs-windows-fluent-bit` タスク定義を Amazon ECS サービスとして実行する
<a name="tutorial-deploy-fluentbit-on-windows-run-task"></a>

アカウントのタスク定義を登録したら、クラスターでタスクを実行できます。このチュートリアルでは、`FluentBit-cluster` クラスターで `ecs-windows-fluent-bit:1` タスク定義のインスタンスを 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>

ログを生成するタスク定義を登録します。このタスク定義では、1 秒ごとに増分数を `stdout` に書き込む Windows コンテナイメージをデプロイします。

タスク定義では、Fluent Bit プラグインがリッスンするポート 24224 に接続する fluentd ロギングドライバーを使用します。Amazon ECS エージェントは、クラスター名、タスク ARN、タスク定義ファミリー名、タスク定義リビジョン番号、タスクコンテナ名などを含むタグのある各 Amazon ECS コンテナにラベルを付けます。これらのキー値ラベルは 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 タスクコンテナ内のタスクの 2 番目のインスタンスによって生成されたすべてのログが含まれます。

 `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. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/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 EC2 の Linux コンテナで gMSA を使用する
<a name="linux-gmsa"></a>

Amazon ECS は、*グループ管理サービスアカウント* (gMSA) と呼ばれる特殊なサービスアカウントを使用して、EC2 上の Linux コンテナの Active Directory 認証をサポートします。

Linux Core アプリケーションなどの .NET ベースのネットワークアプリケーションは、Active Directory を使用して、ユーザーとサービス間の認証と認可の管理を円滑化することができます。この機能は、Active Directory と統合され、ドメインに参加しているサーバー上で実行されるアプリケーションを設計することで利用できます。しかし、Linux コンテナはドメインに参加できないため、gMSA を使用して実行する Linux コンテナを設定する必要があります。

gMSA で実行される Linux コンテナは、コンテナのホスト Amazon EC2 インスタンスで実行される `credentials-fetcher` デーモンに依存します。つまり、デーモンは Active Directory ドメインコントローラーからも認証情報を取得し、これらの gMSA 認証情報をコンテナインスタンスに転送します。サービスアカウントの詳細については、Microsoft Learn Web サイトの「[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 コンピュータが必要になる場合があります。例えば、PowerShell を使用して Active Directory で gMSA を作成するには、ドメインに参加している Windows コンピュータが必要になる場合があります。RSAT Active 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/ja_jp/AmazonECS/latest/developerguide/linux-gmsa.html)

## 前提条件
<a name="linux-gmsa-prerequisites"></a>

gMSA を使用する前に、Amazon ECS の Linux コンテナ機能のために必ず以下を完了してください。
+ コンテナがアクセスするリソースを含む 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 EC2 の Linux コンテナで gMSA を使用する](#linux-gmsa)」を参照してください。
+ Amazon ECS Linux コンテナインスタンスに `credentials-fetcher` デーモンをインストールして実行しています。また、Active Directory で認証するための初期資格情報セットを `credentials-fetcher` デーモンに追加しました。
**注記**  
`credentials-fetcher` デーモンは、Amazon Linux 2023 および Fedora 37 以降でのみ使用できます。デーモン は Amazon Linux 2 では使用できません。詳細については、GitHub の「[aws/credentials-fetcher](https://github.com/aws/credentials-fetcher)」を参照してください。
+ Active Directory で認証するための `credentials-fetcher` デーモンの認定情報を設定します。認証情報は、gMSA アカウントにアクセスできる Active Directory セキュリティグループのメンバーである必要があります。[インスタンスをドメインに参加させるか、ドメインレス gMSA を使用するかを決定します。](#linux-gmsa-initial-creds) には複数のオプションがあります。
+ 必須の IAM アクセス権限を追加しました。必要な権限は、初期認証情報と認証情報の仕様の保存に選択した方法によって異なります。
  + 初期認証情報に*ドメインレス gMSA* を使用する場合は、タスク実行ロールに AWS Secrets Manager の IAM アクセス許可が必要です。
  + 認証情報の仕様を SSM Parameter Store に保存する場合は、タスク実行ロールで Amazon EC2 Systems Manager Parameter Store に対する 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>
**インフラストラクチャを準備する**  
次のステップは、考慮事項と 1 回実行される設定です。これらのステップを完了したら、コンテナインスタンスの作成を自動化して、この設定を再利用できます。

初期認証情報の提供方法を決定し、再利用可能な 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>

**ユーザーデータを使用してインスタンスを参加させる**

       Active Directory ドメインを EC2 起動テンプレートの 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 リソースネーム (ARN) が含まれています。

        Windows では、`PluginGUID` は次のスニペットの例の GUID と一致する必要があります。Linux では、`PluginGUID` は無視されます。`MySecret` の例を、シークレットの Amazon リソースネーム (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` デーモンをインストールできます。次の例は、2 種類のユーザーデータ (`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
     ```

   `/etc/ecs/ecs.config` で設定できる `credentials-fetcher` デーモンのオプションの設定変数があります。YAML ブロック内のユーザーデータに変数を設定するか、`heredoc`前の例と同様に変数を設定することをお勧めします。これにより、1 つのファイルを複数回編集した場合に発生する、部分的な構成に関する問題を回避できます。ECS エージェントの設定の詳細については、GitHub の「[Amazon ECS コンテナエージェント](https://github.com/aws/amazon-ecs-agent/blob/master/README.md#environment-variables)」を参照してください。
   + オプションで、`credentials-fetcher` デーモン設定を変更してソケットを別の場所に移動する場合は、この変数 `CREDENTIALS_FETCHER_HOST` を使用できます。

**許可とシークレットの設定**  
各アプリケーションおよび各タスク定義のために、次のステップを 1 回実行します。最小特権を認めるというベストプラクティスに従い、ポリシーで使用されるアクセス許可を絞り込むことをお勧めします。これにより、各タスクは必要なシークレットのみを読み取れます。

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

**(オプション) ドメインレス gMSA シークレット**

   インスタンスがドメインに参加していないドメインレス方式を使用する場合は、次のステップに従います。

   次の権限をインラインポリシーとしてタスク実行 IAM ロールに追加する必要があります。これにより、`credentials-fetcher` デーモンが Secrets Manager シークレットにアクセスできるようになります。`MySecret` の例を、`Resource` リスト内のシークレットの Amazon リソースネーム (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 Parameter Store または 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 リソースネーム (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 Parameter Store パラメータに認証情報仕様を追加します。タスク定義の `credentialSpecs` フィールドで SSM パラメータストアパラメータの Amazon リソースネーム (ARN) を参照します。

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

     タスクに SSM Parameter Store パラメータへのアクセスを許可するには、次のアクセス許可をインラインポリシーとして 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」の作成**  
CredSpec を作成するには、ドメインに参加している Windows コンピューター上の CredSpec PowerShell モジュールを使用します。Microsoft Learn Web サイトの「[認証情報の仕様を作成する](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 認証をサポートします。

Linux Core アプリケーションなどの .NET ベースのネットワークアプリケーションは、Active Directory を使用して、ユーザーとサービス間の認証と認可の管理を円滑化することができます。この機能は、Active Directory と統合され、ドメインに参加しているサーバー上で実行されるアプリケーションを設計することで利用できます。しかし、Linux コンテナはドメインに参加できないため、gMSA を使用して実行する Linux コンテナを設定する必要があります。

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

Fargate で Linux コンテナ向けに gMSA を使用する前に、次の点を考慮してください。
+ プラットフォームバージョン 1.4 以降を実行している必要があります。
+ 前提条件を完全に満たすには、ドメインに参加している Windows コンピュータが必要になる場合があります。例えば、PowerShell を使用して Active Directory で gMSA を作成するには、ドメインに参加している Windows コンピュータが必要になる場合があります。RSAT Active 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 バケットに保存します。
+ 1 つのタスクでサポートできるアクティブディレクトリは 1 つだけです。

## 前提条件
<a name="fargate-linux-gmsa-prerequisites"></a>

gMSA を使用する前に、Amazon ECS の Linux コンテナ機能のために必ず以下を完了してください。
+ コンテナがアクセスするリソースを含む 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 ユーザーガイド*」の「[バケットの作成](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>
**インフラストラクチャを準備する**  
次のステップは、考慮事項と 1 回実行される設定です。
+ <a name="fargate-linux-gmsa-initial-domainless"></a>

**ドメインレス gMSA 用に Active Directory ユーザーを作成する**

  ドメインレス gMSAを使用する場合、コンテナはドメインに接続されません。コンテナ上で実行される他のアプリケーションは、Active Directory の認証情報を使用してドメインにアクセスすることはできません。別のドメインを使用するタスクも同じコンテナ上で実行できます。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 とサブネットがあります。DHCP オプションを使用して、Active Directory サービス名を指すドメイン名で VPC を設定します。VPC 向け DHCP オプション設定の詳細については、「*Amazon Virtual Private Cloud ユーザーガイド*」の「[DHCP オプションセットの使用](https://docs.aws.amazon.com/vpc/latest/userguide/DHCPOptionSet.html)」を参照してください。

  1. AWS Secrets Manager にシークレットを作成 

  1. 認証情報仕様ファイルを作成します。

**許可とシークレットの設定**  
各アプリケーションおよび各タスク定義ごとに、次のステップを 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 リソースネーム (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 リソースネーム (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 にアップロードする**  
CredSpec を作成するには、ドメインに参加している Windows コンピューター上の CredSpec PowerShell モジュールを使用します。Microsoft Learn Web サイトの「[認証情報の仕様を作成する](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#create-a-credential-spec)」のステップに従います。

認証情報仕様ファイルを作成したら、Amazon S3 バケットにアップロードします。AWS CLI コマンドを実行しているコンピューターまたは環境に CredSpec ファイルをコピーします。

次の AWS CLI コマンドを実行し、Amazon S3 に CredSpec をアップロードします。`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` および互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。

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

# AWS CLI を使用するドメインレス gMSA で Amazon ECS Windows コンテナを使用する
<a name="tutorial-gmsa-windows"></a>

次のチュートリアルでは、AWS CLI を使用して Active Directory にアクセスするための認証情報を持つ Windows コンテナを実行する Amazon ECS タスクを作成する方法を示します。ドメインレス gMSA を使用すると、コンテナインスタンスはドメインに参加せず、インスタンス上の他のアプリケーションは認証情報を使用してドメインにアクセスできなくなり、異なるドメインに参加するタスクを同じインスタンス上で実行できます。

**Topics**
+ [前提条件](#tutorial-gmsa-windows-prerequisites)
+ [ステップ 1: Active Directory ドメイン サービス (AD DS) で gMSA アカウントを作成して設定する](#tutorial-gmsa-windows-step1)
+ [ステップ 2: Secrets Manager に認証情報をアップロードする](#tutorial-gmsa-windows-step2)
+ [ステップ 3: CredSpec JSON を変更してドメインレス gMSA 情報を含める](#tutorial-gmsa-windows-step3)
+ [ステップ 4： Amazon S3 に CredSpec をアップロードする](#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、SDK、および 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/ja_jp/AmazonECS/latest/developerguide/tutorial-gmsa-windows.html)
+ (任意) AWS CloudShell は、お客様が独自の EC2 インスタンスを作成する必要なく、コマンドラインを提供するツールです。詳細については、「*AWS CloudShell ユーザーガイド*」の「[What is AWS CloudShell?](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)」を参照してください。

## ステップ 1: Active Directory ドメイン サービス (AD DS) で gMSA アカウントを作成して設定する
<a name="tutorial-gmsa-windows-step1"></a>

Active Directory ドメインの gMSA アカウントを作成して設定します。

**注記**  
このステップでは、コンテナの ID を提供するグループ管理サービスアカウント (gMSA) と、ドメイン認証に使用される通常のユーザーアカウントの 2 つの個別のアカウントを作成します。これらのアカウントは目的が異なるため、異なる名前を付ける必要があります。

1. 

**Key Distribution Service のルートキーを生成する**
**注記**  
Directory Service を使用している場合は、このステップを省略できます。

   KDS ルートキーと gMSA アクセス許可は、AWS マネージド Microsoft AD で構成されます。

   ドメインに 1 つの gMSA Service Account をまだ作成していない場合は、まず Key Distribution Service (KDS) ルートキーを生成する必要があります。KDS は、gMSA パスワードの作成、ローテーション、承認されたホストへのパスワードのリリースを担います。`ccg.exe` が gMSA 認証情報を取得する必要がある場合は、KDS に連絡して現在のパスワードを取得します。

   KDS ルート キーが既に作成されているかどうかを確認するには、`ActiveDirectory` PowerShell モジュールを使用して、ドメインコントローラー上でドメイン管理者権限で次の PowerShell コマンドレットを実行します。モジュールの詳細については、Microsoft Learn Web サイトの「[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` は、キーがすぐに有効になることを暗示していますが、KDS ルートキーが複製され、すべてのドメインコントローラーで使用できるようになるまで 10 時間待つ必要があります。

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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。
+ AWS CLI コマンドを実行し、ユーザー名、パスワード、ドメイン名を環境に合わせて置き換えます。ユーザー名には、サービスユーザーアカウント名 (gMSA アカウント名ではない) を使用します。シークレットの ARN を保管して次のステップ [ステップ 3: CredSpec JSON を変更してドメインレス gMSA 情報を含める](#tutorial-gmsa-windows-step3) で使用します。

  次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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 Web サイトの「[ドメイン結合されていないコンテナホストのユースケース向けの追加の認証情報仕様設定](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:aws:ssm:aws-region:111122223333:parameter/gmsa-plugin-input\"` の ARN を使用して SSM Parameter Store でシークレットを使用できます。

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： Amazon S3 に CredSpec をアップロードする
<a name="tutorial-gmsa-windows-step4"></a>



このステップでは、AWS CLI を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

1. AWS CLI コマンドを実行しているコンピューターまたは環境に CredSpec ファイルをコピーします。

1. 次の AWS CLI コマンドを実行し、Amazon S3 に CredSpec をアップロードします。`MyBucket` をお使いの Amazon S3 バケットの名前に置き換えます。ファイルは任意のバケットと場所にオブジェクトとして保存できますが、タスク実行ロールにアタッチするポリシーでそのバケットと場所へのアクセスを許可する必要があります。

   次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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、SDK、CloudFormation でデフォルトで使用されます。追加のクラスターを使用してタスクとインフラストラクチャをグループ化および整理し、一部の構成にデフォルトを割り当てることができます。

クラスターは、AWS マネジメントコンソール、AWS CLI、SDK、または CloudFormation のいずれかを使用して作成できます。クラスター内の設定と構成は gMSA に影響しません。

このステップでは、AWS CLI を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

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

**重要**  
独自のクラスターを作成することを選択する場合は、そのクラスターで使用する予定のコマンドごとに `--cluster clusterName` を指定する必要があります。

## ステップ 6: コンテナインスタンスの IAM ロールを作成する
<a name="tutorial-gmsa-windows-step6"></a>

*コンテナインスタンス*は、Amazon EC2 インスタンスなどの ECS タスクでコンテナを実行するホストコンピュータです。各コンテナインスタンスは 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 Framework*」の「[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 バケットと場所に置き換え、2 番目の `Resource` を Secrets Manager のシークレットの ARN に置き換えます。

   Secrets Manager でカスタムキーを使用してシークレットを暗号化する場合は、そのキー の `kms:Decrypt` も許可する必要があります。

   Secrets Manager の代わりに SSM Parameter Store を使用する場合は、`secretsmanager:GetSecretValue` の代わりにパラメータの `ssm:GetParameter` を許可する必要があります。

------
#### [ 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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

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` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

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` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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. AWS マネジメントコンソール で Amazon ECS 用に設定された Amazon EC2 Windows インスタンスを起動するには、「[Amazon ECS Windows コンテナインスタンスの起動](launch_window-container_instance.md)」を参照してください。*ユーザーデータ*のステップで停止します。

1. gMSA には、ECS コンテナエージェントを開始する前に、ユーザーデータで環境変数 `ECS_GMSA_SUPPORTED` を設定する必要があります。

   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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

1. クラスター内のコンテナインスタンスをリストします。コンテナインスタンスの ID は EC2 インスタンスの ID とは異なります。

   ```
   $ aws ecs list-container-instances
   ```

   出力:

   ```
   {
       "containerInstanceArns": [
           "arn:aws:ecs:aws-region:111122223333:container-instance/default/MyContainerInstanceID"
       ]
   }
   ```

   例えば、`526bd5d0ced448a788768334e79010fd` は有効なコンテナインスタンス ID です。

1. 前のステップのコンテナインスタンス ID を使用して、コンテナインスタンスの詳細を取得します。`MyContainerInstanceID` を ID に置き換えます。

   次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

1. 

   次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは PowerShell と互換性がありません。PowerShell で使用するには、コマンドを変更する必要があります。

   ```
   aws ecs run-task --task-definition windows-gmsa-domainless-task \
       --enable-execute-command --cluster windows-domainless-gmsa-cluster
   ```

   コマンドによって返されるタスク ID をメモします。

1. 次のコマンドを実行して、タスクが開始されたことを確認します。このコマンドは、タスクが開始されるまで待機し、シェルプロンプトを返しません。`MyTaskID` を前のステップのタスク ID に置き換えます。

   ```
   $ aws ecs wait tasks-running --task MyTaskID
   ```

## ステップ 13: コンテナに gMSA 認証情報があることを検証する
<a name="tutorial-gmsa-windows-step13"></a>

タスク内のコンテナに Kerberos トークン gMSA があることを確認します。

このステップでは、AWS CLI を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

1. 

   次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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 を使用します。AWS CloudShell のこれらのコマンドは、デフォルトのシェルである `bash` で実行できます。

1. タスクを停止します。`MyTaskID` をステップ 12 のタスク ID [ステップ 12: Windows タスクを実行する](#tutorial-gmsa-windows-step12) に置き換えます。

   ```
   $ aws ecs stop-task --task MyTaskID
   ```

1. Amazon EC2 インスタンスを停止します。その後、クラスター内のコンテナインスタンスは 1 時間後に自動で削除されます。

   Amazon EC2 コンソールを使用し、インスタンスを検索して終了できます。または、以下のコマンドを実行できます。コマンドを実行するには、ステップ 1、[ステップ 11: コンテナインスタンスを検証する](#tutorial-gmsa-windows-step11) の `aws ecs describe-container-instances` コマンドの出力で EC2 インスタンス ID を見つけます。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 Parameter Store を使用した場合は、パラメータを削除してください。

   次のコマンドでは、`sh` と互換性のあるシェルで使用されるバックスラッシュ継続文字を使用します。このコマンドは 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 はタスクを 1 回のみ開始しようとします。問題のあるタスクはすべて停止され、`STOPPED` 状態に設定されます。タスクに関する一般的な問題には 2 つのタイプがあります。最初に、開始できなかったタスクです。2 つ目は、アプリケーションがいずれかのコンテナ内で停止したタスクです。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 Web サイトの「[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 コンテナはドメインに結合できないため、gMSA で実行するように Windows コンテナを設定する必要があります。

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 コンテナに gMSAs を使用する場合は、次の点を考慮する必要があります。
+ コンテナインスタンスに 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/ja_jp/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 Parameter Store に保存する場合は、タスク実行ロールで Amazon EC2 Systems Manager Parameter Store に対する IAM 許可が必要です。
  + 認証情報の仕様を Amazon S3 で保存する場合は、タスク実行ロールで Amazon Simple Storage Service の IAM 許可が必要です。

## Amazon ECS での Windows コンテナ向け gMSA の設定
<a name="windows-gmsa-setup"></a>

前提条件 [AWS CLI を使用するドメインレス gMSA で Amazon ECS Windows コンテナを使用する](tutorial-gmsa-windows.md) の設定を含む完全なチュートリアルに従い、Windows コンテナ向け gMSA を Amazon ECS 上で設定できます。

次のセクションでは、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 Parameter Store のシークレットの ARN を含む情報を CredSpec に追加します。詳細については、Microsoft Learn Web サイトの「[ドメイン結合されていないコンテナホストのユースケース向けの追加の認証情報仕様設定](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 Parameter Store に保存します。

   ```
   {
       "username":"WebApp01",
       "password":"Test123!",
       "domainName":"contoso.com"
   }
   ```

1. `ActiveDirectoryConfig` 内部の CredSpec ファイルに以下の情報を追加します。ARN を Secrets Manager または SSM Parameter Store のシークレットに置き換えます。

   `PluginGUID` 値は次のサンプルのスニペットの GUID と一致する必要があり、必須であることに注意してください。

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

   また、この形式 `\"arn:aws:ssm:aws-region:111122223333:parameter/gmsa-plugin-input\"` の ARN を使用して SSM Parameter Store でシークレットを使用できます。

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 リソースネーム (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 リソースネーム (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 に最適化された AMI の使用をお勧めしています。ソフトウェアの追加には AMI のカスタマイズが必要になる場合があります。EC2 Image Builder は、サーバーイメージの作成、管理、デプロイに使用できます。アカウントで作成されるカスタムイメージの所有権は、お客様に保持されます。EC2 Image Builder パイプラインを使用してイメージの更新やシステムパッチを自動化したり、スタンドアロンコマンドを使用して定義済みの設定リソースでイメージを作成することができます。

イメージのレシピを作成します。レシピには親画像とその他の追加コンポーネントが含まれます。さらに、カスタマイズした AMI を配信するパイプラインを作成します。

イメージのレシピを作成します。Image Builder イメージレシピは、ベースイメージとベースイメージに適用するコンポーネントを定義し、必要な構成の出力イメージを生成するためのドキュメントです。さらに、カスタマイズした AMI を配信するパイプラインを作成します。詳細については、「*EC2 Image Builder ユーザーガイド*」の「[EC2 Image Builder の仕組み](https://docs.aws.amazon.com/imagebuilder/latest/userguide/how-image-builder-works.html)」を参照してください。

EC2 Image Builder の「親イメージ」として、次の Amazon ECS に最適化された AMI のいずれかの使用をお勧めします。
+ 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
+ Server 
  + 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 ユーザーガイド*」の「[セマンティックバージョニング](https://docs.aws.amazon.com/imagebuilder/latest/userguide/ibhow-semantic-versioning.html)」を参照してください。

AWS は、Amazon ECS に最適化された AMI イメージを、セキュリティパッチと新しいコンテナエージェントバージョンで定期的に更新しています。AMI ID をイメージレシピの親イメージとして使用する場合、親イメージの更新がないかを定期的に確認する必要があります。更新がある場合は、更新した AMI を使用して新しいバージョンのレシピを作成する必要があります。これにより、カスタムイメージに最新バージョンの親イメージが組み込まれます。新しく作成した AMI を使用して Amazon ECS クラスターの EC2 インスタンスを自動的に更新するワークフローを作成する方法については、「[AMI 強化パイプラインを作成して ECS インスタンスフリートの更新を自動化する方法](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 リソースネーム (ARN) を指定することもできます。Amazon は、マネージドパイプラインを通じて、Amazon ECS 最適化 AMI イメージを定期的に公開します。これらのイメージはパブリックアクセス可能です。イメージにアクセスするには、適切なアクセス許可が必要です。Image Builder レシピで AMI の代わりにイメージ ARN を使用すると、パイプラインは実行のたびに最新バージョンの親イメージを自動的に使用します。この方法により、更新のたびに新しいレシピバージョンを手動で作成する必要がなくなります。

## 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
```

イメージの保存時に一緒に保存されないように、すべてのログファイルを現在のインスタンスから削除します。[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 最適化 AMI を作成する方法については、AWS ナレッジセンターの「[How do I create a custom AMI from an Amazon ECS-optimized AMI?](https://forums.aws.amazon.com/knowledge-center/ecs-create-custom-amis/)」を参照してください。

## イメージ ARN と Infrastructure as Code (IaC) の使用
<a name="infrastructure-as-code-arn"></a>

EC2 Image Builder コンソール、Infrastructure as Code (例: CloudFormation)、または AWS SDK を使用してレシピを設定できます。レシピで親イメージを指定する場合、EC2 AMI ID、Image Builder イメージ ARN、AWS Marketplace プロダクト ID、またはコンテナイメージを指定できます。AWS は、Amazon ECS 最適化 AMI の AMI ID と Image Builder イメージ ARN の両方を公開します。イメージの ARN 形式は以下の通りです。

```
arn:${Partition}:imagebuilder:${Region}:${Account}:image/${ImageName}/${ImageVersion}
```

`ImageVersion` の形式は以下のようになっています。*[メジャー]*、*[マイナー]*、*[パッチ]*を最新の値に置き換えます。

```
<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` の 2 つのオプション引数を受け付けます。デフォルト値はそれぞれ「Amazon」と「Windows」です。owner 引数の有効値は、`Self`、`Shared`、`Amazon`、`ThirdParty` です。プラットフォーム引数の有効値は、`Windows` と `Linux` です。たとえば、`owner` 引数を `Amazon` に設定し、`platform` を `Linux` に設定してスクリプトを実行すると、スクリプトは Amazon ECS 最適化イメージを含む、Amazon によって公開されたイメージのリストを生成します。

```
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()
```

## CloudFormation でのイメージ ARN の使用
<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 ユーザーガイド*」を参照してください。

`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 時にビルドを実行しています。以下の `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>

AWSDeep Learning Containersは、 Amazon ECS の TensorFlow と Apache MXNet(インキュベーション)のモデルをトレーニングして提供するためのDockerイメージのセットを提供します。Deep Learning Containersは、TensorFlow、NVIDIA CUDA(GPUインスタンス用)、Intel MKL(CPUインスタンス用)のライブラリを使用し、最適化された環境を実現します。Deep Learning Containers のコンテナイメージは、Amazon ECR で利用でき、Amazon ECS タスク定義で参照できます。Deep Learning Containers と Amazon Elastic Inference を併用することで、推論コストを削減できます。

Elastic Inference を使用せずに Deep Learning Containers の使用を開始するには、「*AWS Deep Learning AMIs デベロッパーガイド*」の「[Amazon ECS setup](https://docs.aws.amazon.com/deep-learning-containers/latest/devguide/deep-learning-containers-ecs-setup.html)」を参照してください。

# チュートリアル: Blue/Green デプロイを使用するサービスの作成
<a name="create-blue-green"></a>

Amazon ECS では、Blue/Green デプロイが Amazon ECS コンソールのサービスの作成ウィザードに統合されています。詳細については、「[Amazon ECS のローリング更新デプロイの作成](create-service-console-v2.md)」を参照してください。

以下のチュートリアルでは、AWS CLI で ブルー/グリーンデプロイタイプを使用する Fargate タスクを含む、Amazon ECS サービスを作成する方法を示します。

**注記**  
ブルー/グリーンデプロイを実行するためのサポートが CloudFormation に追加されています。詳細については、[*AWS CloudFormationユーザーガイド*]の[[CloudFormationを使用した CodeDeploy による Perform 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 およびセキュリティグループが使用できるように作成されていること。詳細については、「[仮想プライベートクラウドを作成する](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 を作成します。異なるアベイラビリティーゾーンにある 2 つのサブネット、およびセキュリティグループを指定します。

   ```
   aws elbv2 create-load-balancer \
        --name bluegreen-alb \
        --subnets subnet-abcd1234 subnet-abcd5678 \
        --security-groups sg-abcd1234 \
        --region us-east-1
   ```

   出力には、次の形式でロードバランサーの Amazon リソースネーム (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) コマンドを使用して、CodeDeploy デプロイ グループの作成時に使用される 2 つ目のApplication Load Balancer ターゲットグループを作成します。

   ```
   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. CodeDeploy デプロイグループの内容で `appspec.yaml` というファイルを作成します。この例では、チュートリアルの前半で作成したリソースを使用します。

      ```
      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. CodeDeploy デプロイの内容で `create-deployment.json` というファイルを作成します。この例では、チュートリアルの前半で作成したリソースを使用します。

      ```
      {
          "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) コマンドを使用して、Amazon S3 バケットから AppSpec ファイルを削除します。

   ```
   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) コマンドを使用して、2 つの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
   ```