この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、菊池です。
API GatewayとLambdaで構成するAPIから、AWS Batchのジョブを実行する環境を作成してみました。Lambdaには向いていない長時間の処理などを、非同期にBatchで実行することで、スケーラブルなジョブ実行環境にできないかと思いました。
API Gateway + LambdaからBatch Jobを実行する
構成イメージは以下のようになります。
APIに対しリクエストを行うと、Lambda関数はBatchに対しジョブの実行を要求し、すぐにレスポンスを返します。Batchはその後、APIのリクエストとは非同期でジョブを実行します。
ElasticBeanstalkのworker環境や、StepFunctionsに実装したActivity State Machineの呼び出しでも、非同期にEC2上のアプリケーションを実行することは可能です。しかし、Batchを使うことで、ジョブの要求数に応じて環境をスケールさせて実行することができます。
構築
以下の順で構築していきます。
- Batch環境の作成
- Lambda関数の作成
- API Gatewaの作成
AWS Batchの準備
今回は特に処理内容はなんでもよかったので、以下の記事の手順でBatchのジョブキュー/ジョブ定義を作成しました。
次のLambda関数の作成で、ジョブキューのARNを指定する必要がありますが、マネジメントコンソールからは確認できませんでした。AWS CLIのdescribe-job-queues
で取得することができます。
$ aws batch describe-job-queues
{
"jobQueues": [
{
"status": "VALID",
"jobQueueArn": "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxx:job-queue/first-run-job-queue",
"computeEnvironmentOrder": [
{
"computeEnvironment": "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxx:compute-environment/first-run-compute-environment",
"order": 1
}
],
"statusReason": "JobQueue Healthy",
"priority": 1,
"state": "ENABLED",
"jobQueueName": "first-run-job-queue"
}
]
}
Lambda関数の作成
Batchに対してJobをサブミットするLambda関数を用意します。Python 3.6のランタイムで以下のような関数を作成しました。
import boto3
def lambda_handler(event, context):
client = boto3.client('batch')
JOB_NAME = event['JobNeme']
JOB_QUEUE = "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxx:job-queue/first-run-job-queue"
JOB_DEFINITION = "first-run-job-definition:1"
response = client.submit_job(
jobName = JOB_NAME,
jobQueue = JOB_QUEUE,
jobDefinition = JOB_DEFINITION
)
print(response)
return 0
Jobを実行するだけの関数です。JobName
のみリクエストから受け取るようにしています。
関数のロールには、AWS BatchのSubmitJob
の実行権限を持つIAMポリシーをアタッチします。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"batch:SubmitJob"
],
"Resource": [
"*"
]
}
]
}
API Gatewayの作成
続いて、API Gatewayの作成です。
API Gatewayのマネジメントコンソールで、[新しいAPIの作成]からAPIとリソースを作成します。以下の記事を合わせて参照ください。
作成したリソースに、[メソッドの作成]からPOSTメソッドを作成し、セットアップします。[統合タイプ]にLambda関数を選択し、先ほど作成した関数を指定します。
メソッドが作成されました。次に、[アクション]から[APIのデプロイ]を選びます。ステージを選択すれば完了です。
APIが呼び出し可能になりました。APIのURLが確認できます。
実行してみる
それでは実行してみます。curlコマンドで作成したURLにPOSTします。
$ curl -X POST -d '{ "JobNeme" : "test" }' https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/testbatch
実行されたJobはAWS Batchのコンソールから確認できます。APIからの呼び出し直後は、RUNABLEのステータスです。
環境で定義したEC2の起動されると、ジョブが実行されます。しばらくすると、ステータスがSUCCEEDEDになりました。ジョブが完了したようです。
これで、APIから呼び出し可能な、スケーラブルなジョブ環境が構築できました。
まとめ
以上です。あとは、Batchジョブにアプリケーションを乗せることで、処理の実行が可能です。処理が非同期化されますので、完了時にSNSのプッシュなどを組み合わせると良いでしょう。