AWS ECSをコマンド操作してみるよ

以前WebUIからECSの基本的な操作方法を理解しました。
Docker Compose的なことをするためにはコマンド操作が必須になりそうなので、ECSをコマンドで操作していきたいと思います。

https://qiita.com/ohtsuka-shota/items/c0bd0ec81858811d5422

# 手順
環境用意するのが面倒なので、CloudShellで代用
まず、コマンドでクラスタを作成します、名前をecs-command-clusterとしました
```
~ $ aws ecs create-cluster --cluster-name ecs-command-cluster
{
    "cluster": {
        "clusterArn": "arn:aws:ecs:ap-northeast-1:***:cluster/ecs-command-cluster",
        "clusterName": "ecs-command-cluster",
        "status": "ACTIVE",
        "registeredContainerInstancesCount": 0,
        "runningTasksCount": 0,
        "pendingTasksCount": 0,
        "activeServicesCount": 0,
        "statistics": [],
        "tags": [],
        "settings": [
            {
                "name": "containerInsights",
                "value": "disabled"
            }
        ],
        "capacityProviders": [],
        "defaultCapacityProviderStrategy": []
    }
}

```

作成出来ていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d3c17d29-1c80-4ef7-adb5-d8fb4a174326.png)

ECSのタスクを作成する際にJSONファイルが必要になるという事で用意していきます。
以下のコマンドをCloudShellで実行して専用のディレクトリを用意。
```
~ $ pwd
/home/cloudshell-user
~ $ mkdir ecs
~ $ cd ecs
ecs $
```

ファイルを作成
Fargateを使用するので、portMappingsでcontainerPortのみ指定。
requiresCompatibilitiesでFargateを指定。
```
ecs $ nano ecs-command-task.json 
ecs $ cat ecs-command-task.json 
{
  "family": "ecs-command-task",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "ecs-command-nextcloud-container",
      "image": "nextcloud:latest",
      "memory": 512,
      "cpu": 256,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ]
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "256",
  "memory": "512"
}
```

タスクを登録します。
```
ecs $ aws ecs register-task-definition --cli-input-json file://ecs-command-task.json 
{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:***:task-definition/ecs-command-task:2",
        "containerDefinitions": [
            {
                "name": "ecs-command-nextcloud-container",
                "image": "nextcloud:latest",
                "cpu": 256,
                "memory": 512,
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "environment": [],
                "mountPoints": [],
                "volumesFrom": [],
                "systemControls": []
            }
        ],
        "family": "ecs-command-task",
        "networkMode": "awsvpc",
        "revision": 2,
        "volumes": [],
        "status": "ACTIVE",
        "requiresAttributes": [
            {
                "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
            },
            {
                "name": "ecs.capability.task-eni"
            }
        ],
        "placementConstraints": [],
        "compatibilities": [
            "EC2",
            "FARGATE"
        ],
        "requiresCompatibilities": [
            "FARGATE"
        ],
        "cpu": "256",
        "memory": "512",
        "registeredAt": "2025-06-14T11:42:51.393000+00:00",
        "registeredBy": "arn:aws:iam::***:root"
    }
}


```

タスクが作成されていることがわかります。
リビジョンが2になっているのは一回ミスっている為。気にしない。
![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/ff7520f8-61fd-4284-ae1b-9e37e3e3aed6.png)

作成したタスクを使ってサービスを作成します。
"--desired-count 1"としていることで常に1つはタスクを実行するようにしています。
サブネットやSGのIDも必要になるので、確認してデプロイします。
```
ecs $ aws ecs create-service \
>   --cluster ecs-command-cluster \
>   --service-name ecs-command-service \
>   --task-definition ecs-command-task \
>   --desired-count 1 \
>   --launch-type FARGATE \
>   --network-configuration "awsvpcConfiguration={subnets=['subnet-***','subnet-***'],securityGroups=['sg-***'],assignPublicIp='ENABLED'}"
{
    "service": {
        "serviceArn": "arn:aws:ecs:ap-northeast-1:***:service/ecs-command-cluster/ecs-command-service",
        "serviceName": "ecs-command-service",
        "clusterArn": "arn:aws:ecs:ap-northeast-1:***:cluster/ecs-command-cluster",
        "loadBalancers": [],
        "serviceRegistries": [],
        "status": "ACTIVE",
        "desiredCount": 1,
        "runningCount": 0,
        "pendingCount": 0,
        "launchType": "FARGATE",
        "platformVersion": "LATEST",
        "platformFamily": "Linux",
        "taskDefinition": "arn:aws:ecs:ap-northeast-1:***:task-definition/ecs-command-task:2",
        "deploymentConfiguration": {
            "deploymentCircuitBreaker": {
                "enable": false,
                "rollback": false
            },
            "maximumPercent": 200,
            "minimumHealthyPercent": 100
        },
        "deployments": [
            {
                "id": "ecs-svc/2677302622911333585",
                "status": "PRIMARY",
                "taskDefinition": "arn:aws:ecs:ap-northeast-1:***:task-definition/ecs-command-task:2",
                "desiredCount": 0,
                "pendingCount": 0,
                "runningCount": 0,
                "failedTasks": 0,
                "createdAt": "2025-06-14T11:44:02.357000+00:00",
                "updatedAt": "2025-06-14T11:44:02.357000+00:00",
                "launchType": "FARGATE",
                "platformVersion": "1.4.0",
                "platformFamily": "Linux",
                "networkConfiguration": {
                    "awsvpcConfiguration": {
                        "subnets": [
                            "subnet-***",
                            "subnet-***"
                        ],
                        "securityGroups": [
                            "sg-***"
                        ],
                        "assignPublicIp": "ENABLED"
                    }
                },
                "rolloutState": "IN_PROGRESS",
                "rolloutStateReason": "ECS deployment ecs-svc/2677302622911333585 in progress."
            }
        ],
        "roleArn": "arn:aws:iam::***:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
        "events": [],
        "createdAt": "2025-06-14T11:44:02.357000+00:00",
        "placementConstraints": [],
        "placementStrategy": [],
        "networkConfiguration": {
            "awsvpcConfiguration": {
                "subnets": [
                    "subnet-***",
                    "subnet-***"
                ],
                "securityGroups": [
                    "sg-***"
                ],
                "assignPublicIp": "ENABLED"
            }
        },
        "healthCheckGracePeriodSeconds": 0,
        "schedulingStrategy": "REPLICA",
        "deploymentController": {
            "type": "ECS"
        },
        "createdBy": "arn:aws:iam::***:root",
        "enableECSManagedTags": false,
        "propagateTags": "NONE",
        "enableExecuteCommand": false,
        "availabilityZoneRebalancing": "DISABLED"
    }
}

```

サービスが作成されていることがわかります。
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/dd486a76-12a3-429d-8db5-bf361be1c244.png)
タスクも作成されています。
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/259f31f0-ee7a-4f2a-9e0b-ad969ce25455.png)
![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/35c7275c-4ee9-49dd-96cb-77d60fdda726.png)
コンテナでアプリがデプロイされていることがわかります。
![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/4fe2bd91-8a2c-4329-82d6-c2ee8ab4016a.png)

タスクをGUIから停止してもすぐに別タスクとして立ち上がってくることが確認できました。
![image (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/bef287c7-a101-47bf-944a-64f7f56fa9c5.png)

サービスを削除します
```
ecs $ aws ecs delete-service \
>   --cluster ecs-command-cluster \
>   --service ecs-command-service \
>   --force
```

![image (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/92324847-b42a-4cfa-98d5-5a0bb74e50b4.png)