【保存版】4年間現場で培ったプロダクト開発を支えるエンジニアリング
何を何のために書くのか
プロダクト開発を行うエンジニアチームが、 どんなことを目標にして、 どんな環境を作っていくのかを、 4年間プロダクト開発を行ってきた自分の集大成として一度言語化してまとめたい。 自分が関わった現場では何のためにどんなことが行われていたかの全体感をまとめ、 今後参画する現場の課題の検知、優先度付け、行動指針をぶれないようにする目的でブログ記事化する。 あくまでも全体感を把握するためなので個々について細かく詳細は記述しない。
アジェンダ
- プロダクト開発を行うエンジニアとは?
- プロダクト開発を行うエンジニアチームの存在意義
- プロダクト開発を行うエンジニアチームの存在意義と目指す方向
- フロー上のムダをなくすための環境作り
- 安定してサービス提供するための環境作り
プロダクト開発を行うエンジニアチームとは
ビジネス上の目標を持ち、 世の中になんらかの価値を提供するプロダクトを開発、運用するエンジニアチームを指すこととする。
プロダクト開発を行うエンジニアチームの存在意義と目指す方向
では、エンジニアチームが持つべきミッションは何になるのか? 結論だけ先にいうと下記の2つになる。
- 企画~リリースまでのフロー上のムダをなくしていくこと
- SLA/OLAにコミットし、安定してサービスを提供し続けること
どういうことか? プロダクトの最終ゴールはお金を生み出すことである。 つまり、お金を生み出すまでのフローのムダを解消し、安定して開発、運用することがコアなミッションになる。
企画からリリースまでには、
- 仮説立て
- 企画
- 要件定義
- 設計
- 実装
- テスト
- リリース
- 効果検証
といった工程が存在する。 このフロー上のムダを解消することで、 仮説立て ~ 効果検証までのサイクルを最速にし、 強いプロダクトを生み出すための環境を作ることができる。 そしてこのフロー上のムダは、
- フローのどこかにムダがあるケース
- フローの外部の要因によってフローの進行が妨げられるケース
の2つのパターンがある。 前者は言うまでも無いが、後者については、 例えば障害対応、ユーザからの問い合わせの対応などにあたる。 障害やユーザからの問い合わせが発生すれば価値を生むための開発に充てるための工数が減っていく。 つまり生み出した欠陥によってお金を産まないムダなことをしなくてはならない。 また、障害の内容によっては(個人情報の流出など)サービスの存続すら危うくなってしまう。
だからこそ、
- SLA/OLAにコミットし、安定してサービスを提供し続けること
はとても重要になってくる。
フロー上のムダをなくすための環境作り
ドキュメント整備
開発をしていて得られた技術的な知見、 チーム内で決まった意思決定の議事録、 環境構築の手順、 システム構成図などはチームメンバー間で何度も参照され得るような再現性の高い内容である。 こうした内容を簡単に検索、参照できるように整理しておくことで、 新しいメンバーが入ってきたときにもすぐキャッチアップして立ち上げられ、 一度やった内容なのに資料がないため再調査、といったようなムダを省き、 タスクの属人化の問題を防ぐことができる。 なんでもかんでもドキュメント化しておけばいいわけではないが、 チームで育てた知見を明文化することはとても大切である。
テストコード
ビジネスの状況はどんどん変遷していくので、プロダクトも常にそこに追随していく必要がある。 テストコードがなければ、 EOLになったライブラリのアップデートさえ上げることに苦労し、 リファクタリングが容易にできず、 改修、拡張の結果デグレがおこったとしても人手以外で検知する術がない。 つまり変更が容易にできない。 テストコードを書かないことによって目先の工数は減らせるが、 その後長期に渡って必要のないムダを生みだすことになる。 一回だけ書いて一切拡張、修正せずに運用するソフトウェア以外についてはテストコードは書くべきである。
各種テストの自動化
単体テスト以外にも、プロダクトならではで手間がかかっているテストがあるはずだ。 たとえば課金の仕組みを持つプロダクトで、課金部分は求められるサービスレベルが高いのでいつも厚めにテストをする、 といったことや、会員制のサービスでテスト用のアカウントを毎回人手で作っていて時間がかかっている、などだ。 こういったところの一部でも自動化することができれば、長期にわたる人件費やテスト工数の削減につなげることができる。
継続的インテグレーション
PullRequestを出した時点でビルドし、テストを実行するのはもうどこの現場でもやられているはずだ。 これによってmasterやdevelopなどのメインブランチにビルドが通らなかったりテストが通らないコードを混入させて チームメンバーの作業をブロッキングすることを回避し、バグの混入を早急に検知して手戻りを防ぐことができる。 またCIに静的解析などを含めることで、バグや障害のリスク回避はもちろんPullRequestのレビュワーの負担を軽減することもできる。
継続的デリバリー
PullRequestが通り、develop、masterにマージされたタイミングで(もしくはPullRequestの時点で)ステージングや開発環境に自動的にデプロイすることで、サーバとフロントの結合や、見た目の部分をいち早く確認することができる。 また、常に最新の開発状態のものを確認することができる。 これによって、デプロイ自体の属人化回避や工数削減はもちろん、すぐに確認できることによってバグやあとの工程での手戻りなどを防ぐこともできる。
データ分析基盤
より良いプロダクトを作っていくためには、 仮説を立て、リリースし、フィードバックを得て学びを得て次の仮説を立てる、 といったサイクルを良質に回していく必要がある。 ここがうまく機能しないと、 ユーザに使われないものを多くの金と工数をかけて世に生みだすことになってしまう。 そのためには、
- 各施策で効果振り返りを適切に行えること
- ユーザの傾向分析などを通して新たなニーズの仮説打ち出しができること
が求められる。 1. どんなデータ、ログがあれば適切な効果測定、適切な傾向分析ができるかの要件出し 2. 要件から実際にログ収集、分析のための仕組みづくり を行うことが求められる。
進捗の可視化
進捗管理はとても重要だ。 見えないことによってリリース日までにどのくらいできて、どれをスコープから外すか、といったような判断ができない。 また、見えないとそもそも何に時間がかかっているのか?といった問題が表面に出てこない。
優先順位の可視化
すべて最優先で、というのはすべて優先度低と言っているのと全く同じだ。 リリースしたい機能、タスクの優先度が見える化された状態で直列に並んでいて、 かつ合意が取られていることで納得して開発でき、柔軟なスコープ調整や、技術都合で必須なものの調整(EOL対応など)が健全にできる。
開発プロセスの整備
開発フローの整備
- Gitのブランチ運用ルールの整備や、障害発生時のエスカレーション、対応ルール、開発とテストの工程定義などはチーム内で明文化しておく必要がある。
- これによってフロー上の品質のブレや、いざというときの対応でもたついて対応がスムーズにいかない、といったことを防ぐことができる。
カイゼンのためのチームづくり
安定してサービスを提供し続ける環境作り
静的解析 & 脆弱性チェック & ライブラリEOLチェック
欠陥を未然に防ぐことはとても重要で、これによって最悪サービス提供ができなくなることもある。 また、ライブラリEOLが原因でアプリストア上で公開できなくなったり、障害の発生によって開発フローを妨げられたりする。 脆弱性をついた襲撃を受けたり、個人情報漏洩などのリスクが発生することもある。 よって、常日頃からコードの品質、ライブラリのバージョン、脆弱性についてはチェックしておく必要がある。
クラッシュログモニタリング
Firebase/Crashlyticsなどのアプリのクラッシュログを収集するSDKを入れ、 定常的にモニタリングすることでテストではきがつけなかったバグの混入などを検知する。
サーバ監視&アプリケーションモニタリング
サーバダウンや、リソース使用状況、エラーログや、APIのレスポンスタイムなどを計測することで、 障害の検知や、障害時の原因特定を行うことができる。 またプロダクトの宣伝を大々的にしたときにインフラが耐えられるかや、ユーザ増加にどこまで対応できるかの分析を行い、 インフラ増強や構成の改善に役立てる。
リリースエンジニアリング
大規模な変更などのリスクのあるリリースでも、 安全にリリースを行う仕組みを活用すれば障害時の影響を最小にすることができる。 また、実験的に一部のユーザにだけ機能を見せてフィードバックを得てから本格的に開発を進めるなど、 MVP検証的なことが可能になる。
具体的には下記のような手法がある。
- 段階的リリースで一部のユーザにのみリリースしてフィードバックを得る
- 機能をダークローンチして、実際にユーザに使わせる前に本番環境で内部検証する
- 時限式リリースで、指定した時刻になってはじめて自動的にユーザに見えるようにする 例: 何周年キャンペーンとか
- Feature Toggleを活用してリリース無しで挙動を変える
- タスクキューやメール配信などの流量をリリース無しで動的に制御
- リスクのある機能をToggleでON/OFFできるようにしておき、問題を検知したらすぐOFFにする
まとめ
プロダクト開発におけるエンジニアチームはプロダクトが安定して利益を生み出す仕組みをエンジニアリングすることに責務を持つ。 そのためにムダを省き、安全に安定してサービスを提供する。 ここがブレなければ独りよがりではなく、うまく技術を利用していけるはず。