Edited at
iRidgeDay 11

AWS BatchでPythonスクリプトを定期的に実行する

More than 1 year has passed since last update.


はじめに

「DBデータをCSVにしてS3に置いてほしい。毎日ね。」と言われ「今時、EC2でやるのはちょっと。」と思いAWS Batchでやってみたので書きます。


前提条件

今回は空のCSVファイルをS3バケットに置くだけの簡単なお仕事を行なうPythonスクリプトを例に実施します。


AWS Batchとは

バッチコンピューティングジョブを実行するためのマネージドサービスです。

料金はEC2・AWS Lambda等の使った分だけ!


こんな時に向いてる


  • 定期的に実行したい


  • AWS Lambdaだとに心細い(参考)

  • サーバの面倒を見たくない

  • 安くいきたい(使った分だけ課金)


用語説明


  • ジョブ定義


    • どのイメージを使用するか、CPU・メモリはどれくらい使用するか、環境変数などを定義する。



  • コンピューティング環境


    • ジョブを実行するための環境。特定のインスタンスタイプや特定のモデル (c4.2xlarge や m4.10xlarge など) を使うように設定できたりする。



  • ジョブキュー


    • ジョブがコンピューティング環境にスケジュールされるまでの待ち行列を保持するもの。



  • ジョブ


    • ジョブ定義で指定したパラメーターを使用して、コンピューティング環境でコンテナ化されたアプリケーションとして Amazon EC2 インスタンスで実行されるもの。




ソースコード書く

書いた。今回使用するものはこちら


ECR(EC2 Container Registory)にイメージをプッシュ

今回はECRを使ってみる。


  • マネジメントコンソールでECSを開く

  • リポジトリ名決める

スクリーンショット 2017-12-10 22.53.11_censored.jpg


  • リポジトリにイメージをPushする

スクリーンショット 2017-12-10 22.56.19_censored.jpg


Job Definitionの作成



  • Job definition nameは任意の名前を入れます。


  • Job Roleaws_batch_roleを選択します。


    • aws_batch_roleは下記ポリシーを保持


      • AmazonEC2ContainerRegistryFullAccess

      • AmazonEC2ContainerServiceFullAccess






  • Container Imageは先程作成したリポジトリのURIを指定します。

スクリーンショット 2017-12-10 22.59.21_censored.jpg


  • Environment



    • CommandはDockerfileでCMDを指定しているので入力しません。


    • vCPUsm3.mediumなので1を指定します。


    • Memory(MiB)m3.mediumなので3072を指定します。(m3.mediumが3.75GBなので超えないように指定しています。)


    • Job Attemptsは1度だけRunnableに移行すれば良いので1を指定します。


    • uLimitsは特に指定しません。


    • Parameterは特に指定しません。



スクリーンショット 2017-12-10 19.08.13.png



  • Environment variables


    • 下記を設定する。


      • AWS_ACCESS_KEY_ID

      • AWS_SECRET_ACCESS_KEY

      • AWS_S3_BUCKET_NAME






  • Security


    • 今回は特に指定しません。




  • Volumes


    • 今回は特に指定しません。




  • Mount points


    • 今回は特に指定しません。




Compute Environmentの作成


  • マネジメントコンソールでAWS Batchを開きます。

  • Create a compute environment



    • Compute environment typeManagedを選択します。


    • Compute environment nameで今回はexecute_python_script_envを入力します。


    • Service RoleAWSBatchServiceRoleを選択します。


    • Instance RoleecsInstanceRoleを選択します。


    • EC2 Key Pairで任意のKeyを選択します。



スクリーンショット 2017-12-10 17.10.49_censored.jpg


  • Configure your compute resources



    • Provisioning Modelで今回はOn demandを選択します。


    • Allow instance typesで今回は大した処理を行わないかつ安くいきたいのでm3.mediumを選択します。(optimalがデフォルトで選択されていますがc4.largeといったインスタンスが選択されるので状況に応じての選択が重要となります。)


    • Minimum vCPUs(環境で維持する必要がある EC2 vCPU の最小数。)1を選択します。


    • Desired vCPUs(コンピューティング環境で必要なEC2 vCPUSの数)1を選択します。


    • Maximum vCPUs(環境で到達できる EC2 vCPU の最大数)1とします。


    • Enable user-specified AMI IDにチェックは入れません。



スクリーンショット 2017-12-10 17.10.59.png



  • Networking



    • VCP IDでは使用するものを選択します。


    • Subnetsでは使用するものにチェックをつけます。


    • Security groupsは任意のものを選択します。



スクリーンショット 2017-12-10 17.11.11_censored.jpg



  • EC2 Tags



    • EC2 Tagはお好みで。




Job Queue作成



  • Queue nameは今回put-csv-to-s3を入力する。


  • Priority1を入力する。


  • Enable Job queueはチェックを入れる。


  • Select a compute environmentは先程作成したexecute_python_script_envを選択します。

スクリーンショット 2017-12-10 22.59.21_censored.jpg


Jobの実行

ここまで来たらジョブを実行していきます。まず、Jobsでsubmit jobを選択します。


  • Job run-time



    • job nametest-put-csv-to-s3を入力します。


    • Job definitionは先程作成したput-csv-to-s3:1を選択します。


    • Job queueは先程作成したput-csv-to-s3を選択します。


    • Job typesingleを選択します。


    • Job depends onは特に入力しません。



スクリーンショット 2017-12-10 23.08.43.png



  • EnvironmentEnvironment variablesJob Denitionsで定義したものがセットされているのでそのまま利用します。

submitすると様々な状態にがありますが、詳細はこちらを御覧ください。

よっしゃ、成功した。

スクリーンショット 2017-12-10 21.42.01.png

S3バケット内にnull.csvがありました。よさそうです。

スクリーンショット 2017-12-10 21.41.55_censored.jpg


lambdaでJobを叩くスクリプト作成

下記の関数を作成する。


lambda_function.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys
import boto3

batch = boto3.client('batch')

def submit_job(event):
result = batch.submit_job(
jobName=event['JobName'],
jobQueue=event['JobQueue'],
jobDefinition=event['JobDefinition']
)
return result

def lambda_handler(event, context):
result = submit_job(event)
print(result)
return None


環境変数は下記を指定。


  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY


  • AWS_DEFAULT_REGION(ap-northeast-1を指定)


CloudWatch Eventsで実行する時間を指定

CloudWatch Eventsのルールより設定を行なう。


  • イベントソース


    • スケジュール


      • Cron式



        • 0 16 * * ? * (UTCなので日本時間の毎日1時に起動します。)







  • ターゲット



    • Lambda関数を指定します。


    • 機能は先程作成したsubmit-jobを選択します。


    • 入力の設定は下記を入力します。(xxxxxxxxxxxxxはアカウントID)


      • { "JobName": "put-csv-to-s3", "JobQueue": "put-csv-to-s3", "JobDefinition": "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxxx:job-definition/put-csv-to-s3:1" }





これで定期的に実行が可能となります。


まとめ

AWS BatchでPythonスクリプトを定期的に実行することができました。

今後は、CI/CDの部分(イメージ作成・Job Definitionの更新等)で改善できる余地があるので対応していきたいと思います。


参考文献