1
1

More than 1 year has passed since last update.

lambdaからECS:RunTaskを使用し、Taskを起動する

Posted at

業務でLambdaの実行時間に引っかかる処理を切り分けるためにLambda->ECSTask実行を行いました。
ServerlessFlameWorkを使用したNode.js/TypeScript環境でECSのTaskを実行する手順です。
Python3&boto3を使用した記事はこちらです。

環境

Node v14.7.0
"typescript": "^4.1.3"
"serverless": "^2.23.0",
"serverless-esbuild": "^1.17.1",

結論

ecsTask.ts
import { ECSClient, RunTaskCommand, RunTaskCommandInput } from '@aws-sdk/client-ecs';

const client = new ECSClient({
  region: 'ap-northeast-1',
});

const { TASK_DEFINITION, CLUSTER, SUBNETS, SECURITY_GROUP } = process.env;

const runTask = async () => {
  const input: RunTaskCommandInput = {
    cluster: CLUSTER,
    taskDefinition: TASK_DEFINITION,
    launchType: 'FARGATE',
    networkConfiguration: {
      awsvpcConfiguration: {
        subnets: SUBNETS.split(','),
        securityGroups: SECURITY_GROUP.split(','),
        assignPublicIp: 'DISABLED',
      },
    },
    overrides: {
      containerOverrides: [
        {
          name: 'app',
          command: ['npm', 'start'],
        },
      ],
    },
    count: 1,
  };
  const command = new RunTaskCommand(input);
  await client.send(command);
};

export { runTask };
serverless.yml
provider:
  iamManagedPolicies:
    - arn:aws:iam::aws:policy/AmazonECS_FullAccess

解説

ハマりポイントはIAMRoleとRunTaskCommandInputでした。

IAMRole

下記でいけるかなと思いましたが、AccessDeniedされました。

serverless.yml
provider:
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - ecs:RunTask
          Resource:
            - '*'

期待しているRoleも含まれてしまうので、FullAccess系は使用したくないのですが、一旦これで行います。
必要なActionが分かり次第、更新します。

RunTaskCommandInput

公式を見ると、TaskDefinitionだけ必須っぽいのですが、他のプロパティも必要です。
最初に記載したプロパティを指定して動きました。
ecsTask側のnetworkmodeが"aws-vpc"でなければ、networkConfigurationは必要ではないかもです。

ecsTask.ts
  const { TASK_DEFINITION, CLUSTER, SUBNETS, SECURITY_GROUP } = process.env;

  const input: RunTaskCommandInput = {
    cluster: CLUSTER,
    taskDefinition: TASK_DEFINITION,
    launchType: 'FARGATE',
    networkConfiguration: {
      awsvpcConfiguration: {
        subnets: SUBNETS.split(','),
        securityGroups: SECURITY_GROUP.split(','),
        assignPublicIp: 'DISABLED',
      },
    },
    overrides: {
      containerOverrides: [
        {
          name: 'app',
          command: ['npm', 'start'],
        },
      ],
    },
    count: 1,
  };
const input = {
  subnets: SUBNETS.split(','),
  securityGroups: SECURITY_GROUP.split(','),
}

上記は環境変数(string)を配列に変更しています。
自分はServerlessFlameWorkでの環境変数の設定にこちらのclassmethodさんの記事を参考にしています。

あとはoverrides.containerOverridesnameは必須です。

あとがき

ここまで読んでいただきありがとうございます。
疑問点等あれば、質問していただければ答えます!

最近見た映画の主題歌がマカロニえんぴつだったからか、またハマり出しました。
好きな音楽を聞きながらコードを書くのが好きな今日この頃です。
ノリノリでコード書いているので周りはちょっと引いているみたいですが。。笑

1
1
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
1
1