CloudFormation による ECS の Blue/Green デプロイを CodePipeline から実行する
今年5月にAWS CloudFormation による Amazon ECS のブルー/グリーンデプロイがサポートされた。 これの AWS CodePipeline からの実行を試した。
サンプルコードはこちら。
仕組み
ECS ではローリング更新と Blue/Green デプロイの2種のデプロイ方式がサポートされている。 (Blue/Greenデプロイについての説明はここでは割愛する。)
ECS の Blue/Green デプロイにおいては AWS CodeDeploy が新旧のコンテナ間のトラフィックをコントロールするのだが、 以下のセクションを CloudFormation のテンプレートに追加することで、 変更セット実行時に内部的に AWS CodeDeploy を起動し、Blue/Green デプロイを実行してくれる。
- AWS::CodeDeployBlueGreen 変換を呼び出す Transform セクション
- AWS::CodeDeploy::BlueGreen フックを呼び出す Hooks セクション
- Blue/Green デプロイをトリガーする ECS リソース
冒頭のサンプルコードから Transform セクションと Hooks セクションを抜粋したものが以下。
Transform:- 'AWS::CodeDeployBlueGreen'Hooks:CodeDeployBlueGreenHook:Properties:TrafficRoutingConfig:Type: TimeBasedCanaryTimeBasedCanary:StepPercentage: 15BakeTimeMins: 5Applications:- Target:Type: 'AWS::ECS::Service'LogicalID: ECSDemoServiceECSAttributes:TaskDefinitions:- BlueTaskDefinition- GreenTaskDefinitionTaskSets:- BlueTaskSet- GreenTaskSetTrafficRouting:ProdTrafficRoute:Type: 'AWS::ElasticLoadBalancingV2::Listener'LogicalID: ALBListenerProdTrafficTargetGroups:- ALBTargetGroupBlue- ALBTargetGroupGreenType: 'AWS::CodeDeploy::BlueGreen'
注意点として、 CloudFormation を使用して ECS の Blue/Green デプロイを実行する場合、 いくつかの考慮事項がある。
例えば、上記の Hooks セクションを見ると Blue と Green の2つの ECS タスクや、トラッフィックを捌くロードバランサのリスナーが含まれているように、 1つのテンプレートにこれらのリソースをすべて含めなければならない。
その他にも、クロススタック参照が使えないなどの項目があるため、 採用時はそれらを許容できるかどうか確認する必要がある。
やってみた
以下のように AWS CodePipeline 上で変更セットを作成、実行することで ECS の Blue/Green デプロイを実行した。
Pipeline:Type: AWS::CodePipeline::PipelineProperties:ArtifactStore:Type: S3Location: !Ref ArtifactStoreName: !Ref 'AWS::StackName'RoleArn: !Ref CodePipelineServiceRoleArnStages:- Name: SourceActions:- Name: SourceActionTypeId:Category: SourceOwner: AWSVersion: '1'Provider: CodeCommitOutputArtifacts:- Name: sourceConfiguration:RepositoryName: !Ref RepositoryNameBranchName: masterRunOrder: 1- Name: BuildActions:- Name: BuildInputArtifacts:- Name: sourceActionTypeId:Category: BuildOwner: AWSVersion: "1"Provider: CodeBuildConfiguration:ProjectName: !Ref BuildProjectOutputArtifacts:- Name: buildRunOrder: 1- Name: CreateChangeSetActions:- Name: CreateChangeSetInputArtifacts:- Name: buildActionTypeId:Category: DeployOwner: AWSVersion: '1'Provider: CloudFormationConfiguration:ActionMode: CHANGE_SET_REPLACEStackName: !Ref EcsStackNameCapabilities: CAPABILITY_AUTO_EXPAND,CAPABILITY_IAMChangeSetName: updateRoleArn: !Ref CloudFormationServiceRoleArnTemplatePath: 'build::cloudformation/ecs.yml'TemplateConfiguration: 'build::cloudformation/stack-config.json'- Name: ExecuteChangeSetActions:- Name: ExecuteChangeSetInputArtifacts:- Name: buildActionTypeId:Category: DeployOwner: AWSVersion: '1'Provider: CloudFormationConfiguration:ActionMode: CHANGE_SET_EXECUTEStackName: !Ref EcsStackNameCapabilities: CAPABILITY_AUTO_EXPAND,CAPABILITY_IAMChangeSetName: updateRunOrder: 1
Dockerイメージを適当に更新して上記のパイプラインを起動すると、 以下の通り CodeDeploy による Blue/Green デプロイが実行された。
CodeDeploy によるトラフィック移行の様子。
感想
技術調査の過程で、これまでの CloudFormation を使わない ECS Blue/Green デプロイも試してみたのだけれど、 ECS Blue\Green デプロイ用の CodeDeploy リソースの CloudFormation による作成がサポートされていなかったり、 ECS 周りのリソース更新が CloudFormation 外で行われるため IaC がやりづらかったり、 やや使いづらい印象を受けた。
一方で今回サポートされた機能では、 ECS の作成から更新まですべてを CloudFormation 上で完結できるのが嬉しい。 考慮事項が許容できるか次第だが、プロダクション環境でも1選択肢として前向きに検討したい。