現象
AWSのCloudformationで以下のようにECSのクラスターとサービスを同時に作成しようとしたところ、 "Unable to assume the service linked role. Please verify that the ECS service linked role exists." というエラーが発生した。(※テンプレートの細部は省略)
AWSTemplateFormatVersion: "2010-09-09"
Description: "ECS"
Resources:
ECSCluster:
Type: "AWS::ECS::Cluster"
Properties:
ClusterName: "TestCluster"
CapacityProviders:
- "FARGATE_SPOT"
- "FARGATE"
ECSService:
Type: "AWS::ECS::Service"
Properties:
ServiceName: "backend-server"
Cluster: !GetAtt ECSCluster.Arn
LoadBalancers:
-
TargetGroupArn: !ImportValue target-group
ContainerName: "server"
ContainerPort: 8080
DesiredCount: 1
LaunchType: "FARGATE"
PlatformVersion: "LATEST"
TaskDefinition: !Ref ECSTaskDefinition
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: "ENABLED"
SecurityGroups: ...
Subnets: ...
HealthCheckGracePeriodSeconds: 0
SchedulingStrategy: "REPLICA"
ECSTaskDefinition:
Type: "AWS::ECS::TaskDefinition"
Properties:
ContainerDefinitions:
しかもこのエラーは初回のみで、2回目以降は発生しない。また、手動でECSを構築したことがある場合にも発生しない。
原因
Cloudformationのマニュアルを読んでいたら以下のような記述があった。
If your account has already created the Amazon ECS service-linked role, that role is used by default for your service unless you specify a role here. The service-linked role is required if your task definition uses the awsvpc network mode or if the service is configured to use service discovery, an external deployment controller, multiple target groups, or Elastic Inference accelerators in which case you should not specify a role here. For more information, see Using service-linked roles for Amazon ECS in the Amazon Elastic Container Service Developer Guide.
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html
Under most circumstances, you don't need to manually create the service-linked role. For example, when you create a new cluster (for example, with the Amazon ECS first-run experience, the cluster creation wizard, or the AWS CLI or SDKs), or create or update a service in the AWS Management Console, Amazon ECS creates the service-linked role for you, if it does not already exist.
つまり、ECSをいい感じに動作させるための「サービスにリンクされたロール」が必要になるものの、多くの場合はAWSが勝手に作ってくれるのでわざわざ手動で作る必要はない。
しかしCloudformationなど手動作成以外の方法でECSを構築する場合、どうもこれらサービスにリンクされたロールが作成されて利用可能になる前に処理が進んでしまい、エラーとなっているようだ。
解決方法
以下のようなCloudformationを定義して、ECSの構築の前にサービスにリンクされたロールを作成すればよいようだ。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Service linked role"
Resources:
AWSServiceLinkedRole:
Type: AWS::IAM::ServiceLinkedRole
Properties:
AWSServiceName: ecs.amazonaws.com