🐳

継続的にライブラリアップデートをする理由とチームでの取り組み方

2021/12/14に公開

つい先日(2021/12/11)、歴史的にみてもトップレベルで深刻な脆弱性が発見されました。
https://www.cyberkendra.com/2021/12/worst-log4j-rce-zeroday-dropped-on.html

自分が所属しているログラスでは同日 13:23 に該当ライブラリのアップデートを対応を終えました。

https://twitter.com/Yuiiitoto/status/1469165714800279553

社内でインシデント起票してから1時間半ほどでの対応でした。

このスピードで対応できたのはひとえに全てのライブラリを ほぼ最新バージョンに保てているからです。
これは日頃のチームの成果であると思っています(もし今回のライブラリに関連するライブラリが古いままならパッチバージョンがうまく動かない可能性があった)。

この記事では改めて、ライブラリアップデートを行う理由と、チームで仕組みとして行っていくtipsを紹介していきます。

なぜ継続的にライブラリアップデートをする必要があるのか?

継続的にライブラリアップデートを行う理由は2つあります。

  1. 迅速に脆弱性に対応するため
  2. ライブラリの新機能を使うため

順に説明していきます。

1. 迅速に脆弱性に対応するため

1つ目は迅速に脆弱性に対応するためです。
これは今回の log4j2 のパターンに合致しますが、何か脆弱性が発表されたときにそのライブラリの依存ライブラリのバージョンが古ければパッチバージョンを当てられない可能性があります。
今回の log4j2 2.15.0 は Javaのバージョンが古ければ動かない可能性があったり、フレームワークのSpring Bootが依存していて、そのバージョンが古くてパッチバージョンが当てられないというような可能性があります。

1日以内の即座に対応が求められる脆弱性が発表されたときに、その修正に言語やフレームワーク自体のバージョンを上げなくてはならないとなったらと思うとゾッとします。

しかしこの事象は今回のlog4j2の脆弱性では実際に起ってしまいました。

このようなことが起きないためにも常に可能な限り(もちろん最新バージョンはバグがあるかもしれないという考慮もあるが)最新バージョンに上げるということをしなければ、最悪サービスを止めるようなことが起きかねません。

2. ライブラリの新機能を使うため

2つ目はライブラリの新機能を使うためです。とてもシンプルな理由です。
例としては React v18 の Concurrent Renderingのような機能です。

https://ja.reactjs.org/docs/concurrent-mode-intro.html

詳細は省きますが、この機能はレンダリングの最適化を行い、画面操作が従来のものと比べて高速になります。
こういったライブラリの新機能は直接何かのビジネス価値につながるわけではないですが、パフォーマンスが良くなったり非機能要件の文脈で貢献する場合が多いです。

単純に新しい機能を使うことは楽しいですし、新しい機能をどんどん使えるという環境は良いエンジニア採用につながる場合もあります。

継続的にライブラリをアップデートするためのTips

銀の弾丸はないですが、3つほどのログラスで行っているTipsをお伝えします。

  1. GitHub Dependabotを入れる
  2. 小さいアップデートは週次に固定の時間をとって潰す
  3. 大きなアップデートはチケットに切り出すか、組織目標に入れる

1. GitHub Dependabotを入れる。

はい、まずはGitHub Dependabotを入れましょう。

https://dev.classmethod.jp/articles/github-dependabot-2021/

Dependabotとはプロジェクトに依存しているライブラリを調べ、新バージョンがあれば自動でPRを作ってくれるGitHubの1機能です。

まずはフロントエンド、バックエンド、Dockerfileなど全てのプロジェクトの設定をしてください。
そうするとPR欄はDependabotのPRで埋まります。通常のPRが埋もれてかなり見にくくなります。溜めるとPR一覧が膨れ上がり、一覧性が下がるのを恐れてエンジニアは主体的にdependabotのPRをテストし、マージしようとします。
CIや言語次第ですが、多くのPRはCIが通ればマージ可能なものが多く、dependabotを入れるだけでかなり多くのライブラリを簡単にアップデートできるチャンスを得ます。

単純に可視化するという用途にも貢献してくれて、今のプロダクトがどれくらい最新のライブラリから乖離しているのかをエンジニア組織全体で共通認識をとることができます。

2. 小さいアップデートは週次に固定の時間をとって潰す

Dependabotでどのライブラリをアップデートすべきか洗い出せたら、次はそのアップデートが小さいか大きいか判断してください。大きい小さいの基準はチームによります。

ログラスでは小さいアップデートは週次で固定の時間をとってチームで潰すということを行っています。

この会が始まると、dependabotが開いたPRを上から人をアサインして、追加対応やテストなどを行ってマージします。

今のログラスでは開発者全員が毎週30分時間をとって行っています。この取り組みは2ヶ月前から始めました。
お恥ずかしながら当時のログラスは最新バージョンとの乖離がかなりありました。
そのため毎週全員という時間が必要でしたが徐々に対応が追いつくようになってきたので、今後は毎週1チーム(複数チームのうちの一部)みたいな感じにしてもいいかなと思っています。

3.大きなアップデートはチケットに切り出すか、組織目標に入れる

上記の週次固定の会でアップデートしきれないものはチケットに切り出すか、組織目標(OKRなど)に入れることをおすすめします。

例えば MySQLのバージョンアップなどは各環境でのバージョンアップやダウンタイムを考慮したリリースリハーサルなど色々なことを考慮しないといけません。とてもではないですが、週次30分で倒せるものではありません。
その場合は、チケットに切り出して通常の開発タスクと同様に対処します。
(※ライブラリアップデートをチケットに切り出すというのは至極当然のことなので、ここでは小さなものはチケットにせずに固定時間でスピーディに対応するということのほうが重要かもしれません)

大きいと言っても1日とかで終わるものは普通のチケットで優先度を調整すればいいですが、数週間準備する必要があるというものは場合によっては組織目標に入れる必要があります。
この場合はプロダクトの戦略レベルで優先度を議論する必要があり、差し込むのはかなりの説明責任を要します。
逆に言うと組織目標に入れなくては行けないレベルまで最新バージョンを乖離させてはいけないということも言えます。

まとめ

ライブラリを継続的にアップデートすることはプロダクト開発においてとても重要です。ログラスのチームもこの2ヶ月で大分ライブラリアップデートが板についてきました。

なぜ重要かというと、脆弱性対応のためと新機能利用のためです。

また、継続的にライブラリをアップデートするためには、dependabotを入れまずは可視化すること、大小判断して大きさにあった対処をすることが大事です。

何よりも 重要なことはライブラリアップデートの大事さを組織全体で合意し、最新バージョンから離されないように継続的に細かくアップデート処理をすることです。

We Are Hiring!

ログラスも道半ばですが、品質高く開発をしたい方ぜひご応募ください!!!

https://job.loglass.jp/

Discussion