CodePipeline で CodeCommit/CodeBuild/CodeDeploy を繋げてデリバリプロセスを自動化してみた #reinvent
こんにちは、藤本です。
AWS re:Invent 2016 で CodeBuild がリリースされました。CodePipeline のビルドプロセスに CodeBuild を置くことができるようになりました。
CodeBuild に関しては以下の記事をご参照ください。
【速報】フルマネージドのビルドサービスCodeBuild爆誕 #reinvent
今回は CodeCommit、CodeBuild、CodeDeploy を CodePipeline で繋げて、デリバリプロセスの自動化を試してみました。
概要
昨今のシステム開発はユーザーの要望をより早く、より多く取り入れることを要求され、リリース頻度が増えてきたことに伴い、デリバリプロセスの自動化がデファクトスタンダードとなってきました。デリバリプロセスにはソースコード管理、ビルド、テスト、デプロイという 4つ主なフェーズがあります。下記は AWS Summit Tokyo 2016 のブレイクアウトセッションの DevOps on AWS: Deep Dive on Continuous Delivery and the AWS Developer Tools のスライドにある 1ページです。
AWS では Developer Tools というサービスのカテゴリで CodeCommit によるソースコード管理、CodeBuild によるコンパイル、ユニットテスト、CodeDeploy によるデプロイができ、それぞれのフェーズを CodePipeline で接続することができ、デリバリプロセスを自動化するサービス群を提供しています。
まだインテグレーションテストや、UI テストは外部サービスを利用することになるかと思います。
試してみた
今回は Django の Webアプリケーションを AWS の Developers Tools を利用して、EC2 インスタンスへデプロイすることを試してみました。
デリバリの流れとしては以下のようになります。
ポイントとしては以下になります。
- CodeCommit リポジトリへのプッシュをトリガとしたデリバリプロセスの開始
- CodeBuild によるユニットテスト
- ユニットテストの結果によるリリース判断(ユニットテストがNGの場合は中断)
- CodeDeploy によるサーバ群に対するデプロイ
目次
- Step 1 : ソースコードの準備
- Step 2 : CodeCommit のリポジトリ作成
- Step 3 : CodeBuild のビルドプロジェクト作成
- Step 4 : CodeDeploy のアプリケーション作成
- Step 5 : CodePipeline のパイプライン作成
- Step 6 : CodeBuild の設定ファイル作成
- Step 7 : CodeDeploy の設定ファイル作成
- Step 8 : 動作確認(ソースコードのプッシュ)
- Step 9 : 動作確認(テストによるエラー発生時)
環境
- AWSリージョン : us-east-1 (東京リージョンは未リリース)
- Web サーバ
- OS : Amazon Linux 2016.09
- Web : Apache httpd(Django と WSGI による連携)
- Application : Django
Step 1 : ソースコードの準備
Django のアプリケーションを適当に生成。ソースコードは Github にアップしました。
Step 2 : CodeCommit のリポジトリ作成
CodeCommit のリポジトリ作成は下記記事をご参照ください。
Step 3 : CodeBuild のビルドプロジェクト作成
CodeBuild のビルドプロジェクト作成は下記記事をご参照ください。
Step 4 : CodeDeploy のアプリケーション作成
CodeDeploy のアプリケーション作成は下記記事をご参照ください。
Step 5 : CodePipeline のパイプライン作成
CodePipeline のパイプラインを作成し、Step : 2 〜 4 の CodeCommit -> CodeBuild -> CodeDeploy を繋げます。
CodePipeline のページから「Get Started」で作成を開始します。
Name
任意のプロジェクト名を入力します。
Source
利用するソースリポジトリを設定します。
項目 | 説明 |
---|---|
Source provider | 今回は CodeCommit を利用するため、CodeCommit を選択 |
Repository name | Step 2 で作成した CodeCommit のリポジトリ名を選択 |
Branch name | 今回は master ブランチをリリース対象とするため、master を選択 master ブランチにプッシュしたら、パイプラインを起動する |
Build
利用するビルドツールを設定します。
項目 | 説明 |
---|---|
Build provider | 今回は CodeBuild を利用するため、CodeBuild を選択 |
Configure your project | Step 3 でビルドプロジェクトを作成済みのため、 Select an existing build project を選択 |
Project name | Step 3 で作成した CodeBuild のプロジェクト名を選択 |
Beta(デプロイ)
利用するデプロイツールを設定します。
項目 | 説明 |
---|---|
Deployment provider | 今回は CodeDeplooy を利用するため、CodeDeploy を選択 |
Application name | Step 4 で作成した CodeDeploy のアプリケーション名を選択 |
Deployment group | 同上のデプロイメントグループ名を選択 |
Service Role
CodePipeline が利用する IAM Role を設定します。
「Create role」から IAM Role を作成します。
Policy は自動生成してくれます。そのまま作成します。
作成した Role が自動で入力されます。
Review
設定内容を確認し、作成を開始します。
以上でパイプラインの作成が開始されます。
作成が完了すると、自動でパイプラインが起動します。
またデフォルトでは CodeDeploy は CodeBuild のアウトプットアーティファクトを利用します。今回、Django アプリケーションはビルドの必要がないため、CodeBuild でアウトプットアーティファクトを生成しません。CodeCommit のアーティファクトを CodeDeploy によってそのままデプロイします。その設定変更が必要です。
CodePipeline の Edit から設定変更します。Source の Output artifacts #1 の名前を事前に確認します。デフォルトの名前は MyApp です。
次に Beta を修正します。Input artifacts #1 に確認した名前(MyApp)を入力します。
Save pipeline changes で設定を保存します。
Step 6 : CodeBuild の設定ファイル作成
CodeBuild の動作を定義する設定ファイルを作成します。CodeBuild の設定ファイルの内容は下記記事をご参照ください。
今回は CodeBuild で実施したいことはユニットテスト、必要なファイルのみを抽出するためのパッケージングです。
buildspec.yml
version: 0.1 phases: install: commands: - pip install -r requirements.txt build: commands: - python project/manage.py test app.tests
項目 | 説明 |
---|---|
install | ユニットテスト時に依存するライブラリのインストール |
pre_build | Django のテスト機能を利用したユニットテスト |
build | デプロイしたいファイルの抽出、およびパッケージング |
Step 7 : CodeDeploy の設定ファイル作成
CodeDeploy のデプロイ動作を定義する設定ファイルを作成します。CodeDeploy の設定ファイルの内容は下記記事をご参照ください。
今回、CodeDeploy で実施したいことは依存ライブラリのインストール、DocumentRoot へのパッケージの展開、および展開後の Apache の再起動です。
appspec.yml
version: 0.0 os: linux files: - source: project destination: /var/lib/project - source: requirements.txt destination: /tmp permissions: - object: /var/lib/project owner: apache group: apache hooks: AfterInstall: - location: scripts/after_install.sh timeout: 60 runas: root ApplicationStart: - location: scripts/application_start.sh timeout: 10 runas: root
以上で準備は完了です。今までは色々なサービス、ツールを利用している時は Github、Jenkins、Travis CI など色々なところにログインして設定が必要だったのが AWS だけで完結できるのは嬉しいですね。
Step 8 : 動作確認(ソースコードのプッシュ)
それでは、ソースコードをプッシュして、動作確認してみましょう。
$ git remote -v origin https://git-codecommit.us-east-1.amazonaws.com/v1/repos/django-fujimoto (fetch) origin https://git-codecommit.us-east-1.amazonaws.com/v1/repos/django-fujimoto (push) $ git commit -m "django test" [master 3ac8d5f] django test 1 file changed, 1 insertion(+) $ git push origin master Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 307 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/django-fujimoto 829122a..3ac8d5f master -> master
パイプラインを見てみましょう。
まず、Source がIn Progress
となり、CodeCommit リポジトリから S3 バケットへのソースアーティファクトの格納(デリバリの流れの図の②)を開始します。
しばらくすると、Source がSuccess
となり、Build がIn Progress
となり、ソースアーティファクトのユニットテスト(デリバリの流れの図の④、⑤)を開始します。
②が完了すると、CodePipeline用に作成された S3 バケットにアーティファクトがアップロードされます。
しばらくすると、Build がSuccess
となり、Beta がIn Progress
となり、ソースアーティファクトの EC2インスタンスへのデプロイ(デリバリの流れの図の⑧、⑨)を開始します。
CodeBuild のビルドヒストリーから各フェーズのビルド処理のステータス、および標準出力を確認することができます。
しばらくすると、Beta がSuccess
となり、プッシュしたソースコードが EC2インスタンスへデプロイされます。
ELB へアクセスし、HTTP レスポンスが返ってくるか確認してみましょう。
$ curl http://lb-000000000.us-east-1.elb.amazonaws.com/app/health {"status": "ok"}
レスポンスが正常に返ってきました。
Step 9 : 動作確認(テストによるエラー発生時)
次に、ユニットテストがエラーになるようにテストコードを書き換え、リポジトリへプッシュします。
$ git diff diff --git a/project/app/tests.py b/project/app/tests.py index 6617de1..47b5ff0 100644 --- a/project/app/tests.py +++ b/project/app/tests.py @@ -9,4 +9,4 @@ class ViewsTest(TestCase): def test_health(self): response = self.client.get(reverse('app:health')) self.assertEqual(response.status_code, 200) - self.assertEqual(response.json()['status'], 'ok') + self.assertEqual(response.json()['status'], 'ng') $ git commit -am "edit test code ng status" [master 49073b6] edit test code ng status 1 file changed, 1 insertion(+), 1 deletion(-) $ git push origin master Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 434 bytes | 0 bytes/s, done. Total 5 (delta 4), reused 0 (delta 0) remote: To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/django-fujimoto 868be36..49073b6 master -> master
しばらくして見ると、Build がFailed
になっていることを確認できます。また Beta(デプロイ)は最終実行時間が 2時間前なので、デプロイが実行されていないことがわかります。
まとめ
いかがでしたでしょうか?
AWS の各種サービスとのインテグレーションはさすがで、AWS 利用者であれば、お馴染みの UI でデリバリの自動化ができるのは嬉しいですね。ただ、CodeCommit vs Github、CodeBuild vs Travis CIや、Circle CIを比べた時に機能的に AWS のサービスには物足りなさを感じます。今後の機能追加に期待したいです。