AWS CLI を使って Amazon ECS のタスクを手動で実行する
2021-01-23前回はスケジュール実行されるタスクを ECS にデプロイしました。今回は、そのタスクを AWS CLI を使って手動で実行してみます。
目次
ECS タスクの作成
これに関しては、前回の記事で AWS Copilot を使ってサクッと作ったものがあるのでそれを使います。
AWS Copilot を使ってを使ってスケジュールされた ECS タスクをデプロイする - michimani.net
実行に必要な情報を取得
AWS CLI で ECS タスクを実行するには ecs run-task コマンドを使います。事前にわかっている情報として、下記の値は AWS CLI やマネコンからあらかじめ取得しておきます。
- クラスター名
- ファミリー名
- サブネットの ID
- セキュリティグループの ID
ecs run-task のヘルプを見てもらうとオプションの数が割と多いとがわかります。
$ aws ecs run-task help
...
SYNOPSIS
            run-task
          [--capacity-provider-strategy <value>]
          [--cluster <value>]
          [--count <value>]
          [--enable-ecs-managed-tags | --no-enable-ecs-managed-tags]
          [--group <value>]
          [--launch-type <value>]
          [--network-configuration <value>]
          [--overrides <value>]
          [--placement-constraints <value>]
          [--placement-strategy <value>]
          [--platform-version <value>]
          [--propagate-tags <value>]
          [--reference-id <value>]
          [--started-by <value>]
          [--tags <value>]
          --task-definition <value>
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
今回は必要最低限のオプションで実行することを目的とします。なので、指定するオプションは下記のとおりです。
- --cluster: 対象のクラスターの名前
- --task-definition: タスク定義の ARN
- --network-configuration: ネットワーク情報 (サブネット、セキュリティグループ)
- --launch-type: 起動タイプ
- --overrides: コンテナの上書き
事前にわかっている情報は変数に設定し、それ以外に必要な値を以降で取得していきます。
CLUSTER_NAME="hello-ecs-test-Cluster-XXXXXXXXXXXX"
SUBNET_ID="subnet-00a78dcxxxxxxxxxx"
SG_ID="sg-0600d2cxxxxxxxxxx"
FAMILY_NAME="hello-ecs-test-hello-ecs-job"
タスク定義の ARN
タスク定義は複数存在する場合があるので、最新リビジョンの ARN を取得します。
その前に、 Family Name を取得します。
$ TASK_DEF_ARN=$(aws ecs list-task-definitions \
--family-prefix "${FAMILY_NAME}" \
--query "reverse(taskDefinitionArns)[0]" \
--output text) \
&& echo "${TASK_DEF_ARN}"
arn:aws:ecs:ap-northeast-1:000000000000:task-definition/hello-ecs-test-hello-ecs-job:4
ネットーワーク情報
事前にわかっているサブネットおよびセキュリティグループの ID  をもと、 --network-configuration で指定する文字列を生成しておきます。
NETWORK_CONFIG="awsvpcConfiguration={subnets=[${SUBNET_ID}],securityGroups=[${SG_ID}],assignPublicIp=ENABLED}"
実行
必要な情報が準備できたので、実行します。
$ aws ecs run-task \
--cluster "${CLUSTER_NAME}" \
--task-definition "${TASK_DEF_ARN}" \
--network-configuration "${NETWORK_CONFIG}" \
--launch-type FARGATE
{
    "tasks": [
        {
            "attachments": [
                {
                    "id": "6fd9a03c-2d49-41bf-afca-a883cce4f42f",
                    "type": "ElasticNetworkInterface",
                    "status": "PRECREATED",
                    "details": [
                        {
                            "name": "subnetId",
                            "value": "subnet-00a78dcxxxxxxxxxx"
                        }
                    ]
                }
            ],
            "availabilityZone": "ap-northeast-1a",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:000000000000:cluster/hello-ecs-test-Cluster-XXXXXXXXXXXX",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:ap-northeast-1:000000000000:container/96bf19a1-2e9a-4922-af8b-9a9336ec3498",
                    "taskArn": "arn:aws:ecs:ap-northeast-1:000000000000:task/hello-ecs-test-Cluster-XXXXXXXXXXXX/d17f05dc06ed4cedxxxxxxxxxxxxxxxxx",
                    "name": "hello-ecs-job",
                    "image": "000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/hello-ecs/hello-ecs-job:783bf7b",
                    "lastStatus": "PENDING",
                    "networkInterfaces": [],
                    "cpu": "0"
                }
            ],
            "cpu": "256",
            "createdAt": "2021-01-23T14:47:41.760000+09:00",
            "desiredStatus": "RUNNING",
            "group": "family:hello-ecs-test-hello-ecs-job",
            "lastStatus": "PROVISIONING",
            "launchType": "FARGATE",
            "memory": "512",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "hello-ecs-job"
                    }
                ],
                "inferenceAcceleratorOverrides": []
            },
            "platformVersion": "1.3.0",
            "tags": [],
            "taskArn": "arn:aws:ecs:ap-northeast-1:000000000000:task/hello-ecs-test-Cluster-XXXXXXXXXXXX/d17f05dc06ed4cedxxxxxxxxxxxxxxxxx",
            "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:000000000000:task-definition/hello-ecs-test-hello-ecs-job:4",
            "version": 1
        }
    ],
    "failures": []
}
出力として、作成された実行タスクの情報が出力されます。 しばらくすると Slack に 「Hello ECS!!!」 というメッセージが届きます。
 
  コンテナを上書きして実行
今回実行しているアプリケーションは、実行時のコマンドラインオプション -m で Slack にポストするメッセージを指定することができます。このように、コンテナ実行時のコマンドなどを上書きしたい場合は --overrides オプションで JSON 形式の値を指定します。指定するのはファイルでもよいので、下記のコマンドで override.json を作成します。
$ ONTAINER_NAME=$(aws ecs describe-task-definition \
--task-definition "${TASK_DEF_ARN}" \
--query "taskDefinition.containerDefinitions[0].name" \
--output text) \
&& cat <<EOF > overrides.json
  {
    "containerOverrides": [
      {
        "name": "${ONTAINER_NAME}",
        "command": ["-m", "Hello Amazon DynamoDB !!!"]
      }
    ]
  }
EOF
内容を確認しておきます。 (エラーが出なければ OK です)
$ python3 -m json.tool ./overrides.json
{
    "containerOverrides": [
        {
            "name": "hello-ecs-job",
            "command": [
                "-m",
                "Hello Amazon DynamoDB !!!"
            ]
        }
    ]
}
作成した overrides.json を --overrides で指定して実行してみます。
$ aws ecs run-task \
--cluster "${CLUSTER_NAME}" \
--task-definition "${TASK_DEF_ARN}" \
--network-configuration "${NETWORK_CONFIG}" \
--launch-type FARGATE \
--overrides file://overrides.json
 
  まとめ
AWS CLI で ECS のタスクを手動で実行してみた話でした。
今回の手順で可変な部分は、おそらくコンテナ上書き時のコマンドくらいなので、何度も手動実行するような機会があるなら今回の手順をスクリプト化しておくと楽かもしれません。