michimani.net

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 やマネコンからあらかじめ取得しておきます。

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_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!!!」 というメッセージが届きます。

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
Hello Amazon DynamoDB

まとめ

AWS CLI で ECS のタスクを手動で実行してみた話でした。
今回の手順で可変な部分は、おそらくコンテナ上書き時のコマンドくらいなので、何度も手動実行するような機会があるなら今回の手順をスクリプト化しておくと楽かもしれません。

以上、よっしー (michimani) でした。