🔎
CDKでAWS Batch環境を作成する
はじめに
久しぶりにAWS Batch
をCDKで書こうとしたら、過去のソースが動かなくなっていました。
リリースノートをみたところ、v2.74.0
にて
コンピューティング環境
とジョブ定義
の2つの定義方法が変わったみたいです。
ComputeEnvironment
has been removed and replaced byManagedEc2EcsComputeEnvironment
,ManagedEc2EksComputeEnvironment
, andUnmanagedComputeEnvironment
.
JobDefinition
has been removed and replaced byEcsJobDefinition
,EksJobDefinition
, andMultiNodeJobDefinition
ECSとEKSとそれ以外を基準に分かれているので、便利になりました!
(ECS以外での環境でAWS Batchを利用したことはないですが…)。
2.87.0-alpha.0
時点でのドキュメントを見つつ変更をしていたのですが、
ちらほらとハマったので全体的な構成を共有します。
EC2とECSを利用してのAWS Batch環境になっています。
2.74.0-alpha.0
以降の書き方
BatchStack.ts
import {
App,
Size,
Stack,
StackProps,
aws_ec2,
aws_ecr,
aws_ecs,
aws_iam,
Duration,
} from 'aws-cdk-lib';
import * as aws_batch_alpha from '@aws-cdk/aws-batch-alpha';
const prefix = "zenn-example"
const ecrTag = "v0.1.0"
interface IParameters {
vpcId: `vpc-${string}`
ecrRepositoryArn: string
}
export class BatchStack extends Stack {
constructor(scope: App, id: string, params: IParameters, props?: StackProps) {
super(scope, id, props);
const vpc = aws_ec2.Vpc.fromLookup(this, "vpc", {
vpcId: params.vpcId
})
const securityGroup = new aws_ec2.SecurityGroup(this, "security-group", {
vpc,
securityGroupName: `${prefix}-security-group`,
allowAllOutbound: true,
})
const instanceRole = new aws_iam.Role(this, "instance-role", {
roleName: `${prefix}-instance-role`,
assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, `AmazonEC2ContainerServiceforEC2Role-batch`, "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
),
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, `CloudWatchLogsFullAccess-batch`, "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
)
]
})
const instanceProfile = new aws_iam.CfnInstanceProfile(this, "instance-profile", {
instanceProfileName: `${prefix}-instance-profile`,
roles: [instanceRole.roleName]
})
const batchComputeEnvironment = new aws_batch_alpha.ManagedEc2EcsComputeEnvironment(this, "batch-environment", {
vpc,
securityGroups: [securityGroup],
maxvCpus: 16,
minvCpus: 0,
instanceRole: instanceRole,
vpcSubnets: {
subnetType: aws_ec2.SubnetType.PUBLIC,
},
computeEnvironmentName: `${prefix}-compute-environment`,
spot: true,
useOptimalInstanceClasses: false,
instanceTypes: [
new aws_ec2.InstanceType("c6i.2xlarge"),
],
})
const containerImage = aws_ecs.ContainerImage.fromEcrRepository(
aws_ecr.Repository.fromRepositoryArn(this, "ecr", params.ecrRepositoryArn), ecrTag
)
const jobRole = new aws_iam.Role(this, `batch-job-role`, {
roleName: `${prefix}-batch-job-role`,
assumedBy: new aws_iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
managedPolicies: [
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, "AmazonECSTaskExecutionRolePolicy-job", "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
),
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, "CloudWatchLogsFullAccess-job", "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
)
]
})
const batchJobQueue = new aws_batch_alpha.JobQueue(this, "batch-job-queue", {
jobQueueName: `${prefix}-job-queue`,
computeEnvironments: [
{
computeEnvironment: batchComputeEnvironment,
order: 1
}
],
priority: 1
})
const batchJobDefinition = new aws_batch_alpha.EcsJobDefinition(this, "batch-job-definition", {
jobDefinitionName: `${prefix}-job-def`,
timeout: Duration.hours(2),
container: new aws_batch_alpha.EcsEc2ContainerDefinition(this, 'containerDefn', {
image: containerImage,
memory: Size.gibibytes(15),
cpu: 8,
readonlyRootFilesystem: true,
privileged: false,
user: "user",
jobRole,
logging: new aws_ecs.AwsLogDriver({streamPrefix: prefix})
}),
})
}
}
一応以下に2.73.0-alpha.0
以前の書き方も残しておきます。
以前の書き方。
BatchStack.ts
import {
App,
Stack,
StackProps,
aws_ec2,
aws_ecr,
aws_ecs,
aws_iam,
} from 'aws-cdk-lib';
import * as aws_batch_alpha from '@aws-cdk/aws-batch-alpha';
const prefix = "zenn-example"
const ecrTag = "v0.1.0"
interface IParameters {
vpcId: `vpc-${string}`
ecrRepositoryArn: string
}
export class BatchStack extends Stack {
constructor(scope: App, id: string, params: IParameters, props?: StackProps) {
super(scope, id, props);
const vpc = aws_ec2.Vpc.fromLookup(this, "vpc", {
vpcId: params.vpcId
})
const securityGroup = new aws_ec2.SecurityGroup(this, "security-group", {
vpc: vpc,
securityGroupName: `${prefix}-security-group`,
allowAllOutbound: true
})
const instanceRole = new aws_iam.Role(this, "instance-role", {
roleName: `${prefix}-instance-role`,
assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, `AmazonEC2ContainerServiceforEC2Role-batch`, "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
),
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, `CloudWatchLogsFullAccess-batch`, "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
)
]
})
const instanceProfile = new aws_iam.CfnInstanceProfile(this, "instance-profile", {
instanceProfileName: `${prefix}-instance-profile`,
roles: [instanceRole.roleName]
})
const containerImage = aws_ecs.ContainerImage.fromEcrRepository(
aws_ecr.Repository.fromRepositoryArn(this, "ecr", params.ecrRepositoryArn), ecrTag
)
const batchComputeEnvironment = new aws_batch_alpha.ComputeEnvironment(this, "batch-environment", {
computeEnvironmentName: `${prefix}-compute-environment`,
computeResources: {
vpc: vpc,
maxvCpus: 16,
minvCpus: 0,
securityGroups: [securityGroup],
instanceRole: instanceProfile.attrArn,
type: aws_batch_alpha.ComputeResourceType.SPOT,
instanceTypes: [
new aws_ec2.InstanceType("c6i.2xlarge")
]
}
})
const jobRole = new aws_iam.Role(this, `batch-job-role`, {
roleName: `${prefix}-batch-job-role`,
assumedBy: new aws_iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
managedPolicies: [
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, "AmazonECSTaskExecutionRolePolicy-job", "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
),
aws_iam.ManagedPolicy.fromManagedPolicyArn(
this, "CloudWatchLogsFullAccess-job", "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
)
]
})
const batchJobQueue = new aws_batch_alpha.JobQueue(this, "batch-job-queue", {
jobQueueName: `${prefix}-job-queue`,
computeEnvironments: [
{
computeEnvironment: batchComputeEnvironment,
order: 1
}
],
priority: 1
})
const batchJobDefinition = new aws_batch_alpha.JobDefinition(this, "batch-job-definition", {
jobDefinitionName: `${prefix}-job-def`,
container: {
image: containerImage,
jobRole: jobRole,
vcpus: 8,
memoryLimitMiB: 14000,
logConfiguration: {
logDriver: aws_batch_alpha.LogDriver.AWSLOGS
},
readOnly: true,
privileged: false,
user: "user"
}
})
}
}
おわりに
元々@aws-cdk/aws-batch-alpha
はalpha版なので大きな変更は入るかなと思っていましたが、
実際に変更が入るとびっくりしました。
Discussion