開発の現場で働いていると、お客様からの要望をどれだけ早く安全にシステムに反映させるかが重要になってきます。ここで重要になってくるのがDevOpsの概念ですが、この考え方はシステム開発のみだけでなく何かを生産するという工程を挟む仕事をしている以上、避けては通れない道だと考えます。私自身、IT業界以外で印刷物や雑貨の生産工程を管理してきた経験がありますので、そういった点も踏まえながら改めてDevOpsについて整理してみました。あくまで概念についての考察なので、細かい技術的なことは今回解説していません。
DevOpsの目的
- 顧客 → 開発 → 運用 → 顧客 のワークフローを高速にして製品の価値を向上させる
- ワークフローを自動化し属人性を排除することでコストを削減する
変化が早い世の中で顧客の製品に対する要望もどんどん変化していきます。その流れに合わせるために、顧客から要望があった瞬間から機能としてシステムに反映されるまでのリードタイムの短縮が重要になってきます。しかし、新しい機能を追加するためには当然コードを変更する必要があり、意図せぬバグが混入することによりシステムの安定稼働を妨げるリスクが高まります。DevOpsに求められていることは、単に新機能を高速で追加することだけではなく、品質を担保する仕組みも重要になってきます。
システムにおいて新しい機能を追加するということは、小売店において新商品を導入することに似ています。新商品を開発するということは、その製品に対するノウハウがない状態のため市場導入後は当然不良率は既存品に比べて上昇します。しかし、生産の自動化、検品・梱包ルールの徹底がされている工場では生産リードタイムも短く、かつ不良率も低く抑えられていました。雑貨などのモノの生産は手作業の割合が高く作業員のスキルによるムラが生じる可能性がありますが、システムの場合は自動化による恩恵を受けることが容易なため冪等性を高く保つことが可能になります。DevOpsワークフローにより製品の品質向上のサイクルを加速させるのは、今後必要不可欠になると考えられます。
DevOpsのメリット
- コード変更によるデプロイ回数が上昇する(スループットが上がる)
- 顧客要望から機能リリースまでのリードタイムが短縮する
- 既存の機能の動作が自動テストにより担保できているため、技術負債になりそうなコードを適宜改修できる
- もしリリース後に不具合が生じた場合もすぐにロールバックができる
- トラブルに対する対応で精神的にすり減ったり、時間を無駄にしたりしなくて済む
- マニュアルテストによる人為的なミス、繰り返し作業による時間の浪費から開放される
- リスクテイクと実験がしやすくなり他社よりも尖った企画や新技術の導入が容易になる
DevOpsへの基本施策
ボトルネックの洗い出し、ボトルネックの処理速度を最大限まで上げる
ボトルネックの処理速度がスループットの速度を決めます。ボトルネック以外の処理以外はいくら早い段階で処理が終わったとしても、ボトルネックを通過しないと次の工程へ進めないため、滞留してしまいます。滞留されたタスクがたまると結果的にどのタスクが優先されるべきか、煩雑になるうえ管理コストがかかってしまって結果的に効率が下がってしまいます。
製造業全てで言えることですが、仕掛品(在庫)である以上何も利益を生み出さない上、在庫保管に対するコストも必要なため、極論在庫はゼロが最も望ましい状態と言えます。
仕事のバッチサイズを小さくする
タスクの粒度は細かくすることも早いフローを生み出すために必要なことです。また、不良や手順に間違いが発見された場合も大バッチでタスクを行っていた場合大きな手戻りまたは製品の大量破棄に繋がります。小バッチ(シングルピースフロー)で行っていれば、製品完成までのサイクルを全て一気通貫で行うため、仕掛りの状態でいる状態が短くて済みかつ間違いを発見した場合でも最小限の手戻りで済みます。
ムダと苦痛の排除
顧客の必要としていない機能の実装、部分的にしか完成していない機能が放置されている。このような事象のように利益に結びつかない実装はムダとして排除されるべきです。また、人による手作業は再現性が低く、作業者にかかる負担も大きいため極力自動化されるべきです。
密結合を避け疎結合な仕組みを構築する
機能を一部修正しただけで、システム全体に影響を与えてしまうようなシステムは良くありません。全ての機能が一枚岩の上に実装されているシステムは、新しい機能を実装する度に構造は複雑化しテストを行いにくく見通しの悪いシステムになります。今トレンドになっているマイクロサービスアーキテクチャを使えば、軽量APIで各機能を結びつけているため、新機能実装による影響は少なく済み、コード量は少なく見通しの良いシステムを構築することができます。
システム開発におけるDevOpsの施策
開発環境の整備
Linterやformatter、styleguideなどでコード規約を作っておくと、チーム全体でそのルールに準じたコードを書けるため開発効率が上がります。コード規約はドキュメントに記載して読み込むなどの作業をしなくても、ルールを記載したファイルを用意しておいてIDEで保存時に自動補正やエラーアラートが出る設定にしておけば個々人による誤解や規約違反なども防ぐことができます。
また、開発言語選定時に型付言語を選択しておくと、データベースに不正な型が渡ってしまったり、思わぬところでnullが混入してしまったりといったバグを防ぎ安全に開発を進めることができます。
開発環境・本番環境のプロビジョニング
以前は環境構築といえば、手作業でapache、php、mysql入れてみたいなのが当たり前でしたが、やはり手作業は時間がかかる上人為的エラーが発生する可能性が高いため現在はインフラ構築は全てコードで記載するのが一般的になっています。Dockerでコンテナ環境を自動で作るにしても、サーバを立てて構成管理をChef、Ansibleで行うでもどちらでも構いませんが、ボタン一発で環境構築でき、ボタン一発で環境をクリアできるという状況を作っておくのが一番ベストな方法です。
継続的インテグレーション(CI)
私はDevOpsを実施する上で一番重要なのが自動テストだと考えています。全ての機能を担保できるテストが存在すれば、安心して新機能の実装や技術負債の返済を実施することができるからです。テストには単体テスト、結合テスト(細かく分ければUIテストやビジネスロジックテスト・API通信テスト)など多岐に渡りますが、これらのテストは極力手作業で行うのではなく自動化し、DevOpsのフローの中に取り込んでしまうのがベストです。1機能追加するたびにその機能に対する、自動テストコードを書くということを続けていれば、その機能に変更が生じた際も、全てのテストを再度手作業で行うといったムダは生じず変更箇所のみテストあとは自動テストに任せるといったことが可能になります。
継続的デリバリー(CD)
環境のプロビジョニング、システムのビルド、自動テストの実行、デプロイまでの工程を自動で行うことです。もちろん全て自動進行してしまうのではなく、要所で人の承認を入れたりといったことも可能です。コンピュータ内で行う手作業は全てコード化することができるはずなので、うまくフローを組み上げれば、ボタン一発で安全なコードを安全にデプロイすることが可能になります。Jenkins、CircleCI、GithubActionsなどのツールを使えば、フローを構築することができす。手作業・目視によるメリットはゼロですので、極限まで自動化するのが一番ベストだと私は考えます。
コメント