AWS コンソール上で CodeDeploy でデプロイ管理されている ECS Service をアップデートすると capacity provider が FARGATE になってしまう件

capacity provider strategy で FARGATE_SPOT に weight = 1 で全振りしていた FARGATE がいます。

  • FARGATE_SPOT weight = 1
  • FARGATE weight = 0

AWS コンソール上で ECS Service をアップデートした際の問題

Configure service で FARGATE_SPOT weight = 1 に指定しています。

ちょっとした検証でタスク定義をちょこっと変えたものを AWS コンソール上でタスク更新だけしてデプロイしました。

すると…

capacity provider strategy の設定がなくなっている…

何故こんなことが起きるのか?

AWS コンソール上で ECS Service 更新ステップを進むと
Configure CodeDeploy Deployment の Revision の AppSpec をクリックしてみると以下設定になっていました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"version": 1,
"Resources": [
{
"TargetService": {
"Type": "AWS::ECS::Service",
"Properties": {
"TaskDefinition": "<タスク定義 ARN>",
"LoadBalancerInfo": {
"ContainerName": "nginx",
"ContainerPort": 80
},
"PlatformVersion": "LATEST"
}
}
}
]
}

ここで capacity provider strategy の設定がありません。

その影響で更新完了後、 capacity provider strategy の設定がなくなってしまいました。

terraform で capacity provider strategy を管理していると
terraform apply 実施すると ECS Service が意図せず再作成となりダウンタイムが発生します。

1
2
3
4
5
6
7
8
9
10
11
  # aws_ecs_service.app must be replaced
-/+ resource "aws_ecs_service" "app" {

+ capacity_provider_strategy { # forces replacement
+ capacity_provider = "FARGATE"
+ weight = 0
}
+ capacity_provider_strategy { # forces replacement
+ capacity_provider = "FARGATE_SPOT"
+ weight = 1
}

対策

CodeDeploy で管理されている ECS Service の更新は
aws-cli や CodeDeploy 経由でデプロイします。

aws deploy create-deployment のオプションで全て対応しようとするとやや複雑になります。

1
2
3
4
aws deploy create-deployment \
--application-name xxx \
--deployment-group-name yyy \
--revision '{"revisionType": "AppSpecContent", "appSpecContent": {"content": "{\"version\": 0.0, \"Resources\": [{\"TargetService\": {\"Type\": \"AWS::ECS::Service\", \"Properties\": {\"TaskDefinition\": \"<タスク定義 ARN>\", \"LoadBalancerInfo\": {\"ContainerName\": \"nginx\", \"ContainerPort\": 80},\"CapacityProviderStrategy\": [{\"Base\":0,\"CapacityProvider\":\"FARGATE_SPOT\",\"Weight\":1},{\"Base\":0,\"CapacityProvider\":\"FARGATE\",\"Weight\":0}]}}}]}"}}'

ファイルにまとめておくとコマンドがシンプル ♪
(content の定義が String なので、1 行にまとめて文字列として定義しており見づらさはある)

1
aws deploy create-deployment --cli-input-json file://deployment.json

deployment.json

1
2
3
4
5
6
7
8
9
10
{
"applicationName": "xxx",
"deploymentGroupName": "yyy",
"revision": {
"revisionType": "AppSpecContent",
"appSpecContent": {
"content": "{\"version\": 0.0, \"Resources\": [{\"TargetService\": {\"Type\": \"AWS::ECS::Service\", \"Properties\": {\"TaskDefinition\": \"<タスク定義 ARN>\", \"LoadBalancerInfo\": {\"ContainerName\": \"nginx\", \"ContainerPort\": 80},\"CapacityProviderStrategy\": [{\"Base\":0,\"CapacityProvider\":\"FARGATE_SPOT\",\"Weight\":1},{\"Base\":0,\"CapacityProvider\":\"FARGATE\",\"Weight\":0}]}}}]}"
}
}
}

appspec を明示的に指定することで capacity provider strategy を明示的に残すようにできることを確認しました。

以上
参考になれば幸いです。

AWS コンソール上で CodeDeploy でデプロイ管理されている ECS Service をアップデートすると capacity provider が FARGATE になってしまう件

https://kenzo0107.github.io/2022/05/26/2022-05-27-update-ecs-service-on-aws-console/

Author

Kenzo Tanaka

Posted on

2022-05-27

Licensed under

コメント