こんにちは、エンジニアの田代です。
バッチ処理等において、ECSサービスのタスク数を調整したいケースがあるのではないでしょうか。
Step Functionsを利用する等複数の方法が考えられますが、今回はAWS外のジョブ管理システムから操作することを想定して、
API Gateway + Lambdaで実装したのでサンプルを共有したいと思います。
ECSサービスのタスク起動数を更新するLambda
Lambdaコード
import boto3 ecs = boto3.client('ecs') def lambda_handler(event, context): params = event['queryStringParameters'] # クエリパラメータから対象のECSクラスターを取得 cluster = params['cluster'] # クエリパラメータから対象のECSサービスを取得 service = params['service'] # クエリパラメータから設定する起動数を取得 desired_count = int(params['desiredCount']) response = ecs.update_service( cluster=cluster, service=service, desiredCount=desired_count ) print(response) return { 'statusCode': 200 }
実行ロール用のIAMポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "allow-update-service", "Effect": "Allow", "Action": "ecs:UpdateService", "Resource": "*" } ] }
ECSサービスのタスク起動数を取得するLambda
Lambdaコード
import boto3 import json ecs = boto3.client('ecs') def get_healthy_task_count(cluster: str, tasks_list: list) -> int: # 各タスク内の全てのコンテナのヘルスチェックステータスがHEALTHYの場合, 起動タスク数を1加算する healthy_task_count = 0 if len(tasks_list) == 0: return healthy_task_count describe_tasks_response = ecs.describe_tasks( cluster=cluster, tasks=tasks_list ) for task in describe_tasks_response['tasks']: if all(i['healthStatus'] == 'HEALTHY' for i in task['containers']): healthy_task_count += 1 return healthy_task_count def lambda_handler(event, context): params = event['queryStringParameters'] # クエリパラメータから対象のECSクラスターを取得 cluster = params['cluster'] # クエリパラメータから対象のECSサービスを取得 service = params['service'] # RUNNINGステータスのタスクを取得 list_tasks_response = ecs.list_tasks( cluster=cluster, serviceName=service, desiredStatus='RUNNING' ) running_tasks = list_tasks_response['taskArns'] healthy_task_count = get_healthy_task_count(cluster, running_tasks) body = {'taskCount': healthy_task_count} return { 'statusCode': 200, 'body': json.dumps(body), 'headers': { 'Content-Type': 'application/json' } }
実行ロール用のIAMポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "allow-list-tasks", "Effect": "Allow", "Action": [ "ecs:ListTasks", "ecs:describeTasks" ], "Resource": "*" } ] }
実行結果
各LambdaのトリガーとしてAPI Gatewayを設定して、それぞれ実行してみます。
$ curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/xxx/update-desired-count?cluster=EcsClusterName&service=EcsServiceName&desiredCount=2
指定した数のタスクが起動しました。
この状態でタスク起動数取得Lambdaを実行します。
$ curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/xxx/get-task-count?cluster=EcsClusterName&service=EcsServiceName
{"taskCount": 2}
期待通りの結果が返りました。
今回の記事が皆様の参考になれば幸いです。
田代 侑大システム開発部 マネックス・ラボ