この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、藤本です。
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 のサービスには物足りなさを感じます。今後の機能追加に期待したいです。