[レポート] DEV319: 継続的インテグレーションのベストプラクティス #reinvent

こんにちは、佐伯です。re:Invent 2018に参加しております。早速ですが本エントリは、DEV-319「Continuous Integration Best Practices」のセッションレポートとなります!

概要

Today, more teams are adopting continuous integration (CI) techniques to enable collaboration, increase agility, and deliver a high-quality product faster. Cloud-based development tools such as AWS CodeCommit and AWS CodeBuild can enable teams to easily adopt CI practices without the need to manage infrastructure. In this session, we showcase best practices for code reviews and continuous integration, drawing on practices used by Amazon engineering teams. We’ll incorporate demos to not just explain the practices but show you how.

スピーカー

Joseph Vusich - Software Development Engineer
Nick Brandaleone - Senior Solutions Architect, AWS

アジェンダ

  • 継続的インテグレーションの紹介
  • 継続的インテグレーションツール
  • 継続的インテグレーションベストプラクティスとテクニック
  • デモ
  • まとめ

継続的インテグレーションの紹介

継続的インテグレーション(以下、CI)はチームのメンバーが頻繁に統合するソフトウェア開発の実践です。自動ビルドおよびテストプロセスによって検証されます。継続的インテグレーションは継続的デプロイメントが導入されている間に成果物を生成し検証します。

継続的インテグレーションとはなにか?

  1. デベロッパー定期的にリポジトリにコードを記録
  2. コードに対して定期的に自動チェックを実行
  3. デベロッパーは自動チェックからフィードバックを受け取る

一般的な開発フロー

  1. コーディング
  2. ローカル環境でコンパイルとユニットテストを実行
  3. コードをGitリポジトリにPush
  4. イメージをビルド
  5. 新しいコードに対してインテグレーションテストを実行
  6. イメージをリポジトリにPush
  7. デプロイ

なぜCIが重要なのか?

  • より早くバグを発見できる
  • より早くバグを修正できる
  • より早くデリバリーできる
  • より多くデリバリーできる
  • デベロッパーの障害物を取り除く
  • より早くスキルを伸ばす

サマリー

  • "Frequency Reduces Difficulty"
  • それぞれの新しい繰り返しは早く・手軽でなければならない
  • 一貫性が信頼を向上させる
  • 継続的な自動化
  • 能力のある開発者が幸せなチームを作る
  • バッチサイズが小さいほどデバッグが簡単
  • ソフトウェア開発の改善

CIツール

CIツール

  • ソースコード
    • AWS CodeCommit
    • GitHub
    • GitHub Enterprise
    • BitBucket
    • S3
  • ビルドとテスト
    • AWS CodeBuild
    • Jenkins w/ CodeBuild
  • 連携
    • Amazon CloudWatch Events
    • AWS Lambda
    • Slack integration
    • SNS(E-mail/Texts)
    • その他AWSサービス

AWS CodeCommit

  • フルマネージドGitサービス
  • プライベートリポジトリ
  • S3バックエンド
  • S3バックエンドだからスケールの心配不要
  • いつでも取り出し可能

AWS CodeCommitの機能

(New!)AWSマネジメントコンソールでCodeシリーズが統合されたUIになりました。

  • Commit Visualizer
    • リポジトリコミット履歴のビジュアライズが可能
  • Pull Request
    • Pull Request作成可能
  • 通知
    • Amazon SNSと連携してメール通知やLambdaでSlack通知も可能

AWS CodeBuild

  • フルマネージドビルドサービス
  • 複数ビルドの並列ビルド
  • 時間課金
  • 拡張性

AWS CodeBuildの機能

  • ビルドソース
    • CodeCommit, S3, BitBucket, GitHub, GitHub Enterprise
  • Webhookをサポート
  • 複数のソース入力とアーティファクト出力
  • VPC内で起動
  • Amazon Parameter Storeとの連携
  • キャッシュ機能
  • ローカルでのデバック

AEWS CodeBuildのサポートしているビルド環境

  • Ubuntu
    • .NET Core
    • Android
    • Docker
    • Golang
    • Java
    • Node
    • PHP
    • Python
    • Ruby
  • WIndows Server 2016
    • .NET Framework
    • .NET Core
    • C#
    • F#
    • Visual Basic

AWS CodeBuild: ビルド設定

  • 各ビルドフェーズでタスクを設定
    • install: ビルド環境必要なパッケージなどをインストールを実行
    • pre_build: ビルドに必要なライブラリなどのインストールを実行
    • build: コンパイルやテストなどのビルドを実行
    • post_build: ビルド後のパッケージ化、ビルドの成功/失敗通知などを実行
  • 設定ファイルはYAML形式

参考リンク: AWS CodeBuild のビルド仕様に関するリファレンス - AWS CodeBuild

CIベストプラクティスとテクニック

CIジャーニー

  • Nightly checks: 毎日など定期的に実行するCI
  • Branch checks: ブランチへのPushをトリガーとしたCI
  • Pull Request checks: プルリクエストトリガーのCI

Nightly checks

Nightly checksは定期的(毎日など)にビルドを実行する方法。

  • Nightly checksの実装
    • CloudWatch EventsをトリガーにAWS CodeBuildでビルドを実行する
  • スピードブースト
    • コードベースのメンテナンスを自動化する
    • メール通知

スピードブースト

  • アップデートの自動化
    • CloudWatch Eventsで定期的にビルドを実行
    • ビルド内で依存ライブラリのアップデート、テストを実行
    • リポジトリへPush
  • メール通知
    • AWS CodeBuildのビルドの失敗イベントなどをCloudWatch Eventsでモニタリング
    • CloudWatch EventsからAmazon SNSに連携しメール通知

ビルド失敗/タイムアウトをトリガーするCloudWatch Events ルールパターン例:

{
  "source": [
    "aws.codebuild"
  ],
  "detail-type": [
    "CodeBuild Build Phase Change"
  ],
  "detail": {
      "build-status": [
          "FAILED",
          "TIMED_OUT"
      ]
  }
}

参考リンク: AWS CodeBuild のビルド通知サンプル - AWS CodeBuild

Nightly checksのサマリー

  • 実装: 毎晩実行など
  • フィードバックループ: 16-24時間
  • チームへの影響: ビルド間隔がまる1日程度あり、修正が必要なコードがマージされる可能性あり
  • スピードブースト: コードベースメンテナンスの自動化、メール通知

Branch checks

Branch checksは特定ブランチに変更がPushされる度にビルドを実行する方法。

  • Branch checksの例
    • AWS CodeCommit -> CloudWatch Events -> AWS CodeBuild の連携
  • スピードブースト
    • Slack通知
    • ビルドバッジ
    • キャッシュ

スピードブースト

  • Slack通知
    • AWS CodeBuild -> CloudWatch Events -> AWS Lambda -> Slack
    • CloudWatch EventsをトリガーにLambdaファンクションを実行し、ビルドステータスをSlackに通知する
  • ビルドバッジ
    • ビルドバッジを使用してリポジトリの最新のビルド結果を知らせる
  • キャッシュ
    • S3バケットへのキャッシュ機能を使用することでビルド実行時間を大幅に削減

Branch checksのサマリー

  • 実装: 特定ブランチに変更がPushされる度にビルドを実行
  • フィードバックループ:ビルドに必要な時間
  • チームへの影響: サイクルは短くなったが、特定ブランチのビルドのため修正が必要なコードがマージされる可能性あり
  • スピードブースト: Slack通知、ビルドバッジ、キャッシュ

Pull request checks

Pull request checksはプルリクエストの作成をトリガーにビルドを実行する方法。

  • Pull request checksの例
    • AWS CodeCommit -> CloudWatch Events -> AWS CodeBuild -> CloudWatch Events -> AWS CodeCommit
    • ビルド実行まではこれまで同様だが、ビルド結果をプルリクエストのコメントする

スピードブースト

  • インテグレーションテストをする
    • AWS CodeBuildはビルドコンテナをVPC内で起動できる
    • VPC内のリソースにアクセスが必要なインテグレーションテストを実行する
  • 並列ビルド
    • AWS CodeBuildは並列ビルド可能
    • 利用料はコンピューティングタイプとビルド時間に対して発生

参考リンク: AWS CodeBuild の制限 - AWS CodeBuild

Pull request checksのサマリー

  • 実装: レビュー中にビルドを実行
  • フィードバックループ: ビルドに必要な時間
  • チームへの影響: PRがマージされる前にビルドを実行するので十分なテストを行っていれば修正が必要なコードがマージされることはない
  • スピードブースト: インテグレーションテスト、並列ビルド

まとめ

  1. ライブラリのアップデートなど退屈な作業を自動化する
  2. ビルドステータスを通知する
  3. キャッシュ、並列ビルドでビルド時間を短縮
  4. インテグレーションテストを取り入れる

サンプル

buildspec.ymlや各サービスとの連携用のLambdaファンクションのサンプルが以下リポジトリにあります。

最後に

CIに取り組みたいが何から手をつけて良いかわからない or そこまでコストが割けないなどの場合、CIジャーニーを参考に最初はNightly checksを導入してみるのはいかがでしょうか。