AWS CloudFormationとAmazon ECS/AWS FargateのBlue/Greenデプロイについて

# What's？

> 2022年3月29日時点の情報で記載しています

Amazon ECS/AWS Fargateのデプロイ方法は、以下の2種類の方法から選ぶことができます。

- [ローリング更新](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-ecs.html)
- [CodeDeploy による Blue/Green デプロイ](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html)

実際のデプロイ時にはAWS CodePipelineのアクション内に組み込んで使いたくなるのかな、と思うのですが、そのような構成をAWS CloudFormationで構築することはできません。

> カスタムリソースを使う場合を除く

この情報を、少しまとめておきたいな、と。

AWS FargateはAmazon ECSに含まれる話だろう、とは思いますが、AWS Fargateの情報として参照することも考えて今回は「Amazon ECS/AWS Fargate」という表記で記載することにします。

# AWS CloudFormationとAmazon ECS/AWS FargateとBlue/Greenデプロイ

最初に記載したBlue/Greenデプロイのページは、Amazon ECSのドキュメントでした。

他にも、AWS CodeDeployやAWS CodePipelineにも説明があります。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorial-ecs-deployment.html

なのですが、ここでAWS CloudFormationを持ち出すと、ちょっと話が変わってきます。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/blue-green.html

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployments-create-ecs-cfn.html

AWS CodeDeployのドキュメントの記載内容を見ると、AWS CodeDeploy管理によるBlue/GreenデプロイとAWS CloudFormationによるBlue/Greenデプロイには違いがあることが書かれています。

> このトピックでは、CodeDeploy によって管理される Amazon ECS ブルー/グリーンデプロイと、によって管理されるデプロイの違いについて説明します。AWS CloudFormation。

両方ともAWS CodeDeployは使うことになるので、ややこしいなという気はしますが…。

AWS CloudFormationを使ったBlue/Greenデプロイは、端的には以下の1文が特徴を表していると思います。

> 次の ECS リソースの置き換えが必要なプロパティを更新するスタック更新を実行すると、CloudFormation はグリーンデプロイを開始します。
> 
> - AWS::ECS::TaskDefinition
> - AWS::ECS::TaskSet 

[AWS CloudFormation を使用して CodeDeploy を通じて ECS ブルー/グリーンデプロイを実行する / グリーンデプロイをトリガーするリソースの更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/blue-green.html#blue-green-resources)

つまり、AWS CodeDeploy単体で動かしたり、AWS CodePipelineを使ったパイプラインに組み込んで使うものというより、「AWS CloudFormationでAmazon ECS/AWS Fargateのリソース更新を行う際の仕組みとして、Blue/Greenデプロイが行われるもの」に見えますね。

Amazon ECSクラスターや、関連するALB等のリソースもまるっとテンプレートに含める必要があります。

> CloudFormation を通じて CodeDeploy を使用して ECS ブルー/グリーンデプロイを実行するには、テンプレートに Amazon ECS サービスとロードバランサーなど、デプロイをモデル化するリソースを含める必要があります。

[AWS CloudFormation を使用して CodeDeploy を通じて ECS ブルー/グリーンデプロイを実行する / CloudFormation リソースを使用したブルー/グリーンデプロイのモデリング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/blue-green.html#blue-green-required)

また、AWS CodeDeploy管理のBlue/Greenデプロイとは違う考慮事項が存在します。

[AWS CloudFormation を使用して CodeDeploy を通じて ECS ブルー/グリーンデプロイを実行する / CloudFormation を使用して ECS ブルー/グリーンデプロイメントを管理する際の考慮事項](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/blue-green.html#blue-green-considerations)

そもそも、AWS CodeDeployを使った時に出てくるような`appspec.yml`も`imageDetail.json`も説明に現れませんからね。

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorial-ecs-create-appspec-file.html

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/file-reference.html

というわけで、「（AWS CodePipelineのような）デプロイパイプラインに組み込んで、AWS CodeDeployでBlue/Greenデプロイ」といったものとはだいぶ性格が違いそうです。

> 組み込むなら、AWS CloudFormationによるリソース更新、という表現が適切でしょう

ちなみに、このデプロイ方法は大阪リージョンでは使用できないようです。

> による Amazon ECS ブルー/グリーンデプロイの管理AWS CloudFormationは、アジアパシフィック (大阪) リージョンでは使用できません。

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployments-create-ecs-cfn.html

# AWS CloudFormation × AWS CodeDeploy

AWS CloudFormationドキュメントから、AWS CodeDeployでのリソース定義について情報を追っておきます。

AWS CloudFormationの`AWS::CodeDeploy::DeploymentGroup LoadBalancerInfo`プロパティのページに以下のように書かれており、Blue/GreenデプロイはAWS Lambdaのみのサポートとなっていることが明記されています。

> AWS CloudFormation supports blue/green deployments on the AWS Lambda compute platform only.

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codedeploy-deploymentgroup-loadbalancerinfo.html

このページ内にある`TargetGroupInfoList`の説明をよくよく見ると、以下のように書かれておりターゲットグループのリストに指定できる要素はひとつであることが書かれています。

> Adding more than one target group to the array is not supported. 

ここが制限になっているのではないかな、と思うのですが、どうでしょう…。

# カスタムリソースを使う方法

では、AWS CloudFormationではどうにもならないかというと、カスタムリソース（AWS Lambda）を使ってAWS CodeDeployのAPIを直接操作すれば、できないことはないです。

以下がその記事ですね。

https://dev.classmethod.jp/articles/cloudformation-with-custom-resource-for-fargate-blue-green-deployment/

こういう方法を取るか、AWS CLIやマネージメントコンソールで作成するか、といったところでしょうか…。