この記事は
最近「継続的デリバリー」を読んでいるので、そのまとめのようなものです。
如何せん長編ということもあり *1、まだ読了していないのですが、この本の中心となる考えである「デプロイメントパイプライン」が紹介されている5章まで読み終わったので、一つの区切りとして記事を公開します。
まず、筆者である私と継続的デリバリーについて、この本に出会う前の状況を簡単に書き下します。
私と継続的デリバリー
- 業務で一定の関わりはある
- 一方で現状に漠然とした少し行き詰まりを感じていた
- ここからもう一歩踏み込んで勉強したい、という時にどこから手を付けたものか分からない
- 現状のCI/CDについてもっと課題点のイメージを固めたい
- それに対する解決策のヒントを得たい
そこで、この「継続的デリバリー」に対しては、以下のようなことを期待して読み始めました。
- 継続的デリバリーに対する広く浅い、入門的な知識を得る
- 実践はしてきたものの、ヌケモレが不安
- ここで入門的な知識を固めておくことで、後から個別のテーマを追いやすくしたい
- 継続的デリバリーが誕生した経緯、歴史を知る
- 個人的な興味に近い
- どんなプラクティスでも歴史を知っておくことに意味があると思う
以下、5章までの簡単なまとめと、それに対して私が印象に残った箇所をまとめて記載します。
各章別の概要と感想
導入
あらすじ
- この本ではソフトウェア開発において、開発からリリースまでの自動化戦略を通して、継続的にユーザーに価値を提供するにはどうすれば良いのかの見取り図を提供する
- 中心となる考えが「deployment pipeline(5章)」
印象に残った箇所
- 「コードを1行だけ変更したとして、その変更をデプロイするのにあなたの組織ではどのくらいかかるだろうか?その変更からデプロイまでの作業は反復可能で信頼できるやり方に基づいて行われているだろうか?」
- 「時間」(サイクルタイムにも近い)だけじゃなく「反復可能性」という大事な考え方を提示してるとおもった
- 反復可能=自動化ができるはず、自動化することによってプロセス自体の検証が容易になる?
感想
- 理論よりも実践に近い本だと知る。「継続的デリバリ」そのものに対して大きな見取り図を提供してくれそう。自分の期待値に合っていると感じた。
1章
めっちゃまとめると
- リリースって大変だし手作業だとミスが起こりやすいよね
- なるべく自動化しよう、全ての関係あるものをバージョン管理しよう、開発者は運用、テスト担当と協調して仕事を進めよう
- つまり、「ソフトウェアをリリースするための、反復可能で信頼できるプロセスを作り上げよ」
印象に残った箇所
- 裁量措置について
- 手作業が介する手順は作業者の判断の余地を生じさせる。それが結果ヒューマンエラーにつながる。
- デプロイメントプロセスが自動化されていないと、反復可能にならないし、信頼できない
- 「反復可能だから自動化できる」というよりも「自動化されているからちゃんと反復可能である」
- リリースプロセスの品質を確かめるには自動化するしかない
- そうしないと作業者の作業品質を評価することになる(それはプロセスの評価ではない)
- プルシステム
- QA,TE,運用担当が「このバージョンをデプロイしてくれ」と依頼するのでなく、彼らが好きなバージョンを好きな環境にデプロイできる状態にすること
- どこにデプロイする場合でも、デプロイメントのアプローチを同一にするのが最善の策
- 環境固有の作業を極力生じさせないことでデプロイプロセスの品質を担保する
感想
- 自動化は偉大。自動化することでプロセスの品質を担保することが出来る
- 逆に言えば手動で作業しなければいけない領域がある時点で、そこにプロセスの品質を阻害する要因が入り込む可能性がある
- 極力エラーを減らした上で高速にフィードバックサイクルを回すにはどうすれば良いかを語っている
- 継続的インテグレーションはそれまで開発プロセスの最後に一度だけ行なっていたインテグレーションを常に行う(チェックインと同時)ことで、インテグレーションに伴うリスクを軽減して品質を高めるアプローチ
2章 構成管理
まとめると
- 構成管理とはプロジェクトの成果物に関わる関係性と成果物が保存、検索、一位に特定され修正されるプロセス
- これだけだと抽象的だが、環境設定(OS、アプリ、ネットワークなど)などが対象というと具体的
- これをチームメンバが再現可能で、インクリメンタルに改善可能な形にしておく必要がある
印象に残った箇所
- トランクベースはCIと相性がいい
- 逆にブランチベース開発がCIと相性がよくない
- ブランチを統合するまでの間マスターでのCIを回すことができず頻度が落ちリスクが高まる
- 社内maven repositoryのように外部ライブラリのコピーを取っておく話
- これがコンプライアンスの観点から重要ということは初めて知ったかも
- 確かに言われてみると外部からのファイルダウンロードになるので一定リスクがある
- 設定はアプリケーションの挙動を外部から変更するもの、すなわち一定のリスクがあり必ずテストすべき
- 設定をテストする、設定によってアプリを壊すという発見
- アプリケーションのソースコードと設定は変更速度が異なるので分けて管理する
- 変更される頻度、タイミングという観点で、SRP(単一責任原則)とも似ている考えかなと思った
- 適切にデプロイされた状態にある環境はベースラインと呼ばれ、自動化された環境プロビジョニングシステムではあらゆるベースラインの構築、再構築をできる必要がある
- 再現可能性
3章 継続的インテグレーション
ざっくりとしたまとめ
- 継続的インテグレーション(CI)は定期的(しかも高頻度)にシステムを統合し、ビルド、テストすることで、システムが常に動作可能な状態を作ることを目指す
- 元々統合にはリスク(ビルドが失敗しやすい、意図しないシステムを作り込んでしまう)があり、これを低減させるためにより頻繁に統合を行うようにした
- CI実現のためにはコードのバージョン管理、環境の構成管理、そしてチームのコミットメント(ビルド失敗時にチェックインしない等)が必要不可欠
印象に残った箇所
- コードベースを定期的に統合することがよいのならそれを常にやるほうが良い
- 常に=誰かがバージョン管理システムに何かしらの変更をチェックインする時
- つまり思ったよりも高頻度だしエンジニアの数が増えるほどその頻度は増していく
- CIサーバーを使うことで得られる最も重要な恩恵の一つが可視性
- CIサーバーにはコマンドの定期実行だけでなくグラフィカルな出力を行うwebサーバー、外部出力の機能がある
- 飛行機のパイロットは着陸するたびに何か問題が起きることを想定するべきだと教えられる
- 常にrevertできるようにせよ、というところの例
- チェックインしてビルドが壊れたら10分取って直す、それで無理ならリバーとする
- タイムボックスを切って修正する、というアイデア
- テストが遅い場合にビルドを失敗させる
- まずは計測しないと話にならない
4章 テスト戦略を実装する
ざっくりとしたまとめ
- 自動テストはプロジェクトの状態によって導入戦略が異なる
- 「高品質を実現するために、大人数での調査に頼るのをやめよ。まずはプロセスを改善し、本番の品質を作り込め」(デミング)
印象に残った箇所
- 同じテストを2回繰り返したら自動化するのが良い
- ただしテストのメンテナンスコストが高いなら安易に作るのも考えもの
- デプロイメントテスト
- アプリケーションが正しくインストールされ、正しく設定され、必要なサービスと接続できてレスポンスが帰ってくることをテストする
- 従来のE2E内で暗黙的に担保されているが、セットアップなどで分けて最初にテストするのもありかな?と思う
- ビジネス視点でのプロジェクト評価「テスト」としてのイテレーションレビュー
- 早めに成果物を見せる
- どこまでフィードバックを取り込むかは別としても、早めに動かせるに越したことはない
- モックをコラボレーターとのやりとりではなくいくつかのコードの動作に関する詳細をアサートするためだけに使うのはNG
- 実装を変えるとテストが壊れてしまう、壊れやすいテストを生み出すもととなる
- INVEST原則
- independent, negotiatable, valuable, estimatable, small, testableなストーリーを作る
感想
- モックの使い方はもっと洗練させられる
- パーシャルモックはアンチパターンくらいの勢いにしていきたい。
5章 デプロイメントパイプラインの解剖学
ざっくりまとめ
- デプロイメントパイプラインはソースコードから顧客に成果物をデリバリするまでのプロセスを自動化したもの
- 自動化されているからこそ反復可能であり、プロセスの品質を担保できる
- デプロイメントパイプラインはチームがフィードバックを高速に受けられるようにするためにも存在する
- デプロイメントパイプラインはコミットステージ、受け入れテストステージ、その後のステージからなる
- コミットステージでは静的解析、ユニットテストなど(長くても10分)
- 受け入れテストステージでは自動化された受け入れテストをまわす
- その後のステージでは手動テストや非機能的なテスト(自動の場合もある)を回す
- 結果リリースの準備が万全になる
- デプロイメントパイプラインでリリースを自動化する
- 後続するステージでリリースを自動化するところまで含むことができる
- その場合はバックアウト戦略なども考えておく
- 後続するステージでリリースを自動化するところまで含むことができる
- デプロイメントパイプラインを作るには
- まずバリューストリームを明確にする
- そのあとはインクリメンタルに作っていく
印象に残った箇所
- コミットステージではユニットテストをすべて実行するが、その後のステージで失敗しやすいテストを実行することも検討できる
- より早くフィードバックを得てより早く失敗するため
- ユニットテストでテストしているのはコードが正しく動くかであり、問題をきちんと解決できるかではない
- それは受け入れテストの責務である
- ユビキタス言語を用いてテストを設計する
- デプロイを民主化する、従来の組織の役割を越境する
- 開発者だけにテストを閉じさせない、その上でユーザーの要件を満たすものにする
感想
- デプロイメントパイプラインが継続的デリバリの根本的な概念であるとわかる
- あとで読み直すとしたらこの章になりそう
- 非機能要件に対するテストがまだあまりイメージがついていないかもしれない
- 実際にそこまでシビアなプロジェクトにぶつかっていないから説はある
まだ読み切れていないものの継続的デリバリ、デプロイメントパイプラインといった概念について見取り図を知ることが出来る、という観点で良い本だと思いました。
私は現状この分野についてあまり明るくないのですが、ここで見取り図のようなものが頭に入ることで詳細なテーマについてどのように深ぼっていけばいいかイメージが格段に湧きやすくなったと思っています。