Posted at

AWS lambdaを使ってBatchにjobを投げる


本記事でやること


  • Pythonで書いたlambda functionでAWS Batchにジョブを投げる。

本記事でやらないことは以下の通りなので、他の記事を参照してください。


  • lambdaやBatchにアクセスするためのIAMロールの作成

  • lambda functionの作成の仕方

  • AWS Batchのコンピューティング環境やジョブ定義などの環境構築(過去の記事で紹介しているのでこちらを参照してください)


対象読者


  • AWSの各サービスの役割を一通り知っている方

  • AWS lambdaとAWS Bathをいじって何か動くものを作ってみたい方

  • Python入門者


使用言語

Python 3.6.3


AWS Batchにジョブを送るlambdaスクリプト

以下が、AWS Batchにジョブを送るlambdaのスクリプトになっています。

get_revisionメソッドは、ジョブ定義の最新のrevisionを取得する役割のメソッドになっています。

get_job_paramsメソッドでは、lambda_handlerメソッドでジョブを送る際のジョブ名やジョブキュー、ジョブ定義のパラメータを作成するメソッドになっています。

また、関数外で定義しているARNには、AWS Batch / lambda / CloudWatchへのFullAccess権限が付与されています。


lambda_function

import logging

import boto3

LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)

ARN = "arn:aws:batch:ap-northeast-1:hogehoge"

def lambda_handler(event, _context):
LOGGER.info(event)

client = boto3.client("batch")

params = get_job_params(event, client)

client.submit_job(
jobName=params["JOB_NAME"],
jobQueue=params["JOB_QUEUE"],
jobDefinition=params["JOB_DEFINITION"]
)

def get_revision(client, job_definition_name):
job_definitions = \
client.describe_job_definitions()['jobDefinitions']

revision_num = 1

for job in job_definitions:
if job["jobDefinitionName"] == job_definition_name:
if job["revision"] > revision_num:
revision_num = job["revision"]

return revision_num

def get_job_params(event, client):
params = {}
job_definition_name = "test-batch-job"
revision_num = get_revision(client, job_definition_name)

params["JOB_NAME"] = "test-job"
params["JOB_QUEUE"] = ARN + ":" + "job-queue/s3_get_bucket_list"
params["JOB_DEFINITION"] = "test-batch-job" + ":" + str(revision_num)

return params



実行及び確認

今回は定期的にBatchを動かすことを想定しているので、CloudWatch eventsを使って定期的にlambdaを起動しジョブを送ります。(エラーが発生し実行されない場合はCloudWatch logsを使ってエラー内容を確認しながら修正をしていきました。)

以下、AWSコンソールでCloudWatch eventsのルール(いつlambdaを起動するのか)を定めます。ルールが作成されたらlambdaが起動しますのでAWS Batchのコンソール画面で正常にジョブが送信されたことを確認します。

スクリーンショット 2019-01-06 21.03.19.png

以下、該当のジョブキューでのジョブのステータスがSUCCEEDEDになっていることが確認できれば無事完了です。

スクリーンショット 2019-01-06 21.08.58.png


なぜlambdaを使ってAWS Batchにジョブを送るのか

AWS Batchを定期的に動かしたいだけであれば、lambdaからではなくCloudWatch eventsにBatchを登録すれば達成できます。

しかし、「S3の該当バケットにファイルがPUTされたことを確認しBatchを動かしたい」などBatchを動かしたいある一定の条件がある場合にlambdaが非常に役立ちます。

S3のバケット及びファイルを確認するlambdaスクリプト、Batchにジョブを送るlambdaスクリプトと役割を分けたlambdaを用意し、「S3の該当バケットにファイルがPUTされたことを確認したらBatchにジョブを送るlambdaを起動する」といった具合にlambda同士を連携させることができれば上記を達成することができます。

つまり、lambdaを使えば、諸AWSサービスの状態を確認しBatchにジョブを送ることが可能になります。


終わりに

今回はただlambdaを使ってBatchにジョブを送るスクリプトを作成しましたが、S3の状態を監視しある一定の条件を満たした場合にジョブを送る様なlambdaスクリプトを時間がある時に作成したいと思います。