LoginSignup
8
6

More than 1 year has passed since last update.

Step Functions から ECS Task を呼びだすときに、実行するシェルスクリプトを指定してみた

Last updated at Posted at 2022-03-19

はじめに

システムの中で、1日1回シェルスクリプトを動かしてバッチ処理を行うときがあります。その際に、実行したいシェルスクリプトを複数用意して、時間帯によって実行するシェルスクリプトを指定したいときがあります。シェルスクリプトごとにコンテナイメージを用意する方法もアリですが、1個のコンテナイメージに複数のシェルスクリプトを格納しておいた方が管理が簡単な場合もあります。

ECS Task を呼びだすときに、containerOverrides を指定することで、Dockerfile 上の CMD を上書きして実行することが出来ます。これにより、元々定義されていたコンテナイメージの CMD の指定を上書きして ECS Task を実行できます。

今回の記事では、Step Functions から ECS Task を実行するときに、CMD の上書きをしてみて、実行するシェルスクリプトを上書きする方法を確認していきます。

ECR の作成

まず、コンテナイメージを新たに自作していくために、ECR の Reposutory を作成します。

ECR のページに移動して Create repository を押します。

image-20220319025515447.png

  • Private な Repository
  • 名前を指定

image-20220319025608481.png

Create を押します

image-20220319025630242.png

ECR Repository が作成されました

image-20220319025708584.png

コンテナイメージ

ECS 上で動かすためのコンテナイメージを自作していきます。CMD で上書きするために、2 つの Bash シェルスクリプトを準備します。シェルスクリプトは、終了コードの違いで 2 種類のものを用意します。

  • 終了時のコード exit 0
  • 終了時のコード exit 1

成功するシェルスクリプト : success-shellscript

#!/bin/bash
echo "$(date) : Hello, I am success shell script!"
exit 0

失敗するシェルスクリプト : fail-shellscript.sh

#!/bin/bash
echo "$(date) : Hello, I am fail shell script!"
exit 1

上記の2個のシェルスクリプトを使うための Dockerfile を作成します

  • ベースイメージは、Amazon Linux 2
  • 実行するシェルスクリプトのファイル名を CMD で渡す。ENTRYPOINT だと ECS Task を実行するときに上書きが出来ないため、CMD で指定すること。
FROM public.ecr.aws/amazonlinux/amazonlinux:2

WORKDIR /root/workdir
ENV PATH $PATH:/root/workdir

COPY success-shellscript.sh .
COPY fail-shellscript.sh .

CMD [ "success-shellscript.sh" ]

Dockerfile を使って、コンテナイメージを Build します。

docker image build -t xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/stepfunctions-ecs:0.0.1 .

ECR に Login をしたあとに

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com

ECR に Push します

docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/stepfunctions-ecs:0.0.1

ECS Task Definition を作成

作成したコンテナイメージを動かすために、Task Definition を作成してきます。

Create new task definition

image-20220319030333691.png

  • 名前を指定
  • ECR の URI を指定
  • Port mappings では、ポートを公開しないので何も指定しない

image-20220319030530597.png

Next を押します

image-20220319030841685.png

  • Task に紐づけるリソースを指定
  • Task のロールを必要に応じて指定

image-20220319031023536.png

残りはデフォルトのまま Next を押します

image-20220319031111069.png

Create を押します

image-20220319031136643.png

Task Definition が作成されました

image-20220319031210129.png

Task Definition の ARN をメモっておきます。後の手順で使います。

image-20220319110740755.png

Step Functions から ECS Task を呼びだす部分を作成

Step Functions の State machine を作成して、ECS Task を呼びだす部分を作成していきます。

Create state machine を押します

image-20220319031317374.png

Workflow Studio でフローを作成していきます

image-20220319031408005.png

Workflow Studio が立ち上がったので、ECS の RunTask を配置します

image-20220319032354141.png

RunTask では、実行するシェルスクリプトを指定したいので、CMD を上書きしたいです。API Parameters で上書きが出来るのですが、どういった パラメータを指定できるか、Run Task に関する API のドキュメントを見ていきます。画面右側にある「API」の文字をクリックすることで、このアクションのドキュメントが直接開けます。便利に使えるので覚えておくといいでしょう。

image-20220319032613176.png

こんな感じに Request Syntax のページが開きます。この Request Syntax が、そのまま API Parameters に利用できます。

次の画像にある overrides.containerOverrides.command の部分で、Dockerfile の CMD を上書きできます。ここで、実行する シェルスクリプト名を指定していきましょう。

image-20220319110912617.png

注意点として、上の Document では小文字で書かれていますが、実際にはこのURL のようにイニシャル大文字で書かないとけないので気を付けましょう。

Document に従い、API Parameters を次のように指定します

  • Cluster : ECS Cluster の ARN を指定
  • TaskDefinition : TaskDefinition の ARN を指定
  • NetworkConfiguration : Security Group, Subnet の指定
  • Overrides.ContainerOverrides.Name : Task Definition で定義したコンテナ名を指定
  • Overrides.ContainerOverrides.Command: 実行したいシェルスクリプトの名前を指定
{
  "LaunchType": "FARGATE",
  "Cluster": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:cluster/test-cluster01",
  "TaskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/stepfunctions-ecs-taskdefiniton:1",
  "NetworkConfiguration": {
      "AwsvpcConfiguration": { 
         "AssignPublicIp": "DISABLED",
         "SecurityGroups": [ "sg-03b5c3afba3e352ee" ],
         "Subnets": [ 
             "subnet-0cf48d891b1bea31c",
             "subnet-09023225144fa1c62",
             "subnet-0c414bf2d11f17bba"
         ]
      }
  },
  "Overrides": {
      "ContainerOverrides": [
          {
              "Name": "shellscript",
              "Command": [ "fail-shellscript.sh" ]
          }
      ]
  }
}

次のように API Parameters を入力しました。

image-20220319174628356.png

Wait for task to complete にチェックを入れる

これを入れないと、ECS Task の実行結果 (ExitCode) が異常でも、Step Functions としては正常として扱うので、チェックを入れるのが良いです。

image-20220319192732441.png

右上の Next を押します

image-20220319193042348.png

このまま Next を押します

image-20220319113005572.png

State Machine の名前や IAM Role を指定します

image-20220319113253558.png

Logging を有効にしてみます

image-20220319113337426.png

Create state machine を選びます

image-20220319113410322.png

State Machine が作成されました。

image-20220319115815335.png

Step Functions の IAM Role を設定

Step Functions の State machine を作成したときに自動生成された IAM Role の権限を設定していきます。iam:PassRole の権限を付与していきます。

State machine の詳細画面にある IAM role ARN を選択します。

image-20220319120016328.png

Create inline policy を選択します

image-20220319120440640.png

以下の JSON を指定します

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                  "iam:PassRole",
                  "events:PutTargets",
                  "events:PutRule",
                  "events:DescribeRule"
            ],
            "Resource": "*"
        }
    ]
}

image-20220319192049501.png

Create Policy を選択します

image-20220319120658601.png

動作確認 : ECS のタスク実行

これで Step Functions から ECS を実行するときに、CMD を上書きする環境が出来ました。State machine を実行して動作確認をしていきます。

State machine 上で、Start execution を選択します

image-20220319122616593.png

Start Execution を押します

image-20220319122708148.png

実行が出来ました。Task の中で、exitcode 1 のものを指定しているので、Failed になっています。想定通りです。TaskSubmittedにある「ECS Task」をクリックしてみます。

image-20220319193948362.png

ECS Task のログを確認が出来て、正しく CMD で上書きした failscript が実行されていることが確認できました。

image-20220319122849321.png

わかったこと

  • Task を Run するときに、CMD をオーバーライド可能。ENTRYPOINT はオーバーライド出来ない
  • Task を Run するときに、「Wait for task to complete」を ON にしないと、ECS Task の ExitCode を拾えない。つまり、ECS Task の実行結果がどのようになっても、Step Functions 的には正常終了として扱うことになるので、「Wait for task to complete 」は ON にしておくのが良いと思う。
8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6