ECSのFargateコンテナに入ることができるようになりました。
詳しくは、下記のAWSブログを参照。
CloudFormationでECSを構築して試してみました。
環境
- Windows10のWSL2(ubuntu20.04)
- docker20.10
- aws-cli/2.1.13
- Administorator権限のアクセスキーを使用します。
- blue21の名称でprofileを使用します。
- aws-cli用session mamanger plugin
- Rain v1.1.2
cfnテンプレート
- VPC、ECS、Fargateを構築します。
- AWS::ECS::ServiceのEnableExecuteCommandを trueにすると Fargateに入れるようになります。
- 今回は nginx コンテナを1つ起動します。
AWSTemplateFormatVersion: "2010-09-09" Description: VPC,ECS Parameters: VpcCidr: Description: VPC CIDR Type: String Default: 10.0.0.0/16 SubnetPublicCidr: Description: Subnet CIDR. (public) Type: String Default: 10.0.0.0/24 Resources: MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Sub ${VpcCidr} EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default RouteTablePublic: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MyVPC SubnetPublic: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC CidrBlock: !Sub ${SubnetPublicCidr} MapPublicIpOnLaunch: true AvailabilityZone: !Select - 0 - !GetAZs "" SubnetPublicIn1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref SubnetPublic RouteTableId: !Ref RouteTablePublic InternetGateway: Type: AWS::EC2::InternetGateway AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref MyVPC InternetGatewayId: !Ref InternetGateway RouteIgw: Type: AWS::EC2::Route Properties: RouteTableId: !Ref RouteTablePublic DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway EcsCluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Sub ${AWS::StackName} CapacityProviders: - FARGATE_SPOT DefaultCapacityProviderStrategy: - CapacityProvider: FARGATE_SPOT Weight: 1 EcsSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: ECS Security Group VpcId: !Ref MyVPC SecurityGroupIngress: - CidrIp: 10.0.0.0/16 FromPort: -1 IpProtocol: "-1" ToPort: -1 EcsService: Type: AWS::ECS::Service Properties: ServiceName: !Sub ${AWS::StackName} Cluster: !Ref EcsCluster DesiredCount: 1 EnableExecuteCommand: true TaskDefinition: !Ref EcsTaskDefinition DeploymentController: Type: ECS DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 100 NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED SecurityGroups: - !Ref EcsSecurityGroup Subnets: - !Ref SubnetPublic EcsTaskCloudwatchLogsGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "${AWS::StackName}" RetentionInDays: 1 ECSTaskRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${AWS::StackName}-task AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: [ecs-tasks.amazonaws.com] Action: ['sts:AssumeRole'] Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess Policies: - PolicyName: ssm PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - ssmmessages:CreateControlChannel - ssmmessages:CreateDataChannel - ssmmessages:OpenControlChannel - ssmmessages:OpenDataChannel Resource: - '*' ECSTaskExecRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${AWS::StackName}-taskexec AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: [ecs-tasks.amazonaws.com] Action: ['sts:AssumeRole'] Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy EcsTaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub "${AWS::StackName}" TaskRoleArn: !GetAtt ECSTaskRole.Arn ExecutionRoleArn: !GetAtt ECSTaskExecRole.Arn Cpu: "256" Memory: "512" NetworkMode: awsvpc RequiresCompatibilities: - FARGATE ContainerDefinitions: - Name: nginx Essential: true Image: nginx LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref EcsTaskCloudwatchLogsGroup awslogs-region: !Sub ${AWS::Region} awslogs-stream-prefix: nginx PortMappings: - HostPort: 80 ContainerPort: 80
Makefile
- 検証で使用するコマンドをMakefileに記述します。
- 下記サンプルではTABがスペース8個に置き換わっているので注意。(そのままコピペしても動きません。)
- cfn-python-lintについては下記URL参照
https://github.com/aws-cloudformation/cfn-python-lint
#----------------------------------------------------- # valiables #----------------------------------------------------- AWSPROFILE := blue21 #----------------------------------------------------- # validate cfn template #----------------------------------------------------- all: lint lint: docker run --rm -v `pwd`:/data cfn-python-lint /data/cfn_*.yml #----------------------------------------------------- # deploy #----------------------------------------------------- deploy: $(eval STACK_NAME := Blue21EcsPoC) rain deploy cfn_ecs.yml $(STACK_NAME) $(RAINOPT) \ --profile $(AWSPROFILE) \ --params \ VpcCidr=10.0.0.0/16,\ SubnetPublicCidr=10.0.0.0/24 #----------------------------------------------------- # stack #----------------------------------------------------- # LIST Stack stackls: aws cloudformation describe-stacks \ --profile $(AWSPROFILE) \ --query 'Stacks[?contains(StackName,`Blue21`)].{StackName:StackName,StackStatus:StackStatus,Desc:Description}' \ --output table # DELETE Stack stackrm: rain rm $(STACK_NAME) \ --profile $(AWSPROFILE) #----------------------------------------------------- # util #----------------------------------------------------- update_svc: $(eval CLUSTER_NAME := Blue21EcsPoC) $(eval SERVICE_NAME := Blue21EcsPoC) aws ecs update-service --cluster $(CLUSTER_NAME) --service $(SERVICE_NAME) --enable-execute-command --profile $(AWSPROFILE) list_task: $(eval CLUSTER_NAME := Blue21EcsPoC) $(eval SERVICE_NAME := Blue21EcsPoC) aws ecs list-tasks --cluster $(CLUSTER_NAME) --service-name $(SERVICE_NAME) --profile $(AWSPROFILE) describe_task: $(eval CLUSTER_NAME := Blue21EcsPoC) aws ecs describe-tasks --cluster $(CLUSTER_NAME) --tasks $(TASK) --profile $(AWSPROFILE) exec_task: $(eval CLUSTER_NAME := Blue21EcsPoC) aws ecs execute-command --cluster $(CLUSTER_NAME) --task $(TASK) --container nginx --command "/bin/bash" --interactive --profile $(AWSPROFILE)
ファイルの配置
cfnテンプレート(cfn_ecs.yml)とMakefileは、下記のようにファイルを配置します。
$ tree . . ├── Makefile └── cfn_ecs.yml 0 directories, 2 files
動作確認
cfn-python-lintでcfnテンプレートをテストします。
下記のようにcfn-python-lint が、まだ、EnableExecuteCommandに対応してないようなのでエラーになりますが、無視します。
$ make lint docker run --rm -v `pwd`:/data cfn-python-lint /data/cfn_*.yml E3002 Invalid Property Resources/EcsService/Properties/EnableExecuteCommand /data/cfn_ecs.yml:88:7 make: *** [Makefile:22: lint] Error 2
Rainでスタックを作成します。
$ make deploy
下図は実行例です。
スタックを確認します。
$ make stackls
下図は実行例です。
タスク一覧を表示します。
arn の最後の部分(3d5562a63bb94749a67048002f2995bf)を、あとで、使用します。
$ make list_task aws ecs list-tasks --cluster Blue21EcsPoC --service-name Blue21EcsPoC --profile blue21 { "taskArns": [ "arn:aws:ecs:us-east-1:0123456789:task/Blue21EcsPoC/3d5562a63bb94749a67048002f2995bf" ] }
タスクの詳細を表示します。
platformVersionが1.4.0で、enableExecuteCommand が true であれば、Fargateに入れます。
make describe_task TASK=3d5562a63bb94749a67048002f2995bf aws ecs describe-tasks --cluster Blue21EcsPoC --tasks 3d5562a63bb94749a67048002f2995bf --profile blue21 { "tasks": [ { "attachments": [ { ~省略~ "desiredStatus": "RUNNING", "enableExecuteCommand": true, "group": "service:Blue21EcsPoC",~省略~ "platformVersion": "1.4.0", ~省略~
Fargateタスクに入ります。
$ make exec_task TASK=3d5562a63bb94749a67048002f2995bf
下図は実行例です
Fargateコンテナで実行したコマンドはCloudWatchLogsに記録されます。
あとかたずけ
CloudFormationで構築した環境を削除します。
$ make stackrm STACK_NAME=Blue21EcsPoC
下図は実行例です。