LoginSignup
8
4

More than 3 years have passed since last update.

CDKを使ってBatch環境の構築とECRへプッシュを行う

Last updated at Posted at 2020-06-08

概要

Dockerイメージの作成、ECRリポジトリの作成・プッシュ、Batch環境(コンピューティング環境、ジョブキュー、ジョブ定義)の構築をCDKで行います。
コンピューティング環境の作成も行いますが、コンピューティング環境はCDKを使っても後からパラメータを変更することができず、パラメータを変えるには一度デストロイする必要があります。
そのためジョブキューやジョブ定義とは別で作成しておくことをお勧めします。

前提

CDKをデプロイするためのロールや環境は準備してあることを前提とした記事です。

用意しておくもの

  • Dockerfile
    • 使用したいDockerfileをプロジェクトディレクトリから見て ./Dockerfile に配置してください

既存のコンピューティング環境を使用したい場合

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

コンピューティング環境の作成から行いたい場合

  • VPC
    • VPC ID
  • サブネット
    • サブネットID
    • アベイラビリティゾーン
    • ルートテーブルID
  • セキュリティーグループ
    • セキュリティグループID

環境

  • Typescript 4.1.2
  • CDK 1.75.0

CDKを書いていく

今回はサンプルとしてジョブ定義を利用してジョブを送信すると日付が表示されるバッチを作ります。
以降のコードはCDKの lib/cdk-stack.ts のconstructor()内に記述します。
最低限の設定しか行わないため、必要に合わせてパラメータを追加・変更してください。
サンプルコード

1. コンピューティング環境の用意

A. 既存のコンピューティング環境を使用したい場合

コンピューティング環境の取得

const computeEnvironment: batch.ComputeEnvironment = batch.ComputeEnvironment.fromComputeEnvironmentArn(
  this, 'BatchCompute', 'arn:aws:batch:ap-northeast-1:0123456789:compute-environment/ExampleComputeEnvironment'
);

B. 新規のコンピューティング環境を作成したい場合

ネットワーク情報の取得

コンピューティング環境の作成に使用するネットワーク周りの情報を取得します。

VPCの取得
const vpc: ec2.IVpc = ec2.Vpc.fromLookup(this, 'VPC', {
  vpcId: 'vpc-0123456789abcdef',
});
サブネットの取得
const selectSubnets: ec2.SelectedSubnets = vpc.selectSubnets({
  subnets: [
    ec2.Subnet.fromSubnetAttributes(this, 'Subnet', {
      subnetId: 'subnet-0123456789abcdef',
      availabilityZone: 'ap-northeast-1a',
      routeTableId: 'rtb-0123456789abcdef',
    }),
  ],
});
セキュリティグループの取得
const securityGroup: ec2.ISecurityGroup = ec2.SecurityGroup.fromSecurityGroupId(
  this, 'SecurityGroup', 'sg-0123456789abcdef',
);

ロールの作成

バッチ実行に必要な各ロールを作成します。

Batch実行用のロール作成
const batchRole: iam.IRole = new iam.Role(this, 'BatchRole', {
  roleName: 'ExampleBatchRole',
  assumedBy: new iam.CompositePrincipal(
    new iam.ServicePrincipal('batch.amazonaws.com'),
  ),
  managedPolicies: [
    iam.ManagedPolicy.fromManagedPolicyArn(
      this,
      'AWSBatchServiceRole',
      'arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole',
    ),
  ],
});
インスタンス用のロール作成
const instanceRole: iam.IRole = new iam.Role(this, 'InstanceRole', {
  roleName: 'ExampleInstanceRole',
  assumedBy: new iam.CompositePrincipal(
    new iam.ServicePrincipal('ec2.amazonaws.com'),
  ),
  managedPolicies: [
    iam.ManagedPolicy.fromManagedPolicyArn(
      this,
      'AmazonEC2ContainerServiceforEC2Role',
      'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role',
    ),
  ],
});
インスタンスプロフィールを作成
const instanceProfile: iam.CfnInstanceProfile = new iam.CfnInstanceProfile(this, 'InstanceProfile', {
  instanceProfileName: 'Example',
  roles: [instanceRole.roleName],
});

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

const computeEnvironment: batch.ComputeEnvironment = new batch.ComputeEnvironment(this, 'BatchCompute', {
  computeEnvironmentName: 'ExampleComputeEnvironment',
  computeResources: {
    type: batch.ComputeResourceType.ON_DEMAND,
    instanceRole: instanceProfile.attrArn,
    vpc: vpc,
    vpcSubnets: selectSubnets,
    securityGroups: [securityGroup],
  },
  serviceRole: batchRole,
});

2. イメージの用意

ビルドとプッシュ

ECR上にイメージをプッシュします。
指定したリポジトリがECRに存在していなければ、作成されるため事前にリポジトリ作成をしておく必要はありません。
またDockerfileを指定するだけでイメージのプッシュまでできるため、事前のビルドは不要です。

const tag = '適当なタグ名'
const imageAsset: cdk.DockerImageAssetLocation = this.synthesizer.addDockerImageAsset({
sourceHash: tag,
  directoryName: `${__dirname}/../`,
  repositoryName: 'example',
})

3. ジョブキュー・ジョブロールの用意

ジョブ実行用のロール作成

const jobRole: iam.IRole = new iam.Role(this, 'JobRole', {
  roleName: 'ExampleJobRole',
  assumedBy: new iam.CompositePrincipal(
    new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
  ),
});

ジョブキューを作成

new batch.JobQueue(this, 'JobQueue', {
  jobQueueName: 'ExampleJobQueue',
  computeEnvironments: [{
      computeEnvironment: computeEnvironment,
      order: 1,
  }],
});

ジョブ定義を作成

dateコマンドを実行するジョブ定義を作成します。

new batch.JobDefinition(this, 'JobDefinition', {
  jobDefinitionName: 'ExampleJobDefinition',
  container: {
    command: ['date'],  // コンテナ内で実行されるコマンド
    environment: {'TZ': 'Asia/Tokyo'},
    image: image,
    jobRole: jobRole,
    vcpus: 1,
    memoryLimitMiB: 100,
  },
});

環境が正しく作られたか確かめる

ジョブを送信する

以下のコマンドでジョブキューにジョブを送信してみましょう。
AWSコンソールから送信することも可能です。

aws batch submit-job \
    --job-name "test" \
    --job-queue "arn:aws:batch:ap-northeast-1:0123456789:job-queue/ExampleJobQueue" \
    --job-definition "arn:aws:batch:ap-northeast-1:0123456789:job-definition/ExampleJobDefinition"

ジョブが完了したことを確認する

AWSコンソールからジョブがsucceededにあることを確認しましょう。
ジョブを選択して、View logsから実行日時が出力されていることを確認できれば正常に環境構築ができています。
スクリーンショット 2020-06-08 15.33.01.png

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4