AWS Batchの概念を理解する

AWS Batchを触ってみたメモです。今回の内容はAWS Batchの概念を理解するため、単純に1つのジョブを実行してみた内容となっています。

AWS Batchとは

AWS Batchについてざっくりと説明すると、作成したコンテナイメージを、AWS側にて管理されたECS Contaner Instace上で実行してくれる機能となっています。

以下より、実際にAWS Batchを実行するために必要な作業を記載していきます。

コンテナタスク用IAM Roleの作成

ECS Container Instance上でdocker runされたコンテナで利用するIAM Roleを作成する処理です。考え方は、ECSやFargateと同じですね。

必要なIAM Roleは、以下にて記載されているので、その内容に沿って作成。 AmazonECSTaskExecutionRolePolicy というポリシーがあるので、最低限、このポリシーをアタッチしておく必要があります。

Amazon ECS タスク実行 IAM ロール

AWS Batch用IAM Roleの作成

続いて、AWS Batchで利用されるIAM Roleを作成しておきます。AWS Batch処理内にてAWS APIを呼び出す処理をしてくれています。公式のドキュメントを参考に、 AWSBatchServiceRole を作成しておきます。

AWSBatchServiceRole IAM ロールを作成するには

ほとんどの場合、AWS Batch サービスロールは、コンソールの最初の実行時に自動的に作成されます。

マニュアルに上記記載がある通り、既にコンソール上でAWS Batchに触っている場合、 arn:aws:iam::XXXXXXXXXXX:role/service-role/AWSBatchServiceRole というIAM Roleが作成されているはずです。

実行用コンテナの作成

AWS Batchにて実行するためのコンテナイメージを作成します。今回はサンプルなので、 hostname コマンドを実行するだけのコンテナイメージを作成します。

Dockerfile

FROM centos:latest
CMD ["hostname"]

ビルドします。

$ docker build -t XXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/job:latest .

試しにローカルでdocker runしてみます。

$ docker run --rm XXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/job:latest
bb79ee5198f7

作成できたコンテナイメージを、ECRにpushしておきます。

ジョブ定義テンプレートの作成

ジョブ定義テンプレートとは、ECSやFargateでいう所のタスク定義にあたるようなものとなります。コンテナの基本情報やdocker run実行時の付与パラメータ等を定義してあげます。

今回作成したサンプルとなるジョブ定義のCloudFormationはこちら。作成したジョブ定義名は sample-job-definition となります。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  JobDefinition:
    Type: "AWS::Batch::JobDefinition"
    Properties:
      Type: "container"
      # Parameters: Json
      # NodeProperties:
      #   MainNode: Integer
      #   NodeRangeProperties:
      #     - NodeRangeProperty
      #   NumNodes: Integer
      Timeout:
        AttemptDurationSeconds: 300
      ContainerProperties:
        # MountPoints:
        #   - ReadOnly: Boolean
        #     SourceVolume: String
        #     ContainerPath: String
        # User: String
        # Volumes:
        #   - Host:
        #       SourcePath: String
        #     Name: String
        # Command:
        #   - String
        Memory: 1024
        Privileged: false
        JobRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole"
        # Environment:
        #   - Value: String
        #     Name: String
        ReadonlyRootFilesystem: true
        # Ulimits:
        #   - SoftLimit: Integer
        #     HardLimit: Integer
        #     Name: String
        Vcpus: 1
        Image: !Sub "${AWS::AccountId}.dkr.ecr.ap-northeast-1.amazonaws.com/job:latest"
      JobDefinitionName: "sample-job-definition"
      RetryStrategy:
        Attempts: 1

公式の各種説明資料はこちら。

CloudFormation - AWS::Batch::JobDefinition

ジョブ定義のパラメータ

AWSのDocker系サービスを触ったことある人であれば、困ることなく作成できると思います。

コンピューティング環境の作成

コンピューティング環境とは、ECS Container Instanceのことです。AWS Batchでは、実行されるコンテナで必要とされるvCPU数に合わせて、必要となるECS Container Instance数をいい感じに管理してくれます。なので、コンピューティング環境で定義する内容は、以下のようなものになります。

  • 基本的なECS Container Instanceの設定
  • 利用するEC2 Instance Type
  • Instance最大/最小起動台数

今回作成したサンプルとなるコンピューティング環境のCloudFormationはこちら。作成したコンピューティング環境の名前は compute-sample となります。

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  VpcId:
    Type: "AWS::EC2::VPC::Id"
  Subnets:
    Type: "List<AWS::EC2::Subnet::Id>"
  KeyPair:
    Type: "AWS::EC2::KeyPair::KeyName"

Resources:
  IAMRole:
  # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
    Type: "AWS::IAM::Role"
    DeletionPolicy: "Delete"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "ec2.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
      # Policies:
      #   - PolicyName: String
      #     PolicyDocument:
      #       Version: "2012-10-17"
      #       Statement:
      #         - Effect: String
      #           Action: String
      #           Resource: String
      RoleName: EC2InstanceRoleAWSBatch
  InstanceProfile:
  # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html
    Type: "AWS::IAM::InstanceProfile"
    DeletionPolicy: "Delete"
    DependsOn: "IAMRole"
    Properties:
      Roles:
        - !Ref IAMRole
  SecurityGroup:
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html
    Type: "AWS::EC2::SecurityGroup"
    DeletionPolicy: "Delete"
    DependsOn: "InstanceProfile"
    Properties:
      GroupName: "for-awsbatch"
      GroupDescription: "for-awsbatch"
      # SecurityGroupEgress:
      #   - Security Group Rule
      SecurityGroupIngress:
        -
          CidrIp: "0.0.0.0/0"
          # CidrIpv6: String
          # Description: String
          IpProtocol: "tcp"
          FromPort: "22"
          ToPort: "22"
          # SourceSecurityGroupId: String
          # SourceSecurityGroupName: String
          # SourceSecurityGroupOwnerId: String
      Tags:
        - Key: "Name"
          Value: "for-awsbatch"
      VpcId: !Ref "VpcId"
  ComputeEnv:
  # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-batch-computeenvironment-computeresources.html
    Type: "AWS::Batch::ComputeEnvironment"
    DependsOn: "SecurityGroup"
    DeletionPolicy: "Delete"
    Properties:
      ComputeEnvironmentName: "compute-sample"
      ComputeResources:
        # BidPercentage: Integer
        DesiredvCpus: 1
        Ec2KeyPair: !Ref KeyPair
        # ImageId: String
        InstanceRole: !GetAtt InstanceProfile.Arn
        InstanceTypes:
          - "c5"
        # LaunchTemplate:
        #   LaunchTemplateId: String
        #   LaunchTemplateName: String
        #   Version: String
        MaxvCpus: 8
        MinvCpus: 1
        # PlacementGroup: String
        SecurityGroupIds:
          - !Ref SecurityGroup
        # SpotIamFleetRole: String
        Subnets: !Ref Subnets
        Tags:
          Name: sample-compute-env
        Type: "EC2"
      ServiceRole: !Sub "arn:aws:iam::${AWS::AccountId}:role/service-role/AWSBatchServiceRole"
      State: "ENABLED"
      Type: "MANAGED"

公式の各種説明資料はこちら。

CloudFormation - AWS::Batch::ComputeEnvironment

コンピューティング環境のパラメータ

こちらも、ECS Container Instacneを作成したことがあるなら、作成することに困ることはないと思います。

ジョブキューの作成

実行されるジョブ(コンテナ)をキューイングしてくる機能となります。SQSを作成するのかな、と思いましたが、AWS Batch用にキューを設定することになります。(ジョブキューを作成しても、SQSにはキューが作成されていなかったので)

今回作成したサンプルとなるジョブキューのCloudFormationはこちら。作成したジョブキューの名前は sample-queue となります。定義内で、上で作成したコンピューティング環境と紐付けしていることが分かると思います。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  jobqueue:
    Type: "AWS::Batch::JobQueue"
    Properties:
      ComputeEnvironmentOrder:
        - ComputeEnvironment: !Sub "arn:aws:batch:ap-northeast-1:${AWS::AccountId}:compute-environment/compute-sample"
          Order: 1
      Priority: 10
      State: "ENABLED"
      JobQueueName: "sample-queue"

公式の各種説明資料です。

CloudFormation - AWS::Batch::JobQueue

ジョブキューのパラメータ

ジョブのsubmit

以上にて、必要となる事前の準備は完了ですので、ジョブを投入してみます。実際の利用時には、Cloudwatch Eventを利用したスケジューリングしたりする事になるでしょうが、今回は単純にAWS CLIよりジョブ投入コマンドを実行しています。

aws batch submit-job ^
--job-name sample ^
--job-queue sample-queue ^
--job-definition sample-job-definition:1

AWS CLI - submit-job

AWS Batchコンソール上のDashboard画面にジョブの実行ステータスが表示されます。コンテナ上で出力されたログは、CloudwatchLogsに連携されています。

f:id:goodbyegangster:20190822014831p:plain