ECS(EC2)のCloudFormation最小構成
awsEC2でECSのServiceを動かすCFnテンプレートを書く。以前Fargateで動かしたものを一部再利用する。
ECS FargateでSidecarのFluentdでログをS3に送る構成をCloudFormationで構築する - sambaiz-net
EC2で動かす場合、自分でリソースが不足しないようにインスタンスのスケールを気遣うことになるがprivilegedをtrueにするなどEC2でしかできないことがある。あと同リソースで比較すると安い。
まずはEC2インスタンス以外のリソースを書く。LaunchType以外はFargateのときとほぼ同じ。 LBなしでバッチのようなものを動かすことを想定した最小構成。
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: 'test-cluster'
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: 'test-task-log-group'
RetentionInDays: 1
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- EC2
Cpu: '256'
Memory: '512'
ContainerDefinitions:
- Name: 'app'
Image: 'busybox'
EntryPoint:
- 'sh'
- '-c'
Command:
- 'while true; do echo "{\"foo\":1000,\"time\":\"2019-05-09T20:00:00+09:00\"}"; sleep 10; done'
Essential: 'true'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Ref LogGroup
awslogs-region: 'ap-northeast-1'
awslogs-stream-prefix: 'app'
Environment:
- Name: 'TZ'
Value: 'Asia/Tokyo'
Volumes:
- Name: 'varlog'
ECSService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref ECSCluster
LaunchType: EC2
DesiredCount: 1
TaskDefinition: !Ref TaskDefinition
ServiceName: 'test-service'
EC2インスタンスとECSクラスタの紐付きはAssociationのようなリソースがあるわけではなく、
ECS-optimized AMIからecho ECS_CLUSTER=<cluster name> >> /etc/ecs/ecs.config
で指定したクラスタにインスタンスを登録する。そのために必要なroleを付ける。
各リージョンごとのAMI IDをMappingsで書き並べてもいいが、次のように書くとParameter Storeから最新のAMI IDを取得できる。
Parameters:
ECSAMI:
Description: AMI ID
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id
なお、amazon-linux2ルートデバイスは/dev/sda1
ではなく/dev/xvda
なので
間違えると Client.InstanceInitiatedShutdown: Instance initiated shutdown
でインスタンスが落ち続けてServiceがstableにならず失敗する。
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AvailabilityZones:
!GetAZs ""
LaunchConfigurationName: !Ref LaunchConfig
MinSize: "1"
MaxSize: "1"
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ['ec2.amazonaws.com']
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'ecs:CreateCluster'
- 'ecs:DeregisterContainerInstance'
- 'ecs:DiscoverPollEndpoint'
- 'ecs:Poll'
- 'ecs:RegisterContainerInstance'
- 'ecs:StartTelemetrySession'
- 'ecs:Submit*'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref 'EC2Role'
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref ECSAMI
IamInstanceProfile: !Ref EC2InstanceProfile
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
InstanceType: "t2.small"
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
VolumeSize: "30"
VolumeType: "gp2"
CDKでALBとECS(EC2)クラスタを作成し、ecs-cliでDocker Composeの構成をデプロイする - sambaiz-net