Lean と DevOps の科学を読んで

Kenta Kosugi
17 min readOct 27, 2022

この書籍自体は2018年に発売されたものですが、2022年の IT エンジニア本大賞技術部門ベスト10に入っている書籍になります。みなさんは以下の本の中で何冊読みましたか?私は 2021 年に4冊、2022年に入って、この Lean と DevOps に出会いました(良著でした)。

少し前にソフトウェア品質シンポジウム2022で和田さんが講演した中で、本書が取り上げられていたので再度話題にあがっているようです。

その時の様子はいかにまとめられていました。

本書には過去に読んだ「The Unicorn Project」の作者である「ジーン・キム」氏も著作に関わっています。「The Unicorn Project」も非常に面白いので是非読んでみてはいかがでしょうか。

本書の特徴

普段 DevOps / Agile 開発を実践している人が何気なく感じていることをデータを示して明らかにしたということろが本書の大きな役割ではないでしょうか。

本書の結論

ソフトウェアデリバリのパフォーマンス

これに尽きると思います。

一見、ソフトウェアのデリバリスピードが速い企業は品質を犠牲にしていると思われがちだったのですが、それを数あるデータから間違いだったということを示しています。

本書には 2016年、2017年のレポートしか掲載されていませんが、このデータの元となった DevOps Report 自体は途中からスポンサーを Google に変え、毎年発行されているものになっています。したがって、2018年以降のデータも取得しようと思えば可能です。

2016 年に明確になったケイパビリティ

本書ではシステムのタイプ(SoR や SoE、パッケージソフトウェア、組み込み開発)とデリバリのパフォーマンスには相関関係は見受けられなかったと言っています。

SoR を開発している企業でもハイパフォーマーはいるし、SoE を開発している企業でもローパフォーマーはいるということを表しています。

ただ、2016年のアンケートでは、ハイパフォーマーが回答したアンケートの内容には、アプリケーションのアーキテクチャのある二つの特性との強い相関関係があったと記載されています。それが以下の二つです。

  1. テスト容易性
    テストの大半を、統合環境を必要とせずに実施できる
    (※) 統合環境 = ステージング、テスト環境などの特殊な環境のこと
  2. デプロイ容易性
    アプリケーションを、それが依存する他のアプリケーションやサービスからは独立した形で、デプロイまたはリリースできる(そして実際にもデプロイまたはリリースしている)。

言われてみれば違和感はないですが、漠然としたイメージしか湧かないのでもう少し深ぼってみましょう。

テスト容易性

上記を言い換えると、テストの大半をテスト環境、ステージング環境を必要とせずに実施できるということです。

極論をいうと、開発者もしくはテスター自身の PC でテストが実行できることと置き換えても良いのではないかと思います。実際、単体テストは自分の開発環境で書いて、どんどん実施していきます。

Test Drvien Development を実践されている方は、コードよりも先にテストコードを記載し、Red(テスト失敗) → Green(テスト成功) → Refectering (リファクタリング)を実践しより良いコードになるように心がけているはずです。

テストがテスターみんなで共有されるテスト環境とか、ステージング環境でしか実施できないと品質が悪くなるのは分かりきったことでしょう。環境の取り合いが発生しますし、誰かが汚したデータベースをまっさらにしてからテストをやり直さなければいけないので、テスト時間に非常に多くのリードタイムがかかってしまいます。

デプロイ容易性

デプロイ容易性は一体どういうことでしょうか。本書の P.77 に言い換えたものがありますので、引用します。

コンテキスト境界と API により、大規模なドメインを、より小規模、より疎結合なユニットに分割する

これについては以下のエントリで詳しく取り上げていますので、時間があれば読んでいただければと思います。

簡単にいうとドメイン駆動設計によって(データやビジネスロジックの)責務が分離されたシステム群ということになります。

詳細は後述します。

2017年に明らかになったケイパビリティ

2017年にはアンケートを増やしました。そして、テスト容易性やデプロイ容易性の他にどのケイパビリティがハイパフォーマーと相関関係があるのかについて明らかにしました。

それが以下になります。

チーム外の人物の許可を得なくても対象システムに大幅な変更を加えられる。

対象システムの変更作業で他チームに頼ったり、他チームに相当量の作業を課したりすることなく、対象システムに大幅な変更を加えられる

チーム外の人々とやりとりしたり協業したりすることなく作業を完遂できる

ソフトウェア製品やサービスを、それが依存する他のサービスに関係なく、オンデマンドでデプロイ、リリースできる。

統合テスト環境を必要とせずに、オンデマンドでテストの大半を実施できる

デプロイメントを、無視できるほどわずかな稼働停止時間のみで、通常の勤務時間内に完了できる。

本書ではこの部分でコンウェイの法則と逆コンウェイ戦略を掲載しています。結論をいうと、開発するシステムは組織の構造に似てしまうため、作りたいアーキテクチャに合わせて先に組織を作っておきましょうということを言っているのです。

本ページより引用

本書ではドメイン駆動設計によって、コンテキスト境界と API によってより小さな粒度となったユニット(上記図では ServiceX)、それに合わて組織を形成することによって(逆コンウェイ戦略)、組織とアーキテクチャが疎結合な仕組みが出来上がります。

ここでドメイン駆動設計の再登場です。以下の図を見てください。

ドメイン駆動設計におけるコンテキスト分割

ファットモデル + モノリスの場合、何か変更を加えようとすると各チームに影響範囲が及びます。自分のチームにしか関係のない変更であっても、別のチームに作業を依頼しなければならなくなります。加えて、モノリスであるためにアプリケーションのビルド、テスト、デプロイ等の作業はチーム全体で共有されます。自分の機能だけをビルド、テスト、デプロイということはできません。

DDD を使ってコンテキスト分割すると影響範囲が極小化されるような分割の単位でサービスを形成することが可能です。これにより、自分のチームの変更は自分のチームにしか影響を及ぼさない上、自分のチームだけでビルド、テスト、デプロイが回せるのです。

つまり、組織とアーキテクチャが疎結合な仕組みができあがることによって、ハイパフォーマーとなっているというのを本書では言っています。

チーム外の人物の許可を得なくても対象システムに大幅な変更を加えられる。

対象システムの変更作業で他チームに頼ったり、他チームに相当量の作業を課したりすることなく、対象システムに大幅な変更を加えられる

チーム外の人々とやりとりしたり協業したりすることなく作業を完遂できる

この3点はまさにそういうことを表しています。

12 factors app

ご存知の方も多いとは思いますが、 SaaS を開発する上でのベストプラクティスや原則が載っています。製作者は Heroku のアーキテクトだそうで、クラウドネイティブ業界でははほぼ当たり前になっていることが列挙されています。その中の「プロセス」にはのことが記載されていますが、これは上記の DDD による分割と同じことだと考えています。

Twelve-Factorのプロセスはステートレスかつシェアードナッシング である。永続化する必要のあるすべてのデータは、ステートフルなバックエンドサービス(典型的にはデータベース)に格納しなければならない。

ここより引用

対してシェアードエブリシングは以下です。

ここより引用

継続的デリバリ

継続的デリバリを実施するには以下の3つを作業の基盤を整備する必要があると述べられています。

  1. 包括的な構成管理(CM : Configuration Management)
    バージョン管理で収集した情報のみを使い、完全に自動化した方法でソフトウェアをビルド/テスト/デプロイできる作業管理を整備する必要がある。作業環境の変更も、その環境で運用しているソフトウェアの変更も、すべてバージョン管理の自動化されたプロセスに従って行うべきである。ただしこれでも手作業で承認する部分が残るが、承認後はどの変更も漏れなく自動的に行うべきである。
  2. 継続的インテグレーション(CI : Continuous Integration)
    ブランチを作って、何日(あるいは何週間)もかけて特定の機能を開発しているチームは多い。こうしたブランチのすべてを統合するには、かなりの時間と修正作業を要する。対照的に、「作業はバッチ処理で進める」と「品質の概念を最初から組み込んでいく」といった継続的デリバリの原則を実践しているハイパフォーマンスチームの場合、ブランチ(分岐したディレクトリ)の「寿命」は常に1日未満で、メインのトランクへの統合を頻繁に行っている。変更を追加するたびに、単体テストの実施も含めたビルドプロセスが発動される。このプロセスのどの部分が失敗しても、開発者は即座に修正を行う。
  3. 継続的テスト
    テストとは、機能の開発やリリースの作業が完了した時点で始めるものではない。
    テストは必要不可欠なものであるから、開発プロセスに必須の構成要素として常時行う必要がある。バージョン管理システムでコミットするたびに単体テストと承認テストが自動的に実行され、変更に関するフィードバックを開発者が迅速に入手できるようにするべである。また、開発者は不具合の優先順位をきめて修正に当たれるよう、自動化されたテストはすべて実行可能にするべきである。テスターは、CI で生じる最新のビルドに対して継続的に探索型テストを行うべきである。関連する自動化テストがすべて作成され、そのすべてに合格しなければ「作業完了」を宣言するべきではない。

至極当たり前のことを言っているように見えますが、バージョン管理で収集した情報のみを使うということろにポイントがあります。

CI/CD のパイプラインを整備すると、バージョン管理システムへのプルリクエストを契機にコードのレビューが走ります。問題ないコードであればマージされます。web-hook によってインスペクション、ビルド、テスト、デプロイ等が自動で走りますが、何か問題があってレビューをすり抜けたとしても、このインスペクションやビルド、テストのいずれかの部分でエラーが発生し、ビルドプロセスは中止されます。

逆を言えば、バージョン管理に保存されているコード、ドキュメントが一番最新情報であるということを意味しています。バージョン管理を通さずに、個別にビルド、デプロイするケースは考えられません。バージョン管理に格納されている情報が構成情報として使える最新の情報となります。つまり Single Source Of Truth と言えます。

アプリケーションだけではなく、Infrastructure As a Code でインフラもコード化されていると、例え日本が明日沈没したとしても、PaaS と IaC を使って環境をすぐに再現することができるでしょう。

変更管理とパフォーマンスの相関関係

本書では変更管理とハイパフォーマーとの相関関係も調査しています。

  1. 本番環境に対する変更につては必ずチーム外の人や組織(管理者や CAB)の承認を得なければならない。
  2. データベースの変更などハイリスクな変更に関してのみ、承認を得なければならない。
  3. 変更の管理はピアレビューだけで済ませている
  4. 変更承認プロセスはない

回答 2 はデリバリのパフォーマンスとの相関関係が見られなかったと記述されています。そして 2 のパフォーマンスを上回っていたのが 3 と 4 の回答をした企業だということでした。

2 を下回っていたのは 1 のチームです。

加えて、1 のチームは「リードタイム」「デプロイ頻度」「サービス復旧までの所要時間」との間に負の相関関係があったことが示されています。

本書では3のピアレビューをおすすめしています。

変更管理は悪者なのか

変更管理が「リードタイム」、「デプロイ頻度」、「サービス復旧までの所要時間」の悪化の要因となっているとは思えません。

個人的には因果関係が逆ではないかと考えています。
ハイパフォーマーは組織やアーキテクチャーが疎結合になっているため、他のチームに頼らずに大規模な変更を自身のチームだけで完結することができます。そのため、ピアレビューのみで済むのです。

逆に、ハイパフォーマーではない組織は組織やアーキテクチャーが疎結合になっていないため、変更にかかる影響範囲が大きくなり、変更に対する承認や CAB を実施せざるを得ない状況になっているのではないかと思います。ファットモデル&モノリスアーキテクチャーだとどう頑張っても変更箇所の抜けが発生してしまいます。

おそらく変更管理を実施している企業のほとんどが以下の図の左になっているのではないかと予想します。

ドメイン駆動設計におけるコンテキスト分割

結論としてはどう頑張っても「リードタイム」、「デプロイ頻度」、「サービス復旧までの時間」と負の相関関係になってしまうのではないでしょうか。なぜなら根本原因を解決していないからです(技術的負債)。

2022/11/15 追記

セキュリティのシフトレフト

セキュリティに関するケイパビリティとデプロイのパフォーマンスの関連は本書ではあまり触れられていません。が、セキュリティのシフトレフトは私も同じ考えなので少し触れておきます。

CI/CD には以下の要素を自動化し、早期に問題点を発見し対処することができるようになります。

  • インスペクション自動化
  • ビルド自動化
  • テスト自動化
  • デプロイ自動化

インスペクション自動化の中ではコードを読み込み脆弱性に対して問題のあるコードかどうかをチェックする仕組みがあります。具体例を出すと Parasoft Jtest や Coverity 等です。

上記は Jtest の製品説明の例ですが、OWASP に対応した検出パターンが記載されています。また ISO26262 等、自動車業界における規制に対する検出も可能な製品があります。

ビルド自動化は Java を使っているケースでは多くの場合 Maven / Gradle 等を使用してビルド自動化しますが、この Maven / Gradle が読み込むビルド情報(pom.xml / build.gradle)にはどのライブラリを使用してアプリケーションをビルドするかの情報がすべて載っています。Log4J なんかもそうです。リリースして使い始めてから検出しました!では遅すぎるのです。CIの段階で検出可能であるため、CI/CD にこうしたセキュリティの仕組みを組み込んでおくべきです。

ドメイン駆動設計を使うとコンテキストごとに API で分離されたサービスができあがります。API を直接テストするための仕組みや、依存する API を模倣してテストを続けるための仕組みも必要になります。これはテスト容易性にも含まれる内容です。

本書の P.77 に「テストダブル(ソフトウェアのテストでテスト対象が依存するコンポーネントを書き換えた代用品)と仮想化により、サービスやコンポーネントを独立した形でテストする」ということが記載されています。

依存する API を模倣してテストを実施できることと同義ですが、具体的には CA Service Virtualization や Parasoft Virtualization といった製品がこれにあたります。テスト対象のサービスをテストするにあたって、そのサービスが依存する API をこれらの製品が模倣してくれるわけです。独立してテストできることを保証するわけです。

API そのものをテストするツールによっては侵入テストを実施できる製品もあります。Go Live する前に一連のセキュリティによるテストは CI/CD の中で実施しておくべきでしょう。

リーン製品開発

リーンによる製品開発についても触れられていましたが、そちらは以下のエントリで言及しているので割愛します。

最後に

QA を担当していた自分としては、読み応えのある本だと感じました。加えてリーン開発における要素が含まれており、最近主張していることも含めてすべて包含している内容になっていたと思います。

ぜひ一読していただきたい本です。

--

--

Kenta Kosugi

Javaアプリケーションサーバーの開発からCORBA製品のサポート、QA、証券外務員(第一種免許)、ストレージ屋、アーキテクト、SaaS屋と一貫性のない道を歩んでいます。Red Hatに復帰しました。