CodeDeployでBlue/Green方式を構成するためのパイプライン設計

1. はじめに

昨今、CI/CDやDevOpsを適用するために、開発フェーズやオペレーションフェーズにてパイプラインを使用する機会が増えてきました。

かつては、テストの自動化や、サーバ構築の自動化など、イチ要素だけの自動化に焦点があたっていました。ただ、ビジネスを加速化するためには、開発〜デプロイ〜オペレーションまでを含めた"プロセスの自動化"が必要になっており、そこでパイプラインが注目を浴びています。

AWSでは、パイプラインなどDevOpsにおける様々な自動化を実現するツールが、開発者用ツールとして用意されています。 例えば、AWS CodePipelineでパイプラインを定義し、そのなかで、AWS CodeCommitによるソース管理、AWS CodeBuildによるテスト&ビルド、AWS CodeDeployによるアプリケーションデプロイを実行することができます。

 

図1. 典型的なパイプライン構成とAWSサービスによる適用例

 

本稿では、CloudFormation 化した CodeDeploy で Blue/Green デプロイメントを構成するためのパイプライン設計についてお話します。

 

2. 前提条件 - アプリケーション/インフラ

 まず、今回使用する構成について解説します。

アプリケーションはNode.js + Expressで構築し、インフラリソースとしてVPC内に複数のAmazon EC2とElastic Load Balancer、Amazon RDSを使用しています。

インフラリソース部分はCloudFormationでコード化し、アプリケーションのコードと同じソースコードリポジトリに保存しています。

 

図2. アプリケーション/インフラ構成

 

3. 前提 - パイプライン関連

アプリケーション/インフラリソースのリポジトリ更新時に、ビルド、テスト、デプロイを自動化するためパイプラインを構築しています。

ここでは、CodeDeploy と CodeBuild を CodePipelineでパイプライン化しています。

なお、このパイプライン関連のサービスも CloudFormation でコード化しています。

 

図3. パイプラインのCloudFormation化

 

コード化をすることで、属人性の排除、ソースコードによるバージョニングなど、アプリケーションコードと同様のメリットが享受できます。

 

4. CodeDeploy のBlue/Greenデプロイメント

ここで簡単にCodeDeployについて解説します。

CodeDeployとはアプリケーションのデプロイ管理を行うツールで、EC2インスタンス、オンプレミスサーバ、Lambdaをデプロイ先として指定が可能です。

アプリケーションの更新というと、ダウンタイム回避という厄介なオペレーションが付き物ですが、CodeDeploy がサポートする Blue/Green デプロイメントを利用することで、新サーバのプロビジョニング〜LoadBalancerの紐づけまで、CodeDeploy に任せることが可能です。

 

 

図4. CodeDeploy - Blue/Green Deployment

 

 

5. 問題点 - CFnによるCodeDeploy実装

 CodeDeploy による Blue/Green デプロイメントは、ダウンタイムを最小化できる強力な設定ですが、ひとつだけ問題に突き当たりました。

2018年4月現在、CloudFormation では CodeBuild のデプロイメントに Blue/Green 方式を指定することはできません。

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

そこで、CloudFormation による CodeDeploy 定義と、Blue/Green デプロイメントを両立するために、Lambda による設定変更をパイプライン内に追加することでワークアラウンドとしました。

 

6. 設計のキモ - Lambda ワークアラウンド

 

CloudFormation では In-Place 方式しかサポートしていませんが、各種 API なら Blue/Green 方式をサポートしています。

そこで、パイプラインの中に Lambda のアクションを追加し、CodeDeploy が実行される前に デプロイ方式を Blue/Green 方式に変更するようにします。

 

図5. Lambda によるワークアラウンド

 

今回は、Lambda の Python3.7 を使用し、以下のように DeploymentGroup を修正する Python スクリプトを作成しました。

ここではまず、Deployment タイプをチェックし、もし IN_PLACE 方式だったら Blue/Green 方式に変更しています。二度目以降のパイプライン実行時では、Blue/Green 方式に変更済みのため、何も変更することなく Lambda は終了します。

```python

if(checkDeploymentType(CDAppName, CDGroupName) == 'IN_PLACE'):

  response = changeDeploymentTypeBG(CDAppName, CDGroupName, lookForASG(tagfilter = ASGFilters) , LBTargetGroup)

  print(response)

  code_pipeline.put_job_success_result(jobId=job_id)

else:

  print("OK, aborting")

  code_pipeline.put_job_success_result(jobId=job_id)

     (snip)

 def changeDeploymentTypeBG(app, group, asg, lbTargetGroup):

  try:

      response = codedeploy_client.update_deployment_group(

        applicationName = app,

        currentDeploymentGroupName = group,

        autoScalingGroups=[

            asg,

        ],

        deploymentStyle={

            'deploymentType': 'BLUE_GREEN',

            'deploymentOption': 'WITH_TRAFFIC_CONTROL'

        },

        blueGreenDeploymentConfiguration={

     (snip)

```

 

ここでのキモは、

1. CodeDeploy 実行前に Blue/Green 変更を行う
2. 二度目以降のパイプライン実行時でも、同様の結果になるよう Lambda 内でチェックする

となります。

これにより、CodeDeploy は Blue/Green デプロイメント方式でアプリケーションデプロイできるようになりました。下記の画像から成功していることがわかります。

図6. CodeDeploy 結果

 

なお、CodePipeline 上のパイプライン概要は以下のようになっており、Deploy_Production の fixDeploymentGroup アクションが該当の Lambda になっています。

図7. CodePipeline 構成

 

7. まとめ

本稿では、CloudFormation 化した CodeDeploy で Blue/Green デプロイメントを構成するためのパイプライン設計について解説しました。

今回は、CodeDeploy の設定変更に AWS Lambda を利用しましたが、以下のような外部サービスの設定などにも威力を発揮します。

- 外部バックアップサービスの設定変更
- 外部モニタリングサービスの設定変更
- notification

DevOps 向けにパイプラインを作り始めると何かと複雑化してしまいがちですが、AWS Lambda を使えば比較的すっきりと機能を追加できるようになります。

著者プロフィール

著者アイコン
後藤僚哉
伊藤忠テクノソリュージョンズ株式会社在籍中 | 1. 現在の担当業務 : AWS, オープンソースを利用したCI/CD, DevOpsのインプリ
2. これまでの担当業務 : オンプレミス仮想化(VMware/Microsoft)の設計構築 -> OpenStackの開発&設計構築
3. 最近の想い・考えていること: 現在InfraからAppへ脱皮中。

関連記事はこちら