CodeBuild,CodeDeploy,CodePipeline3つ使ってCI/CDの環境構築してみた

Pocket
LINEで送る

先日、Developers Summit 2019 に初めて参加してきました。

広いジャンルのセッションがあって大変勉強になったんですが、
その中でも一際興味を惹かれたのが、このセッションでした。
CI/CDを使い倒して数段上のソフトウェア開発をしよう!

フクロウラボではCircleCIを使っているのですが、「なぜCIを使うのか?」という質問にちゃんと説明ができないなと思っていたのと
what’s CD????聞いたことすらない・・・状態だったので聞いてきました。結果よかった。

簡単にセッション内容をまとめてみました。

CIとは?

継続的インテグレーションのこと(Continuous Integration)
主にプログラマーのアプリケーション作成時の品質改善や納期の短縮のための習慣のこと
狭義にはビルドやテスト、インスペクションなどを継続的に実行していくことを意味する。
(wikipedia)

今回はこの意味で使ってます。
狭義にはビルドやテスト、インスペクションなどを継続的に実行していくことを意味する。

【何ができるの?】
コードの変更時のテスト自動実行
※他にもタスクの自動化が可能
構文チェック
カバレッジ計測
循環的複雑度のチェック
ドキュメントの自動生成

何が嬉しい?

手動でテストを実行した時発生する3つの問題を解決し、テストの信頼性をあげることができる。

・テストがあるけど実行し忘れた

変更の度にテストを回すことで解決

・昔書いたテストが壊れて動かない

毎回回しているのですぐに気づいて修正ができる。

・テスト結果が環境依存

CIを唯一のテスト環境にする
docker等を使って毎回コンテナを構築し、毎回同じテスト環境かつまっさらな状態でテストを実行できる。

便利な機能

可視化

  • ステータスバッチ(テストの成否が分かる)
  • ダッシュボード(テスト実行履歴や実行中のものを確認できる)
  • メール・チャットへの通知(slackへも可)

マージブロック

  • githubの機能でCIがokでないとマージできないようにできる。

参考(https://dev.classmethod.jp/tool/github/protect-branch/)

CIの種類

オンプレミス型

  • Jenkins
  • Concourse CI
  • Drone (クラウド版もあり)

・クラウド型

  • Travis CI
  • CircleCI
  • Wercker
  • Codeship
  • AWS CodeBuild
  • GCP Cloud Build
  • gitLab CI/CD

メリット・デメリット

https://codezine.jp/article/detail/11083

CI/CDサービスのオンプレミス型とクラウド型との比較

スクリーンショット 2019-03-01 19.25.36

CIの選定はどうすれば??

わからん。(ごめんなさい

色々と読んでいると、料金・使いやすさ・速さ・規模が重要なファクターになっていて、
流行りはCircleCIっぽいですね。

触ってみての感想ですが、AWS CodeBuildも流行りそうな気がしますが。

詳しい方選び方について教えてくださると嬉しいです。

読んでみた記事

ここの記事が良さげ。使ってみての感想を書いてるのと、メリットデメリット書いてくれてる。
https://sue445.hatenablog.com/entry/2018/12/07/114638

下記は少し古めの記事

https://qiita.com/tomlla/items/5e107578eda573e8d02b

https://qiita.com/uramotot/items/5f1a9f03b5df308822f8

jenkinsとcodebuildとの比較

https://qiita.com/umamichi/items/6b4c550f8ca5861f28d9

CDとは?

継続的デリバリー(Continuous Delivery)
継続的デプロイ(Continuous Deployment)

継続的デプロイはリリースに人の意思が介在しない。
継続的デリバリーは人の意思が介在する。

コード変更の度にデプロイされると困るケースもあると思うので、途中に承認フローを挟んでいるところは多そうですね。
こういった場合は継続的デリバリーに分類されます。

CICD

画像参照元(https://cloudbees.techmatrix.jp/devops/cd/)

何ができるの?

テスト以降のリリースの作業を自動化することができる。

何が嬉しい?

rollbackが自動化
ヒューマンエラーが発生しなくなる。
フィードバックループが回る。
→リリースに対して、億劫にならない。

よくある問題と解決

検証環境で見つからなかったバグ
仕様と違う動きをする
そもそも仕様が間違ってた。

→フィードバックループで解決
細かい単位でリリース。フィードバックを得て、カイゼンを繰り返す。

高度な使い方

本番環境でテストする
・ブルーグリーンデプロイで片方のインスタンスでテストできる
・カナリーリリースで部分デプロイし、本番でテストする。

hands-onに参加してみた

さて、では実際に作ってみたいと思います。
このセッションの話をしたら、弊社の高木さんが過去にハンズオンに参加したとのことで、教えてもらいました。
知見を深めるいい機会だったので、参加することにしました!

※クラスメソッドの方に記事にしていいか聞いてみたところ快く承諾いただけました。ありがとうございます。
興味ある方はぜひ参加してみてください。

参加したハンズオン
DevOps Hands-on vol.7〜CI/CD 環境構築ハンズオン(https://classmethod.connpass.com/event/121354/)

行った設定などは機能説明の後に記述しています。

使用したAWSの機能

  • CloudFormation
  • CodePipeline(CD)
  • CodeBuild(CI)
  • CodeDeploy(CD)

CloudFormationとは


以下はAWSのドキュメントより

AWS CloudFormation は Amazon Web Services リソースのモデル化およびセットアップに役立つサービスです。リソース管理に割く時間を減らし、AWS で実行するアプリケーションにさらに注力できるようになります。使用するすべての AWS リソース (Amazon EC2 インスタンスや Amazon RDS DB インスタンスなど) を記述するテンプレートを作成すれば、AWS CloudFormation がお客様に代わってこれらのリソースのプロビジョニングや設定を受け持ちます。AWS リソースを個別に作成、設計して、それぞれの依存関係を考える必要はありません。AWS CloudFormation がすべてを処理します。次のシナリオは AWS CloudFormation がどのように役立つかを示します。

要は、設計図の役割のようです。
EC2、RDSなどなど各リソースの設計、依存関係などをyamlかjsonで記述し、読み込ませることで自動的で構成してくれるツール。
サンプルテンプレートやGUIも用意されており、GUIでデザインしてしまえば一緒に生成されたyamlの内容をコピペするだけでオッケーのようです。
楽でいいですね。

料金はCloudFormationの分はかからない模様(EC2などには、料金発生する模様)

CodePipelineとは

AWS CodePipeline

AWS CodePipeline は完全マネージド型の継続的デリバリーサービスで、素早く確実性のあるアプリケーションとインフラストラクチャのアップデートのための、パイプラインのリリースを自動化します。CodePipeline は、お客様が定義したリリースモデルに基づき、コードチェンジがあった場合のフェーズの構築、テスト、デプロイを自動化します。これにより、機能とアップデートを素早く、信頼性の高い方法で配信できます。GitHub やお好みのカスタムプラグインなどのサードパーティ製のサービスと、AWS CodePipeline を簡単に統合することができます。AWS CodePipeline ならば、お支払いいただくのは実際に使用した分のみです。初期費用や長期契約は不要です。

読んだままですが、継続的デリバリーサービスです。

sourceの変更の感知からデプロイまでをマネジメントしてくれます。

codepipeline

今回の構成は以下でやっています

  • github(source)
  • CodeBuild(build+test)
  • CodeDeploy(staging+Production)

他の記事で、CodePipeline+CircleCIとかもみたので、設定次第のようです
(この構成以外だとどんな構成が主流なんだろうか・・・


CodeBuildとは

CodeBuild

AWS CodeBuild は、ソースコードをコンパイルし、テストを実行し、デプロイ可能なソフトウェアパッケージを作成できる完全マネージド型のビルドサービスです。CodeBuild により、ビルドサーバーのプロビジョニング、管理、スケーリングが不要になります。CodeBuild は連続的にスケールされ、複数のビルドが同時に処理されるので、ビルドが待機状態でキュー内に残されることがありません。パッケージ済みのビルド環境で、すぐに開始できます。自分のビルドツールを使用するために、カスタムビルド環境を作成することもできます。CodeBuild では、コンピューティングリソースの使用に対して、分単位で料金が発生します。

CI(継続的インテグレーション)ですね。
テスト環境のビルドと実行両方やってくれます。

buildspec.yamlに書いておくと自動で動いてくれるようです。(コマンドでも可な模様)

CodeDeploy

CodeDeploy

AWS CodeDeploy は、Amazon EC2、AWS Fargate、AWS Lambda、オンプレミスで実行されるサーバーなど、さまざまなコンピューティングサービスへのソフトウェアのデプロイを自動化する、フルマネージド型のサービスです。AWS CodeDeploy を使用すると、新しい機能をすばやく簡単にリリースできます。また、アプリケーションのデプロイ時のダウンタイムを回避し、アプリケーションの複雑なアップデート処理にも対応します。さらに、ソフトウェアのデプロイを自動化できるため、ミスが起こりやすい手動操作の必要がなくなります。このサービスでは、デプロイのニーズに応じてスケールできます。

CD(継続的デプロイ)ですね。
デプロイ時に必要な作業を自動化できます。

CodeDeploy内にアプリケーションを作成し、デプロイ先やデプロイ内容の設定をします。

appspec.yamlという設定ファイルを置いておくことで自動的にデプロイが可能。(コマンドでもおそらく可

全体構成

※画像はクラスメソッドさんが作成したものです
全体構成

リリースプロセス

ソース管理:github

CI: CodeBuild

CD:
CodePipeliune(継続的デリバリ)
CodeDeploy(継続的デプロイ)


解説

ソースの管理はgitで行います。
masterブランチのソースコードが変わった時にCodePipelineが検知しCodeBuildにてビルドを行います。
ビルドのテストが通ると次はCodeDeployが動き、EC2インスタンス1台ずつにデプロイする。

といった流れになります。

作ってみる(サンプルアプリケーション編)

まず、サンプルアプリケーションとCloudFormationを使って環境を構築します。

アプリケーションとCloudFormationのテンプレートは用意してあるもの(S3に置いてある)を使いました。

アプリケーション
github

CloudFormationのテンプレート
cloudformation1

※もし、テンプレートがない場合はサンプルテンプレートを使うか、自分でGUIなどでデザインする必要があります。

cloudformation4

次に、スタック名を決めて、IAMを同時に作成するかどうか聞かれるのでチェックを入れてつくってしまいます。
stack-name

cloudformation6

すると、作成中のステータスになるので、出来上がるまで待ちます。(5分くらい待ちました
cloudformation7

cloudformation8

できたので、サンプルアプリケーションが置かれる場所を確認しに行きます。

まだデプロイされていないのんでnginxのエラーが表示されます

appsample

作ってみる(CodeDeploy編)

さて、下準備ができたのでDeploy環境から作っていきます

 

アプリケーションの作成を押して、設定していきます

codedeploy1

アプリケーションメイトコンピューティングプラットフォームを決めます

今回はEC2にアップロードするのでこちらを選択します。

codedeploy2

codedeploy3

次にデプロイグループ名を決めます。

サービスロールは、先ほどcloudformationで自動生成されているので、そちらを選択します
codedeploy4

デプロイタイプ、環境設定、ロードバランサーを選択して、デプロイグループの作成を行います。

codedeploy5

作ってみる(CodePipeline,CodeBuild編)

次にCodePipelineの設定をしていきます。

この過程で、CodeBuildも同時に作成します。

codepipeline1
パイプライン名をつけて、rollは作成済みのものを選択します
codepipeline2
次にソースステージを選択します。
今回はgithubなので、githubと連携させます。

codepipeline3
連携終了後リポジトリを選択し、コードが変わった時に見て欲しいブランチを選択。
今回はデプロイまでして欲しいのでmasterになります。
codepipeline4

ソースの選択が終わったら、次にビルドの設定をしていきます。
今回はCodeBuildを使って欲しいので、選択すると同時に別窓でCodeBuildの設定をします。(選択すると勝手に開きます。)

codebuild1

プロジェクトに合わせて選択

今回は、OperationSystemはUbuntu。

RuntimeはNode.jsを選択しました。
codebuild2
任意のversionを選択し、(常に最新を使う設定もあります)

作成済みのサービスロールを選択。
codebuild3

buildspecは作成済みのものを使うので”Use a buildspecfile”を選択し、作成終了します。

codebuild4

ここでCodePipelineに戻ってくるので、次へを選択。
codepipeline5

デプロイの設定は、先ほど作ったCodeDeployのアプリケーションをそのまま使います。
codebuild6

codebuild7

これで設定完了です!!!

使ってみる

最初は自動的に動くようになっています。
動いているかどうかの確認はCodePipelineで確認できます

codepipeline7

codepipeline6

ということでビルドが通って、デプロイが完了しました。
先ほどのエラーページが出た画面を確認してみます。

デプロイできてる!!!!

sampleapp2

テストをわざと落としてみる

では、テストが落ちた時にどんな挙動をするのか確認します。(5行目を変えています)

test-faild

落ちました!!デプロイはされないようになっています!!!
test-faild-pipe

ということで、以上がハンズオンの内容でした。
一回やってしまうと理解は深まりますが、その1回目が辛いだろうなとやってて感じました。

おまけ1 プルリクエスト毎にビルドテストする

新しく作る必要があります。

ソースなどは、github,リポジトリを選択するのは同じ工程ですが、
“primary source webhook events”を選択することで、毎回’ビルドテストしてくれて、テストが落ちた場合はmargeできないようにしてくれます

omake-giy

 

codebuild-webhook codebuild-webhook2

おまけ2 手動承認を挟む

勝手にデプロイされるのはまずいという場合は手動デプロイのフローを増やすこともできます

設定はCodePipeline上で”編集→ステージの追加”で簡単にできます

omake2-1 omake2-2 omake2-3 omake2-4 omake2-5

Pocket
LINEで送る