/ci-cd-hands-on

CI/CD環境構築ハンズオン用リポジトリ

Primary LanguageHTML

CI/CD環境構築ハンズオン

アジェンダ

  1. 構成の簡単な紹介
  2. サンプルアプリケーションのフォーク及びクローン
  3. ハンズオン用環境構築用のCloudFormationの実行
  4. 手動デプロイしてみる
  5. CodePipelineによるパイプラインの構築
  6. テストが失敗するとどうなるかを見る
  7. 再度正しいコードに戻す

ハンズオンで構築する構成

構成図

今回は上記の図のような構成を構築します。

GitHubにコードがプッシュされるとCodePipelineでの処理が開始されます。CodeBuildではテスト、Dockerイメージの作成および作成したイメージのECRへのプッシュを行います。CodeBuildでの処理が成功したらECSに新しいバージョンのイメージがデプロイされます。

1. サンプルアプリケーションのフォークおよびクローン

まずは、今回利用するサンプルアプリケーションのリポジトリをフォークし、自分のアカウントにリポジトリを作成します。 サンプルアプリケーションは、指定された数までFizzBuzzを表示するNode.jsによる簡単なアプリケーションです

サンプルアプリケーション

上のリンクからGitHubの当該リポジトリのページに移動し、右上の Fork というボタンからフォークを実行します。

自分のGitHubアカウント上に作成されたフォークしたリポジトリから、ローカルのPCにクローンします。 作業用のディレクトリで以下のコマンドを実行します。

$ git clone git@github.com:<ご自分のgithubのアカウント名>/ci-cd-hands-on.git

クローンされたリポジトリのディレクトリに移動して中身を確認し、クローンが正しく行われたことを確認します。

$ cd ci-cd-handson
$ ls
Dockerfile	Rakefile	config		log		template
Gemfile		app		config.ru	package.json	tmp
Gemfile.lock	bin		db		public		vendor
README.md	buildspec.yml	lib		spec

2. ハンズオン用環境構築用のCloudFormationの実行

Launch Stack

上のリンクより、ハンズオン用の環境を構築するためのCloudFormationを実行します。

この、CloudFormationによって、以下の図ような構成の環境が作成されます。

CloudFormationによってい構築される構成

アプリケーションの動作環境以外に後でCodeBuildで使用するためのIAM Roleを作成しています。

作成したスタックが CREATE_COMPLETE の状態になるまで待ちます。

動作確認

作成したスタックの出力にALBDNSNameというキーで出力された値が、今回のサンプルアプリケーションのアクセス先のURLです。アドレスバーにコピペして、サンプルアプリケーションの動作を確認します。

3. 手動デプロイしてみる

ecs-deployのようなデプロイに便利なツールもありますが、CodeBuildで行う処理との対比をわかりやすくするため、ここではそういったものは使わずにデプロイを実行します。

まずはデプロイされたことがわかりやすくするため、画面を修正します。

$ vim app/views/layouts/application.html.erb 
$ git commit -am "manual deploy"$ 

つぎに以下のコマンドを実行し、手動でデプロイを実行します。

まず、手元でDockerイメージを構築し、ECRにプッシュします。

$ $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)

$ IMAGE_REPOSITORY_NAME="<環境構築用スタックのImageRepositoryNameという出力の値>"
$ IMAGE_TAG=`git rev-parse HEAD`
$ docker build -t $IMAGE_REPOSITORY_NAME:$IMAGE_TAG .
$ docker push $IMAGE_REPOSITORY_NAME:$IMAGE_TAG

$ echo $IMAGE_REPOSITORY_NAME:$IMAGE_TAG

ECSの設定の修正で使用するため、イメージをプッシュしたリポジトリとタグの値を覚えておきます。

ここまでの操作の中でも、プッシュする対象とは異なるブランチで作業を行っていた場合や、リモートブランチとの同期を忘れるなどした場合には意図したものとは異なるソースコードをデプロイしてしまうリスクがあります。

つぎに、コンソールの操作に移り、実際にECSへのデプロイを行っていきます。

マネジメントコンソールからECSの画面に移動します。

まず、タスク定義の新しいリビジョンを作成します。

環境構築用スタックによって作成されたタスクの新しいリビジョンの作成画面を表示します。 コンテナ名fizzbuzzの設定画面に移動し、イメージの指定を先程プッシュしたイメージのものに書き換え新しいリビジョンを作成します。

次に、環境構築用スタックによって作成されたサービスの編集画面に移動し、新しいタスク定義のリビジョンを指定するように編集をおこない、サービスの更新を実行します。

しばらくすると新しいタスク定義に基づくタスクが実行され、コードの修正が反映されます。

4. CodePipelineによるパイプラインの構築

手動でのデプロイが大変だと感じてもらったところで、CodePipeline/CodeBuildを使用したパイプラインを作成していきます。

今回作成するパイプラインは以下図の左側の部分です。

構成図

では、早速作成していきましょう。

マネジメントコンソールのトップ画面より「CodePipeline」をクリックします。

devops-hands-on-15

まだパイプラインを作成していない場合は以下のような画面が表示されるので「今すぐ始める」をクリックします。

devops-hands-on-16

パイプラインのセットアップが開始するのでパイプライン名をわかりやすい名前(hands-on-pipelineなど)で入力して「次のステップ」をクリックします。

devops-hands-on-17

ソースプロバイダのセットアップが始まるので以下の表のように入力後、「次のステップ」をクリックします。

入力項目
ソースプロバイダ GitHub
リポジトリ フォークしておいたリポジトリ
ブランチ master

ビルドプロバイダのセットアップが始まるので以下の表のように入力後、「ビルドプロジェクトの保存」をクリックしてから「次のステップ」をクリックします。

入力項目
ビルドプロバイダ AWS CodeBuild
プロジェクトの設定 新しいビルドプロジェクトを作成
プロジェクト名 わかりやすい名前(hands-on-projectなど)
環境イメージ AWS CodeBuild マネージド型イメージの使用
OS Ubuntu
ランタイム Node.js
バージョン aws/codebuild/nodejs:10.1.0
ビルド仕様 ソースコードのルートディレクトリの buildspec.yml を使用
CodeBuild サービスロール 環境構築用のスタックの出力
VPC No VPC
特権付与(アドバンスト内)
環境変数(アドバンスト内) 名前:IMAGE_REPOSITORY_NAME,
値:環境構築用のCloudFormationImageRepositoryName という出力の値

デプロイプロバイダのセットアップが始まるのでプロバイダに「Amazon ECS」を入力後、「AWS CodeDeploy に新たにアプリケーションを作成します。」のリンクをクリックします。

入力項目
デプロイプロバイダ Amazon ECS
クラスター名 <ハンズオン環境用 CloudFormationスタック名>-ECS-Cluster
サービス名 <ハンズオン環境用 CloudFormationスタック名>-ECS-Service
イメージのファイル名 imagedefinitions.json

CodePipelineにアタッチするIAM Roleの画面に変わるので、「ロールの作成」をクリック後、遷移する画面で「許可」をクリックします。

devops-hands-on-21

IAM Roleの作成が完了したら「次のステップ」をクリックします。

devops-hands-on-22

最後に確認画面が表示されるので、内容を確認後、「パイプラインの作成」をクリックします。

すると、パイプラインが自動で開始されます。

Stagingステージまで緑色になり、デプロイが完了したところで一度正常にページにアクセスできることを確認します。

5. テストが失敗するとどうなるかを見る

バグが混入した際に、テストでデプロイが途中で止まることを確認するため、フォークしたリポジトリのコードを修正します。

エディタでFizzBuzzのロジックが記述されているファイル、src/model/fizzbuzz.jsを開きます。

意図的にバグを混入させるため、

if (i % 15 == 0) {

と書かれた行を

if (i % 10 == 0) {

のように修正します。

修正が終わったらコミットし、GitHub上にプッシュします。

$ git commit -am bug
$ git push origin master

GitHubにプッシュすると、CodePipelineでの処理が開始されます。 しかし、CodeBuildでテストが失敗し、ECSへのデプロイは実行されません。

ß

テストが自動で実行される環境が構築されていたため、バグの混入したバージョンがデプロイされるのを防ぐことができました!

6. 再度正しいコードに戻す

先程の修正をもとに戻すため、app/models/fizzbuzz.rb を開きます。

if (i % 10 == 0) {

のように先程編集した行を

if (i % 15 == 0) {

のように修正し、GitHubにプッシュします。

$ git commit -am fixbug
$ git push origin master

同様に自動でCodePipeline上での処理が開始されます。

今度はテストが成功するため、デプロイが行われました。

まとめ

CodePipelineを使用することでデプロイやテストが自動で実行されるようになりました。

煩雑な手作業が自動化されることで人為的ミスを削減し、デプロイにかかる時間を短縮できます。

補足. 環境の削除

ハンズオンで作成した環境を削除したい場合は以下の手順を参考にしてください。

  • CodePipelineのパイプラインの削除
  • CodeBuildのプロジェクトの削除
  • IAM Roleの削除 CodePipeline用 CodeBuild用
  • CodePipelineのアーティファクト保存用S3バケット削除
    • ※ 他のパイプラインでも利用している場合があるので注意
  • ECRリポジトリ内のイメージをすべて削除
  • CloudFormationスタックの削除