Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

AWS Batchの環境をCloudFormationを使って自動構築し簡単なアプリケーションを実行するまで

More than 1 year has passed since last update.

本記事でやること

  • AWS Batchのコンピューティング環境やジョブ定義などをCloudFormationを使って構築する
  • AWS Batchにジョブを送り、S3のバケット名を取得するアプリケーションを実行する

上記を達成するために予め行うこと

  • AWS ECRを使ってアプリケーションのDocker imageをpushする

以下に関しては、記載しないので他の記事を参照してください。

  • AWS ECSを使用するにあたって必要なVPCやSubnet、セキュリティーグループの作成
  • AWS BatchやECSにアクセスするためのIAMロールの作成

対象読者

  • Dockerについて一通り基礎的な書籍を読んで、何か動くものを作りたい方
  • AWS BatchやCloudFormationを使って何かしたい方

使用言語

python 3.6.3

AWS ECRを使ってアプリケーションのDocker imageをpushする

AWS ECSがコンテナを作成する際にpullするDocker imageを予めAWS ECRにpushする。
また、アプリケーションのファイルやディレクトリ構成は以下の通り。

ディレクトリ構成
.
├── infra
│   ├── Dockerfile
│   ├── .vault_password
│   ├── .aws
│   │    └── config
│   │    └── credentials
│   └── batch_config
│       └── cloudformation.yml
└── run.py
Dockerfile
FROM hogehoge.ecr.ap-northeast-1.amazonaws.com/python:latest

# userの作成
RUN groupadd -g 10000 test && \
    useradd  -u 10000 -g test -s /bin/bash test && \
    echo 'test:test' | chpasswd

ENV HOME /home/test
WORKDIR $HOME
RUN chown test:test -hR ./

USER test

ADD --chown=test:test infra/ $HOME

# 暗号化されているaws認証情報を復元する
RUN ansible-vault decrypt .aws/credentials --vault-password-file .vault_password

ADD --chown=test:test . test
USER root
WORKDIR /home/test/test

CMD ["python", "run.py"]

上記、Dockerfileのベースとなっているimageに関しては、こちらの記事で紹介しているので適宜参照してください。(ベースとなっているimageは、pythonイメージにansibleをインストールしたimageです)

Dockerfile内のCMD箇所で実行しているアプリケーションのファイルの中身は以下のようになっています。(S3のバケット名を取得するスクリプトになっています)

run.py
from boto3.session import Session

def get_bucket_list():
    resource = Session(profile_name="local").resource("s3")

    for bucket in resource.buckets.all():
        print(bucket.name)

if __name__ == '__main__':
    get_bucket_list()

上記Dockerfileをinfra/以下に置き、下記のコマンドでAWS ECRにプッシュする。

bash
# ECRにログインする
$(aws ecr get-login --no-include-email --region ap-northeast-1 --profile hoge)

# イメージのビルド(イメージの名前は適当に"python"とする)
docker build -t test-app .

# 上でビルドしたイメージにタグをつける(hogehogeの部分には)
docker tag test-app:latest hogehoge.dkr.ecr.ap-northeast-1.amazonaws.com/test-app:latest

# イメージをAWS ECRにプッシュする
docker push hogehoge.dkr.ecr.ap-northeast-1.amazonaws.com/test-app:latest

AWS Batchの環境をAWS CloudFormationを使って構築する

以下のcloudformation.ymlファイルを使ってAWS Batchの環境を構築する。set parametersの箇所でのsubnet-idやEC2インスタンスのkeyペア、ECS / BatchのIAMロールのARNは各自用意をしコピペする。

cloudformation.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Build AWS Batch environment

# =======set parameters======== #
Parameters:
  SubnetIds:
    Description: Subnets For ComputeEnvironment
    Type: List<AWS::EC2::Subnet::Id>
    Default: subnet-id
  SecurityGroupIds:
    Description: SecurityGroups For ComputeEnvironment
    Type: List<AWS::EC2::SecurityGroup::Id>
    Default: sg-id
  KeyPair:
    Description: key pair
    Type: String
    Default: key
  image:
    Type: String
    Description: image in container registory
    Default: hogehoge.ecr.ap-northeast-1.amazonaws.com/awsbatch/test-app:latest
  ecsInstanceRole:
    Type: String
    Description: Role For AWS EcsInstanceRole
    Default: arn:aws:iam::hogehoge:instance-profile/ecsInstanceRole
  AWSBatchServiceRole:
    Type: String
    Description: Role For AWS BatchRole
    Default: arn:aws:iam::hogehoge:role/service-role/AWSBatchServiceRole

# =======Batch======== #
# create ComputeEnvironment
Resources:
  MyComputeEnv:
    Type: "AWS::Batch::ComputeEnvironment"
    Properties:
      Type: MANAGED
      ServiceRole: !Ref AWSBatchServiceRole
      ComputeEnvironmentName: "test-batch-compute-environment"
      ComputeResources:
        MaxvCpus: 256
        MinvCpus: 0
        DesiredvCpus: 0
        SecurityGroupIds: !Ref SecurityGroupIds
        Type: EC2
        Subnets: !Ref SubnetIds
        Ec2KeyPair: !Ref KeyPair
        InstanceRole: !Ref ecsInstanceRole
        InstanceTypes:
          - optimal
        Tags:
          Name: "test-batch-computer"
      State: ENABLED

  # Create JobQueue
  MyJobQueue:
    Type: AWS::Batch::JobQueue
    Properties:
      ComputeEnvironmentOrder:
        - Order: 1
          ComputeEnvironment: !Ref MyComputeEnv
      State: ENABLED
      Priority: 1
      JobQueueName: "s3_get_bucket_list"

  # Create JobDefinition
  MyJobDefinition:
    Type: AWS::Batch::JobDefinition
    Properties:
      Type: container
      JobDefinitionName: "test-batch-job"
      ContainerProperties:
        Memory: 16000
        Vcpus: 1
        Image: !Ref image
      RetryStrategy:
        Attempts: 1

aws cliを使って以下のコマンドでAWS Batchの環境を自動構築する。

bash
aws cloudformation create-stack \
--stack-name aws-batch \
--template-body file://$PWD/infra/batch_config/cloudformation.yml \
--profile hoge

AWS Batchにジョブを送り、S3のバケット名を取得するアプリケーションを実行する

上記のコマンドでAWS Batchの環境が構築されたことを確認できたら、以下のコマンドでジョブを送信する。

bash
JOB_DEFINITION_ARN=$( aws batch describe-job-definitions \
  --job-definition-name "s3_get_bucket_list" \
  --status ACTIVE \
  --profile hoge \
  | jq -r '.jobDefinitions | max_by(.revision).jobDefinitionArn' \
) && echo ${JOB_DEFINITION_ARN} 

aws batch submit-job \
--job-name "test-job" \
--job-queue "s3_get_bucket_list" \
--job-definition ${JOB_DEFINITION_ARN}  \
--profile hoge

ジョブのキューがSUCCEEDEDになったら、AWS CloudWatch LogsにS3のバケット名が出力されていることが確認できたら無事完了です。

また、無事完了できたら今回CloudFormationで作成した諸々の環境は、削除しておきましょう。
削除するためには以下のコマンド実行します。

bash
aws cloudformation delete-stack --stack-name aws-batch --profile hoge

終わりに

前回の記事では、ローカル環境でDockerコンテナを作成・起動をしAWS S3のバケット名を取得しましたが、今回はAWS Batchを使ってECSでコンテナを作成・起動を行いました。
また今回はターミナルでコマンドを叩いてAWS Batchにジョブを送信しましたが、AWS lambdaを使ってジョブを送信することも可能です。またCloudwatch eventsでlambdaを定期的に起動することが出来ればBatchも定期実行することができます。次回は、AWS lambdaでBatchにジョブを送るlambda functionに関する記事を作成出来ればと思います。

kurakura0916
GCP, AWSを使った機械学習のインフラについて書いています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away