CodeDeploy の Blue/Green デプロイを利用して、CodePipeline でいい感じに自動化されたデリバリを実装する
こんにちは、藤本です。
ちょっと前から、AWS の Code◯◯ をベースにデリバリの自動化を勉強しています。
今回は今までブログエントリしてきたデリバリ方法に、先日リリースされた CodeDeploy の Blue/Green デプロイを組み合わせた実装を試すとともに、リリースプロセスを今一度整理してみました。
今までのエントリは下記をご参照ください。
- CodePipeline で CodeCommit/CodeBuild/CodeDeploy を繋げてデリバリプロセスを自動化してみた #reinvent
- CodePipeline で承認プロセスを設けて本番環境へリリースする #reinvent
CodeDeploy の Blue/Green デプロイは下記をご参照ください。
復習
現在、AWS の Developer Tools のカテゴリに、ソースコードリポジトリの CodeCommit、ビルドサービスの CodeBuild、デプロイ自動化サービスの CodeDeploy、デリバリの一連のプロセスを繋げて自動化する CodePipeline があります。ちなみに CodeCommit の代わりに Github を利用することもできます(Github を利用している方は CodeCommit に移行する必要はありません)
これらを組み合わせることでソースコードリポジトリへのプッシュをトリガーに、ビルド、ユニットテスト、デプロイまでを自動化し、リリースプロセスのトラッキングを行うことができます。
ただこれはあくまで単純なデリバリであり、多くのシステムにおいて、リリースプロセスはこれだけではありません。Webシステムであれば UI チェック、システムの 1コンポーネントであれば他コンポーネントとのインテグレーションテスト、大規模な修正であれば、ペネトレーションテスト、パフォーマンステストが必要となるかと思います。
そこで CodePipeline の承認プロセスを設けることで、一つのリリースパイプラインでありながら、ステージング環境での各種テストを実行することができるようになりました。
ただこれだけでも満足がいくものではありません。リリースにおいて、バグ内在は付きものです。バグが発覚したら、より早く切り戻す必要があります。より早く切り戻すにはインプレイスデプロイよりも Blue/Green デプロイです。先日以前は CodeDeploy はインプレイスデプロイしか対応していなかったため、CodePipeline + CodeDeploy を利用する時は、Blue/Green デプロイすることができませんでした。(どうにか Blue/Green デプロイしたくて CodePipeline の間に Lambda 挟んで Route 53 書き換え、CodePipeline の変更など頑張りましたが、うまく行かなかった。。。)
今回お伝えすること
それが先日の CodeDeploy の Blue/Green デプロイ対応で CodePipeline + CodeDeploy でも簡単に Blue/Green デプロイを実現できるようにしました!!(EB で言う URL swap、Route 53 書き換えの対応が待たれる!)そして、いい感じにデリバリを自動化できるようになりました。
自動化されたデリバリフローの整理
- リリースするソースコードをソースコードリポジトリへプッシュ(特定のブランチに限定可)
- (自動)ソースコードが S3 に zip 化されて配置
- (自動)CodeBuild がユニットテスト、ビルドしたパッケージを再度 zip 化して、S3 に配置
- (自動)パッケージをステージングインスタンスにデプロイ
- ステージング環境にデプロイされたアプリケーションを自動化できないテストを手動で実施
- リリース判定により、
6-a. リリースできると判断した場合、承認(リリースプロセスの継続、7.へ)
6-b. バグが見つかったなどリリースできないと判断した場合、中止 - (自動)Green 環境のデプロイ
- (自動)ELB へ Green 環境追加・Blue 環境削除 による切り替え
- (自動)任意のタイミングで Blue 環境の削除
実質、ほとんどのリリースプロセスが自動化されていて、切り戻しも簡単にできます!
やってみた
前回の実装から CodeDeploy の Blue/Green デプロイ化を(こっそり AutoScaling 化も)実施しています。
CodeDeploy の設定変更
CodeDeploy のインプレイスデプロイから Blue/Green デプロイへの設定変更は設定画面から簡単に切り替えられます。CodeDeploy のアプリケーション設定画面から変更したいデプロイメントグループを選択し、[Actions] -> [Edit] を選択します。今回は prd(本番環境)を変更します。
Deployment type を In-place Deployment から Blue/green Deployment に変更します。
設定変更はこれだけです。
動作確認
Django で作った Web API アプリケーションをデプロイしています。ソースコード変更して、リリースプロセスの動作を確認します。
事前確認
「今回お伝えすること」の章で貼ったものと同じ構成です。ステージング、プロダクション分かれていて、それぞれ ELB をエンドポイントとしています。ヘルスチェック URL を叩くと JSON が返ってきます。
$ curl stg-clb-769141208.us-east-1.elb.amazonaws.com/app/health {"status": "ok", "instance_id": "i-09dc2fe1d5ae9608d", "version": "blue"} $ curl prd-clb-866491571.us-east-1.elb.amazonaws.com/app/health {"status": "ok", "instance_id": "i-081048996730c9a9e", "version": "blue"}
1. リリースするソースコードをソースコードリポジトリへプッシュ(特定のブランチに限定可)
今回はソースコードの変更として、version を blue から green に変更します。
$ sed -ie 's/blue/green/' project/app/views.py $ git diff diff --git a/project/app/views.py b/project/app/views.py index 446f32b..68caa61 100644 --- a/project/app/views.py +++ b/project/app/views.py @@ -14,6 +14,6 @@ def health(request): instance_id = 'not found' return HttpResponse(json.dumps({ 'status': 'ok', - 'version': 'blue', + 'version': 'green', 'instance_id': instance_id, }), content_type="application/json") $ git commit -am "green deploy" [master 0af4bf4] green deploy 1 file changed, 1 insertion(+), 1 deletion(-) $ git push origin master Counting objects: 9, done. Delta compression using up to 4 threads. Compressing objects: 100% (9/9), done. Writing objects: 100% (9/9), 799 bytes | 0 bytes/s, done. Total 9 (delta 7), reused 0 (delta 0) To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/django-fujimoto aabcc59..527ecb1 master -> master
2. ソースコードが S3 に zip 化されて配置
ソースコードリポジトリ(今回は CodeCommit)への master ブランチのプッシュをトリガーに CodePipeline のデリバリプロセスが開始します。まずはソースコードをクローンして、S3 にアップロードします。
3. CodeBuild がユニットテスト、ビルドしたパッケージを再度 zip 化して、S3 に配置
続いて、CodeBuild を起動し、ビルドプロセスが開始します。今回は Django アプリケーションで特にビルドはしていないので、ユニットテストのみが実行されます。
ユニットテストに NG がある場合、ビルドプロセスが NG となり、デリバリプロセスは中断されます。詳しくはこちらをご参照ください。
4. パッケージをステージングインスタンスにデプロイ
ビルドが完了するとステージング環境へのデプロイが開始されます。
ステージング環境へのデプロイが完了すると、承認待ちとなり、デリバリプロセスは停止します。
5. ステージング環境にデプロイされたアプリケーションを自動化できないテストを手動で実施
それではこの状態でステージング、本番それぞれにアクセスして、デプロイ状況を確認してみます。
$ curl stg-clb-769141208.us-east-1.elb.amazonaws.com/app/health {"status": "ok", "instance_id": "i-09dc2fe1d5ae9608d", "version": "green"} $ curl prd-clb-866491571.us-east-1.elb.amazonaws.com/app/health {"status": "ok", "instance_id": "i-081048996730c9a9e", "version": "blue"}
ステージング環境の version が green を返すようになりました。正常にデプロイが実行されています。当たり前ですが、本番環境は blue のままです。
6. リリース承認
ステージング環境の動作確認に問題がないようであれば、本番環境へデプロイします。CodePipeline の画面から承認します。「Review」ボタンをクリックします。コメントを入力し、「Approval」ボタンをクリックします。
7. Green 環境のデプロイ
承認すると、本番環境へのデプロイが開始されます。
8. ELB へ Green 環境追加・Blue 環境削除 による切り替え
「Details」リンクをクリックすると CodeDeploy の画面に遷移し、デプロイ状況を眺めることができます。
デプロイが完了するのを待ちます。
デプロイが完了しました。1時間は Blue 環境を保持する設定にしていますので、この時点では CodePipeline は完了にはなりません。
本番環境の動作確認
それでは本番環境にアクセスして、デプロイ状況を確認してみます。
$ curl prd-clb-866491571.us-east-1.elb.amazonaws.com/app/health {"status": "ok", "instance_id": "i-08baaba854fa5917a", "version": "green"}
本番環境も version が green を返すようになりました。更にインスタンス ID も変わっていて、別インスタンス(Green面)がデプロイされていることがわかります。
9. 任意のタイミングで Blue 環境の削除
1時間経過後に確認してみます。
CodePipeline のリリースが完了しています。
まとめ
いかがでしたでしょうか?
待望の CodeDeploy の Blue/Green デプロイ対応によって、ようやく安心して CodePipeline を活用できるようになったのではないでしょうか。CodePipeline は昨年12月に東京リージョンで利用可能になりました。ぜひ、利用してみてはいかがでしょうか。