AWS Batchでハマったポイントまとめ
Lambdaの処理時間5分の制約やデバッグの難しさは避けたいけれど、EC2を立ち上げ続けるほどの頻度では発生しないタスクを処理するのにAWS Batchが適任だったので導入してみました。
使い勝手は良かったのですが、上手く動くまでに間違いやすい箇所が多く、失敗すると原因が分かりにくいためチェックすべき箇所をまとめておきます。
VPC関連
デフォルトVPCを利用する場合はあまり問題になりませんが、自作のVPC上でECSクラスタを動かす場合は注意が必要です。
サブネットからインターネットにアクセスできない
サブネットからインターネットアクセスができないとECS用のインスタンスが立ち上がってもECSクラスタに登録されない(要検証)ようでEC2インスタンスは立ち上がったままジョブがRunnableの状態で停止します。放置しておくとEC2が立ち上がっている分課金され続けます。
原因としては次のような事があります。
- VPCにゲートウェイが設定されていない
- VPC内のルーティングが設定されていない
- サブネットのパブリックIPv4自動割当が無効になっている
- セキュリティグループのアウトバウンドが阻害されている
パブリックIPの問題はこちらの記事でも取り上げられていました。
AWS BatchのジョブがRUNNABLEのまま進まない
セキュリティグループがVPCに紐付いていない
こちらはTerraformでセキュリティグループを作成したときにハマりましたが、セキュリティグループをVPCに紐付け忘れるとECS用のインスタンスが立ち上がらなくなります。
この場合コンピューティング環境の状態がINVALIDとなり次のようなエラーが表示されます。
CLIENT_ERROR - One or more security groups configured in the launch configuration are not linked to the VPCs configured in the Auto Scaling group
こちらのブログでも同じ現象が報告されてました。
【未完】Developers.ioの記事を読んでやってみる「API Gateway + LambdaでAWS BatchのJobを実行する」(2018/03/22)
IAM Role関連
AWS Batchには3種類のIAM Roleが出てきますが、それぞれ適切に設定しないとジョブが正常に処理されません。
AWS Batchに付与するロール
AWS BatchがECSやEC2などのリソースを操作するためのロールでAWS Batch自体に付与します。
マネジメントコンソールで「IAM」 -> 「IAM Role」 -> 「ロールの作成」 -> 「Batch」を選択すると予め用意されている「AWSBatchServiceRole 」が表示されるのでそのまま作成すれば大丈夫です。
ECS用のEC2インスタンスに付与するロール
AWS Batchが裏で作成するEC2インスタンスに対して付与するロールです。
マネジメントコンソールで「IAM」 -> 「IAM Role」 -> 「ロールの作成」 -> 「Elastic Container Service」 -> 「EC2 Role for Elastic Container Service」を選択すると予め用意されている「AmazonEC2ContainerServiceforEC2Role」が表示されるのでそのまま作成すれば大丈夫です。
ECSのタスクに付与するロール(ジョブロール)
ECSのタスクに対して付与するロールで、ポリシーの内容はジョブを実行する上で連携するサービスによって変わります。AWSによって用意されているポリシーでは不十分な場合は予めポリシーを作成しておきます。自分の場合は入出力目的のS3バケットへのアクセス用のポリシーを作成しました。
マネジメントコンソールで「IAM」 -> 「IAM Role」 -> 「ロールの作成」 -> 「Elastic Container Service」 -> 「Elastic Container Service Task」を選択し必要なポリシーを付与します。
ECSクラスタ関連
コンピューティング環境のリソースとジョブのリソース
コンピューティング環境の設定で利用できるインスタンスタイプが指定できますが、ジョブに指定したvCPUとメモリが利用できるインスタンスのvCPUとメモリを越えていると適合するインスタンスが作られずジョブが停止するようです。
AWS Batch設定のテンプレート
次回以降の導入を簡単にするために、TerraformでAWS Batchの設定をテンプレート化しておきました。
AWS BatchのチュートリアルにあるHello Worldのジョブ定義まで作られるので、あとはマネジメントコンソールからジョブを動かすことができます。
https://github.com/yukihira1992/aws-batch-template
ジョブを登録後は、ECSクラスタが準備できるまでRunnableで止まり、その後ジョブが完了してSucceededに移動します。