[小ネタ] ECSをBlue/Greenデプロイに変更したらFargateが1.4.0から1.3.0に戻ってしまう

原因は、appspec.ymlでplatform versionを指定していなかったからでした。
2021.03.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ちゃだいん(@chazuke4649)です。

超小ネタですが先日こんなことでハマったのでシェアします。

事象

ECS on Fargateにて、デプロイ方式をローリングアップデートからBlue/Greenデプロイメントに変更したところ、既存ServiceにてFargateのプラットフォームバージョンを 1.4.0を指定しているのに、デプロイされるタスクが 1.3.0になってしまう事象が発生しました。

原因

結論から言うと

appspec.ymlでplatform versionを指定していなかったからでした。

詳細

本環境ではCodePipelineでCI/CDパイプラインを実行しており、そのデプロイステージ部分をECSによるローリングアップデートから、CodeDeployによるBlue/Greenアップデートに変更しました。

それによってタスクのデプロイメントを実行・管理する役割はECS ServiceからCodeDeployに移管されることになります。実際にECS Service側の設定でもデプロイコントローラーを CODE_DEPLOYに変更する必要があります。

CodeDeployのデプロイ設定としてappspec.ymlを使用するケースがあります。今回ECS向けのappspec.ymlのドキュメントを確認するとFargateのプラットフォームバージョンをoptionで指定することができ、指定していないとデフォルト値としてLATESTが指定されます。

現時点(2021/3/5)では LATEST1.3.0 だったので、デプロイされたタスクのプラットフォームが 1.3.0に更新されたという訳です。

appspec.yml

Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "task-definition-ARN"
        LoadBalancerInfo: 
          ContainerName: "ECS-container-name-for-your-ECS-application" 
          ContainerPort: port-used-by-your-ECS-application
# Optional properties
        PlatformVersion: "ecs-service-platform-version" ##←ここで指定できる
        NetworkConfiguration:
          AwsvpcConfiguration:
            Subnets: ["ecs-subnet-1","ecs-subnet-n"] 
            SecurityGroups: ["ecs-security-group-1","ecs-security-group-n"] 
            AssignPublicIp: "ENABLED-or-DISABLED"

PlatformVersion: オプション。デプロイされた Amazon ECS サービス内の、Fargate タスクのプラットフォームのバージョン。詳細についてはAWS、「Fargate プラットフォームのバージョン」を参照してください。指定しない場合、デフォルトで LATEST が使用されます。

引用元)AppSpec 「resources」セクション (Amazon ECS および AWS Lambda デプロイのみ) - AWS CodeDeploy

When specifying a platform version, you can use either a specific version number, for example 1.4.0, or LATEST (which uses the 1.3.0 platform version). AWS Fargate platform versions - Amazon ECS

LATESTがどのバージョンを指すのかは変更される可能性があるので随時公式ドキュメントで確認する必要があります。これら変更による影響を減らすために`LATEST`ではなく明示的に`1.4.0`などと指定することが推奨されます。

解決

以下の通りバージョンを 1.4.0 に指定し、再度デプロイしたところ無事 1.4.0 になりました。

appspec.yml

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "<TASK_DEFINITION>"
        LoadBalancerInfo:
          ContainerName: "nginx"
          ContainerPort: 80
        PlatformVersion: "1.4.0"

参考資料

[アップデート]AWS Fargate プラットフォームバージョン1.4でできるようになったこと | DevelopersIO

AWS Fargate のプラットフォームバージョン 1.4.0 をリリース | Amazon Web Services ブログ

終わりに

超小ネタですが、せっかくハマったので書いてみました。それではこの辺で。ちゃだいん(@chazuke4649)でした。