AWS BatchをFagateで構築したのですが、Fargateの
CloudFormationサンプルが少なかったので記事を投稿します。
ついでにAWS BatchからEFSのマウントも行ってみました。
Fargateを利用する場合、vCPUとMemoryは指定の組み合わせのものだけが利用可能で
vCPUは最大でも4までになります。
リソースに関する定義はEC2とFargateでは結構違うので要注意です。
AWS BatchのEFSマウントは少し苦労したのですが以下の記事を参考にしました。
記事のオペレーションをCFn化しています。
Introducing support for per-job Amazon EFS volumes in AWS Batch
Amazon EFSのテンプレート
セキュリティグループのIDですがRef参照の場合
デフォルトVPCに属するかどうかで動きが変わるところがあるので要注意です。
今回は以下のように取得しています。
!GetAtt LambdaSecurityGroup.GroupId
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Env:
Type: String
Prifix:
Type: String
Mappings:
EnvMap:
dev:
# EFSを構築するVPCのID
MyVpcId: "vpc-xxx"
# EFSを構築するサブネット
MySubnetID1: "subnet-xxxx"
MySubnetID2: "subnet-xxxx"
MySubnetID3: "subnet-xxxx"
Resources:
LambdaSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap [EnvMap, !Ref Env, MyVpcId]
GroupDescription: Security group for Lambda
MountTargetSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap [EnvMap, !Ref Env, MyVpcId]
GroupName: !Sub
- "${prefix}mount-target-security-group"
- { prefix: !Ref Prifix }
GroupDescription: Security group for mount target
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: "2049"
ToPort: "2049"
CidrIp: 0.0.0.0/0
# EFS FileSystem
EfsFileSystem:
Type: AWS::EFS::FileSystem
Properties:
FileSystemTags:
- Key: "Name"
Value: "EfsFileSystem For xxxx"
PerformanceMode: maxIO
BackupPolicy:
Status: 'DISABLED'
Encrypted: False
EfsMountTarget1:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EfsFileSystem
SubnetId: !FindInMap [EnvMap, !Ref Env, MySubnetID1]
SecurityGroups:
- !GetAtt MountTargetSecurityGroup.GroupId
EfsMountTarget2:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EfsFileSystem
SubnetId: !FindInMap [EnvMap, !Ref Env, MySubnetID2]
SecurityGroups:
- !GetAtt MountTargetSecurityGroup.GroupId
EfsMountTarget3:
Type: AWS::EFS::MountTarget
Properties:
FileSystemId: !Ref EfsFileSystem
SubnetId: !FindInMap [EnvMap, !Ref Env, MySubnetID3]
SecurityGroups:
- !GetAtt MountTargetSecurityGroup.GroupId
# AccessPoint
EfsAccessPoint:
Type: 'AWS::EFS::AccessPoint'
Properties:
FileSystemId: !Ref EfsFileSystem
AccessPointTags:
- Key: "Name"
Value: "EfsAccessPoint For xxx"
PosixUser:
Uid: "1001"
Gid: "1001"
RootDirectory:
CreationInfo:
OwnerGid: "1001"
OwnerUid: "1001"
Permissions: "0777"
Path: "/mnt/efs"
Outputs:
EfsFileSystemId:
Value: !GetAtt EfsFileSystem.FileSystemId
EfsAccessPointArn:
Value: !GetAtt EfsAccessPoint.Arn
EfsAccessPointId:
Value: !Ref EfsAccessPoint
MySubnetID1:
Value: !FindInMap [EnvMap, !Ref Env, MySubnetID1]
MySubnetID2:
Value: !FindInMap [EnvMap, !Ref Env, MySubnetID2]
MySubnetID3:
Value: !FindInMap [EnvMap, !Ref Env, MySubnetID3]
MyVpcId:
Value: !FindInMap [EnvMap, !Ref Env, MyVpcId]
SecurityGroupIdForLambda:
Value: !GetAtt LambdaSecurityGroup.GroupId
AWS Batchテンプレート
AWSTemplateFormatVersion: '2010-09-09'
# これらのパラメータはtemplate_efs.yamlで生成したものを親テンプレートから受け取る
Parameters:
Env:
Type: String
Prifix:
Type: String
EfsSubnetID1:
Type: String
EfsSubnetID2:
Type: String
EfsSubnetID3:
Type: String
MyVpcId:
Type: String
EfsFileSystemId:
Type: String
EfsAccessPointId:
Type: String
Mappings:
EnvMap:
dev:
EcrRepoForBatch: "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/repo-name:latest"
Resources:
SecurityGroupForBatch:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref MyVpcId
GroupDescription: Security group for Batch Compute Env
Tags:
- Key: "Name"
Value: !Sub
- "${prefix}security-group-batch"
- { prefix: !Ref Prifix }
# コンピューティング環境
MyComputeEnv:
Type: "AWS::Batch::ComputeEnvironment"
Properties:
Type: MANAGED
State: ENABLED
ComputeEnvironmentName: !Sub
- "${prefix}my-compute-env"
- { prefix: !Ref Prifix }
ComputeResources:
# 最大vcpu数
MaxvCpus: 256
# 最小vcpu
# This parameter isn't applicable to jobs that are running on Fargate resources,
# and shouldn't be specified.
# MinvCpus: 0
SecurityGroupIds:
- !GetAtt SecurityGroupForBatch.GroupId
Type: FARGATE
Subnets:
- !Ref MySubnetID1
- !Ref MySubnetID2
- !Ref MySubnetID3
# JOBキュー定義
MyJobQueue:
Type: AWS::Batch::JobQueue
Properties:
ComputeEnvironmentOrder:
- Order: 1
ComputeEnvironment: !Ref MyComputeEnv
State: ENABLED
Priority: 1
JobQueueName: !Sub
- "${prefix}my-job-queue"
- { prefix: !Ref Prifix }
MyJobRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
- 'arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess'
# JOB定義
MyJobDefinition:
Type: AWS::Batch::JobDefinition
Properties:
Type: container
PlatformCapabilities:
- FARGATE
JobDefinitionName: !Sub
- "${prefix}my-job-definition"
- { prefix: !Ref Prifix }
Timeout:
AttemptDurationSeconds: 43200
RetryStrategy:
Attempts: 1
ContainerProperties:
# 自動IP割当(プライベート環境の場合はDISABLEDにする)
NetworkConfiguration:
AssignPublicIp: ENABLED
FargatePlatformConfiguration:
PlatformVersion: 1.4.0
Image: !FindInMap ["EnvMap", !Ref Env, "EcrRepoForBatch"]
JobRoleArn: !GetAtt MyJobRole.Arn
# リソース定義。VPCとMEMORYの組み合わせがあるのでドキュメント参照
ResourceRequirements:
- Type: VCPU
Value: 4
- Type: MEMORY
Value: 8192
Volumes:
- EfsVolumeConfiguration:
FileSystemId: !Ref EfsFileSystemId
AuthorizationConfig:
AccessPointId: !Ref EfsAccessPointId
Iam: "ENABLED"
# ホスト内のルートディレクトリとしてマウントする
# Amazon EFS ファイルシステム内のディレクトリ
# AccessPointを指定する場合、ルートは「/」にする必要がある。
RootDirectory: "/"
TransitEncryption: "ENABLED"
Name: "efs-volume"
MountPoints:
- ContainerPath: "/mnt/efs"
SourceVolume: "efs-volume"
ExecutionRoleArn: !GetAtt MyJobRole.Arn
Command:
- 'job.sh'
Dockerfile
AWS Batchのイメージ作成用Dockerfileサンプル。
Amazon Linux2をベースにpython3.8とAWSCLIv2をインストールしています。
FROM public.ecr.aws/amazonlinux/amazonlinux:latest
RUN yum install -y amazon-linux-extras
RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# AWS CLIv2インストール
COPY awscliv2.zip /tmp
RUN unzip /tmp/awscliv2.zip -d /tmp/awscli
RUN /tmp/awscli/aws/install --bin-dir /usr/bin --install-dir /usr/bin/aws-cli
#Python3.8インストール
RUN amazon-linux-extras install python3.8 -y
RUN yum install -y python38-devel
RUN pip3.8 install --upgrade pip
RUN pip install setuptools --upgrade
RUN pip install boto3
以上