ECSのBlue/Green(カナリアリリース)がCloudFormationでサポートされました!

2020.05.20

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

こんにちは、コンサル部のもこ@札幌オフィスです。

本日、ECSのBlue/Greenデプロイ(カナリアリリース)がCloudFormationでサポートされたので、早速CloudFormationでECSのBlue/Green、カナリアリリースをやってみました!

ECS環境のBlue/Green(カナリアリリース)の仕組み

そもそもECS環境に対してどのようにBlue/Green(カナリアリリース)を行われるのかをおさらいしておきましょう。

時は遡って昨年、ALBでターゲットグループがサポートされました。

[激アツアップデート]ALBだけでカナリアリリース(重み付け)ができるようになりました!

上記の機能を利用したデプロイを自動化した物がCodeDeployで今年2月にリリースされていて、CodePipelineやコマンドなどから実行することで利用することが出来ていました。

ECSでCodeDeployを使った線形デプロイとCanaryデプロイを試してみた

今回のアップデートはCloudFormationで実行出来ることになり、ECSサービスのアップデートをCloudFormationを利用して実行している場合に利用することが出来ます。

やってみる

早速どんな感じに動くのかを検証していきます。

公式ドキュメントのCloudFormation(YAML)テンプレートを実行してみます。

Perform ECS blue/green deployments through CodeDeploy using AWS CloudFormation

スタックのパラメータはデフォルトのVPCとサブネットを指定しました。

作成されたALBのエンドポイントにアクセスすると、このような画面が出てきます。

Blue/Green(カナリアリリース)をしてみる

それでは早速Blue/Green(カナリアリリース)でコンテナをアップデートしてみます。

AWS::ECS::TaskDefinition または AWS::ECS::TaskSet の更新があった場合にCodeDeployが走るそうなので、適当にイメージを更新してみます。

BlueTaskDefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
ExecutionRoleArn: !Ref ECSTaskExecutionRole
ContainerDefinitions:
- Name: DemoApp
Image: 'nginx:mainline-alpine' # 'nginxdemos/hello:latest' から書き換え
Essential: true
PortMappings:
- HostPort: 80
Protocol: tcp
ContainerPort: 80
RequiresCompatibilities:
- FARGATE
NetworkMode: awsvpc
Cpu: '256'
Memory: '512'
Family: ecs-demo

CodeDeployの設定は Transformで AWS::CodeDeploy::BlueGreen を呼び出した上で、Hookブロックに設定を書いていく形になります。

TrafficRoutingConfig でデプロイの種類を指定することができ、AllAtOnce、TimeBasedCanary、TimeBasedLinearが対応していて、それぞれの特徴は下記の通りです。

  • AllAtOnce: 名前の通り一気にアップデート
  • TimeBasedCanary: 2段階に分けてアップデート、 最初に30%のトラフィックを新しい環境に流して、5分後に残りの70%を新しい環境に流してデプロイを終了するようなイメージ
  • TimeBasedLinear: 指定したパーセントと時間ごとにアップデート、20%を5分ごとに新しい環境にアップデートするイメージ

※ 詳細なパラメーターについては公式ドキュメントを参照してください。

今回はTimeBasedLinearを利用して、1分おきに20%ずつ新しい環境にトラフィックを流してみます。

Transform:
- 'AWS::CodeDeployBlueGreen'
Hooks:
CodeDeployBlueGreenHook:
Properties:
TrafficRoutingConfig:
Type: TimeBasedLinear
TimeBasedLinear:
StepPercentage: 20 # 20%ずつ
BakeTimeMins: 1 # 1分おきに
Applications:
- Target:
Type: 'AWS::ECS::Service'
LogicalID: ECSDemoService
ECSAttributes:
TaskDefinitions:
- BlueTaskDefinition
- GreenTaskDefinition
TaskSets:
- BlueTaskSet
- GreenTaskSet
TrafficRouting:
ProdTrafficRoute:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
LogicalID: ALBListenerProdTraffic
TargetGroups:
- ALBTargetGroupBlue
- ALBTargetGroupGreen
Type: 'AWS::CodeDeploy::BlueGreen'

この状態でCloudFormationをアップデートすると、CodeDeployが実行され、コンテナの実行、Hooksで設定した項目に沿ってリリースが始まります。

デプロイ中のALBのルール設定画面はこんな感じで、20%ずつ変更されている事を確認でき、ブラウザでF5連打してもだいたい2割くらいの確率で新しいコンテナにルーティングされている事を確認出来ます。

2分後には追加で20%新しい環境に流れていることを確認出来ます!

まとめ

CloudFormationを利用したECSのBlue/Greenが対応したことにより、CloudFormationでECSのサービスに対してBlue/Green、カナリアリリースを出来るようになりました。

なお、2020/05/20時点ではまだAWS CDKで対応していませんが、GitHubのIssueでは活発に議論されていて、CloudFormationでのBlue/Green対応待ちの状態が続いていましたが、今回のアップデートでCDKは近いうちに実装され、リリースされると見て良いでしょう。

https://github.com/aws/aws-cdk/issues/1559

参考