[JAWS-UG CLI] ECS #2 タスク定義の登録、タスク実行、削除

AWS CLIを利用して、ECS上にタスク定義を登録、タスク実行、タスク定義の削除をしてみます。

参考: http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_AWSCLI.html#AWSCLI_register_task_definition



前提条件
========


ECSへの権限
-----------

* ECSに対してフル権限があること。


AWS CLIのバージョン
-------------------

* 以下のバージョンで動作確認済

  * AWS CLI 1.7.36

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.7.28 Python/2.7.5 Darwin/13.4.0
```


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile   ec2ecs_full-prjZ-mbp13              env    AWS_DEFAULT_PROFILE
      access_key     ****************LOAQ shared-credentials-file
      secret_key     ****************I1O1 shared-credentials-file
          region           ap-northeast-1              env    AWS_DEFAULT_REGION
```

1. 事前作業
===========


1.1. タスク定義名の決定
-----------------------

```bash:変数の設定:
ECS_TASK_DEFINITION_NAME='sleep360'
```

同じ名前のタスク定義名が存在しないことを確認します。

```bash:コマンド:
aws ecs describe-task-definition \
        --task-definition ${ECS_TASK_DEFINITION_NAME}
```

```text:結果(例):
      A client error (ClientException) occurred when calling the DescribeTaskDefinition operation: Unable to describe task definition.
```


1.2. タスク定義ファイルの作成
-----------------------------

```bash:変数の設定:
FILE_ECS_TASK_DEFINITION='sleep360.json'
```

```bash:コマンド:
cat << EOF > ${FILE_ECS_TASK_DEFINITION}
{
        "containerDefinitions": [
          {
            "name": "sleep",
            "image": "busybox",
            "cpu": 10,
            "command": [
              "sleep",
              "360"
            ],
            "memory": 10,
            "essential": true
          }
        ],
        "family": "sleep360"
}
EOF
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
jsonlint -q ${FILE_ECS_TASK_DEFINITION}
```

```text:結果:
      (戻り値なし)
```


2. タスク定義の登録
===================


2.1. タスク定義の作成
---------------------

```bash:コマンド:
aws ecs register-task-definition \
        --cli-input-json file://${FILE_ECS_TASK_DEFINITION}
```

```json:結果(例):
      {
        "taskDefinition": {
          "status": "ACTIVE",
          "family": "sleep360",
          "volumes": [],
          "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
          "containerDefinitions": [
              {
                  "environment": [],
                  "name": "sleep",
                  "mountPoints": [],
                  "image": "busybox",
                  "cpu": 10,
                  "portMappings": [],
                  "command": [
                      "sleep",
                      "360"
                  ],
                  "memory": 10,
                  "essential": true,
                  "volumesFrom": []
              }
          ],
          "revision": 1
        }
      }
```


2.2. タスク定義の一覧確認
-------------------------

```bash:コマンド:
aws ecs list-task-definition-families \
        --family-prefix ${ECS_TASK_DEFINITION_NAME}
```

```json:結果(例):
      {
        "families": [
          "sleep360"
        ]
      }
```

```bash:コマンド:
aws ecs list-task-definitions \
         --family-prefix ${ECS_TASK_DEFINITION_NAME}
```

```json:結果(例):
      {
        "taskDefinitionArns": [
          "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1"
        ]
      }
```


2.3. タスク定義の確認
---------------------

```bash:コマンド:
aws ecs describe-task-definition \
        --task-definition ${ECS_TASK_DEFINITION_NAME}
```

```json:結果(例)
      {
        "taskDefinition": {
          "status": "ACTIVE",
          "family": "sleep360",
          "volumes": [],
          "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
          "containerDefinitions": [
              {
                  "environment": [],
                  "name": "sleep",
                  "mountPoints": [],
                  "image": "busybox",
                  "cpu": 10,
                  "portMappings": [],
                  "command": [
                      "sleep",
                      "360"
                  ],
                  "memory": 10,
                  "essential": true,
                  "volumesFrom": []
              }
          ],
          "revision": 1
        }
      }
```


3. タスクの実行
===============


3.1. タスクの実行インスタンス数の指定
-------------------------------------

```bash:変数の設定:
ECS_INSTANCE_COUNT='1'
```


3.2. タスクの実行
-----------------

```bash:変数の確認:
cat << ETX

        ECS_TASK_DEFINITION_NAME: ${ECS_TASK_DEFINITION_NAME}
        ECS_CLUSTER_NAME: ${ECS_CLUSTER_NAME}
        ECS_INSTANCE_COUNT: ${ECS_INSTANCE_COUNT}

ETX
```

```bash:コマンド:
aws ecs run-task \
        --task-definition ${ECS_TASK_DEFINITION_NAME} \
        --cluster ${ECS_CLUSTER_NAME} \
        --count ${ECS_INSTANCE_COUNT}
```

```json:結果(例):
      {
        "failures": [],
        "tasks": [
          {
              "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "overrides": {
                  "containerOverrides": [
                      {
                          "name": "sleep"
                      }
                  ]
              },
              "lastStatus": "PENDING",
              "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container-instance/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "clusterArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:cluster/handson-cluster",
              "desiredStatus": "RUNNING",
              "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
              "containers": [
                  {
                      "containerArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                      "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                      "lastStatus": "PENDING",
                      "name": "sleep"
                  }
              ]
          }
        ]
      }
```


3.3. タスク一覧の確認
---------------------

```bash:コマンド:
aws ecs list-tasks \
        --cluster ${ECS_CLUSTER_NAME}
```

```json:結果(例):
      {
        "taskArns": [
          "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        ]
      }
```


3.4. 稼動タスクの内容確認
-------------------------

```bash:コマンド:
ARRAY_ECS_TASKS_UUID=$( \
        aws ecs list-tasks \
          --cluster ${ECS_CLUSTER_NAME} \
          --query 'taskArns[]' \
          --output text | \
        sed 's|^arn:.*/||' \
) \
        && echo ${ARRAY_ECS_TASKS_UUID}
```

```text:結果(例)
      xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

```bash:コマンド:
aws ecs describe-tasks \
        --tasks "${ARRAY_ECS_TASKS_UUID}" \
        --cluster ${ECS_CLUSTER_NAME}
```

```json:結果(例):
      {
        "failures": [],
        "tasks": [
          {
              "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/f703ae48-07a0-410c-9ee5-c1e894512445",
              "overrides": {
                  "containerOverrides": [
                      {
                          "name": "sleep"
                      }
                  ]
              },
              "lastStatus": "RUNNING",
              "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container-instance/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "clusterArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:cluster/handson-cluster",
              "desiredStatus": "RUNNING",
              "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
              "containers": [
                  {
                      "containerArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                      "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                      "name": "sleep",
                      "networkBindings": [],
                      "lastStatus": "RUNNING",
                      "exitCode": 0
                  }
              ]
            }
          ]
        }
```

```bash:変数の設定:
ECS_TASK_UUID=$(echo ${ARRAY_ECS_TASKS_UUID} | sed 's/ .*$//') \
          && echo ${ECS_TASK_UUID}
```


3.5. 稼動タスクの中断
---------------------

```bash:変数の確認:
cat << ETX

        ECS_TASK_UUID:    ${ECS_TASK_UUID}
        ECS_CLUSTER_NAME: ${ECS_CLUSTER_NAME}

ETX
```

```bash:コマンド:
aws ecs stop-task \
        --task ${ECS_TASK_UUID} \
        --cluster ${ECS_CLUSTER_NAME}
```

```json:結果(例):
      {
        "task": {
          "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/824a4122-be46-4371-b85d-896c3f0ba33e",
          "overrides": {
              "containerOverrides": [
                  {
                      "name": "sleep"
                  }
              ]
          },
          "lastStatus": "RUNNING",
          "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container-instance/2e6ab46e-6696-4a7c-b948-f7cbcd983b01",
          "clusterArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:cluster/handson-cluster",
          "desiredStatus": "STOPPED",
          "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
          "containers": [
              {
                  "containerArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container/f2b6cf52-5b37-4775-baff-bedfa21fb04c",
                  "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/824a4122-be46-4371-b85d-896c3f0ba33e",
                  "name": "sleep",
                  "networkBindings": [],
                  "lastStatus": "RUNNING",
                  "exitCode": 0
              }
          ]
        }
      }
```

```bash:コマンド:
ECS_TASK_STATUS_DESIRED=$( \
        aws ecs describe-tasks \
          --tasks "${ARRAY_ECS_TASKS_UUID}" \
          --cluster ${ECS_CLUSTER_NAME} \
          --query 'tasks[].desiredStatus' \
          --output text \
) \
        && echo ${ECS_TASK_STATUS_DESIRED}
```

```text:結果(例):
      STOPPED
```

```bash:コマンド:
ECS_TASK_STATUS_LAST=$( \
        aws ecs describe-tasks \
          --tasks "${ARRAY_ECS_TASKS_UUID}" \
          --cluster ${ECS_CLUSTER_NAME} \
          --query 'tasks[].lastStatus' \
          --output text \
) \
        && echo ${ECS_TASK_STATUS_LAST}
```

```text:結果(例):
      STOPPED
```


3.6. 特定のコンテナインスタンスでのタスクの実行&停止
----------------------------------------------------

```bash:変数の確認:
cat << ETX

        ECS_TASK_DEFINITION_NAME: ${ECS_TASK_DEFINITION_NAME}
        ECS_CLUSTER_NAME:         ${ECS_CLUSTER_NAME}
        ECS_INSTANCES:           "${ECS_INSTANCES}"

ETX
```

```bash:コマンド:
aws ecs start-task \
        --task-definition ${ECS_TASK_DEFINITION_NAME} \
        --cluster ${ECS_CLUSTER_NAME} \
        --container-instances "${ECS_INSTANCES}"
```


```json:結果(例):
      {
        "failures": [],
        "tasks": [
          {
              "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/3322b402-ab6b-4d22-98bc-e2f48a83dc63",
              "overrides": {
                  "containerOverrides": [
                      {
                          "name": "sleep"
                      }
                  ]
              },
              "lastStatus": "PENDING",
              "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container-instance/2e6ab46e-6696-4a7c-b948-f7cbcd983b01",
              "clusterArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:cluster/handson-cluster",
              "desiredStatus": "RUNNING",
              "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
              "containers": [
                  {
                      "containerArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:container/b907fa72-2efb-4120-affe-0f70cd32005e",
                      "taskArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/3322b402-ab6b-4d22-98bc-e2f48a83dc63",
                      "lastStatus": "PENDING",
                      "name": "sleep"
                  }
              ]
          }
        ]
      }
```

```bash:コマンド:
ARRAY_ECS_TASKS_UUID=$( \
        aws ecs list-tasks \
          --cluster ${ECS_CLUSTER_NAME} \
          --query 'taskArns[]' \
          --output text | \
        sed 's|^arn:.*/||' \
) \
        && echo ${ARRAY_ECS_TASKS_UUID}
```

```text:結果(例)
      xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

```bash:変数の確認:
cat << ETX

        ECS_TASK_UUID:    ${ECS_TASK_UUID}
        ECS_CLUSTER_NAME: ${ECS_CLUSTER_NAME}

ETX
```

```bash:コマンド:
aws ecs stop-task \
        --task ${ECS_TASK_UUID} \
        --cluster ${ECS_CLUSTER_NAME}
```

```bash:コマンド:
ECS_TASK_STATUS_LAST=$( \
        aws ecs describe-tasks \
          --tasks "${ARRAY_ECS_TASKS_UUID}" \
          --cluster ${ECS_CLUSTER_NAME} \
          --query 'tasks[].lastStatus' \
          --output text \
) \
        && echo ${ECS_TASK_STATUS_LAST}
```

```text:結果(例):
      STOPPED
```


4. タスク定義の削除
===================

タスク定義の削除には、リビジョン情報が必要になるので、タスク定義から取得します。

```bash:コマンド:
ECS_TASK_DEFINITION_REVISION=$( \
        aws ecs describe-task-definition \
          --task-definition ${ECS_TASK_DEFINITION_NAME} \
          --query 'taskDefinition.revision' \
          --output text \
) \
        && echo ${ECS_TASK_DEFINITION_REVISION}
```

```bash:変数の確認:
cat << ETX

        ECS_TASK_DEFINITION_NAME:     ${ECS_TASK_DEFINITION_NAME}
        ECS_TASK_DEFINITION_REVISION: ${ECS_TASK_DEFINITION_REVISION}

ETX
```

```bash:コマンド:
aws ecs deregister-task-definition \
        --task-definition ${ECS_TASK_DEFINITION_NAME}:${ECS_TASK_DEFINITION_REVISION}
```

```json:結果(例):
      {
        "taskDefinition": {
          "status": "INACTIVE",
          "family": "sleep360",
          "volumes": [],
          "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/sleep360:1",
          "containerDefinitions": [
              {
                  "environment": [],
                  "name": "sleep",
                  "mountPoints": [],
                  "image": "busybox",
                  "cpu": 10,
                  "portMappings": [],
                  "command": [
                      "sleep",
                      "360"
                  ],
                  "memory": 10,
                  "essential": true,
                  "volumesFrom": []
              }
          ],
          "revision": 1
        }
      }
```

```bash:コマンド:
aws ecs describe-task-definition \
        --task-definition ${ECS_TASK_DEFINITION_NAME}
```

```text:結果(例):
      A client error (ClientException) occurred when calling the DescribeTaskDefinition operation: Unable to describe task definition.
```


完了
====