🏭

持続的な運用を支える組織を運営するために少しだけ考えておきたいこと

2024/12/13に公開

はじめに

この記事はドワンゴ Advent Calendar 2024の13日目の記事です。
昨日は@tenax66さんの「Rustとクトゥルフ神話」でした。

ごあいさつ

ドワンゴでニコニコ生放送の開発・運用を担当している @cornet_higashi です。

寒くなってきましたねと書こうとしたのですがまだ割と暖かいですね。120年あまりで最も暖かい秋だそうですと言いつつのんびり記事を書いてたらだいぶ寒くなってきました。冬ですね。

昨年のアドベントカレンダーでは ニコ生の開発環境が不足しがちなのでKubernetes/IstioとChrome機能拡張を使ってスケールするようにしてみた話 という記事を書かせて頂きました。

https://zenn.dev/cornet_higashi/articles/scale-development-environment

弊社で開発・運用を行っているニコニコ生放送サービスはKubernetes(k8s)でクラスタ管理を行なっています。開発時の動作検証用に使用している環境が色々な案件で取り合いっこになって不足しがちなので、サービスメッシュとChrome機能拡張の合わせ技でスケールするような運用を可能にしたというお話です。


今回のテーマはシステム開発の現場において持続的な運用を行える、そんな組織を運営するにあたってどういったことを考えておきたいか。そのような内容になります。

信頼性や保守性などシステムそのものの品質を高めていくことはもちろん重要ですが、そのようなシステムを維持するにあたってどのように運用していけば良いかという点は考慮から漏れてしまうことも多いかと思います。いくらシステム自体の品質が高かったとしても、その運用が立ち行かなくなってしまっては意味がありません。
また、運用を行うための組織を運営するためにも様々な点で注意しなければなりません。自動化を進めたりルールやレギュレーションを定めたとしても最終的に運用を管理するのは人ですので、所属しているメンバーが運用を持続的に回していけるようにするためにはどうすれば良いかという点にも注意を払う必要があります。
本記事では、そのようなテーマについて筆者の所属する組織や環境を前提として書かせて頂きました。

下記注意事項です

  • 持続的な運用を行うための要素として、コードやアーキテクチャ面でどのように保守性の高いシステムを構築するかといった観点もありますが、今回はそのあたりの内容は薄めです
    • どちらかと言うと運用や運営自体をどうしていくかという話ですのでご注意ください
  • どこの現場でも当てはまる話というよりは筆者の所属する開発組織や環境(自社開発)を前提とした話です
    • 紹介されている内容は実際の事例とは限りません
    • 読者の環境と色々と前提が違ってくる箇所もあるかと思いますので、こういう現場もあるんだぐらいの気持ちでお読みください
  • 成功事例やベストプラクティスをまとめた記事ではありません
    • これをやれば必ず問題が解決する、という類の内容ではありません
    • 多分にお気持ちを含みます

今回も少々(少々?)長くなりますが、どうか最後までお付き合い頂けると幸いです。

対象として想定している読者

本記事の想定読者は以下に当てはまるような方となっております。

  • 自社開発しているシステムに携わっており、開発から保守・運用まで担当している
  • 長期間に渡って新規開発や保守・運用が必要なシステムに携わっている
  • システムだけでなく運用の品質を持続的に維持・改善していきたい

本記事の構成

本記事は以下のような構成になっています。全部読むとそこそこ時間もかかりますので、興味がある部分だけ摘読していただく形でも問題ありません。

それでは本題に入っていきます。

背景

我々が携わっているシステム開発の現場では、新しいシステムや機能の開発、すでにリリースを終えて稼働中のシステムの保守・運用などが日々行われています。
日々の業務においてはシステム自体の構築や実装だけでなく、ドキュメントの管理やプロジェクトにおけるステークホルダーとのやり取りなども含まれます。

開発したシステムは一度作ったら終わりではなく、その後も正常に稼働し続けられるように持続的に保守・運用を続けなければなりません。また、組織の目的を実現するよう価値を提供し続けるため、定められた指標に従って品質の維持や改善を行っていくことも重要になってきます。

これらの対応を行うにあたっては、様々な資産や開発リソースを活用して効率的に開発を進めていかなければなりません。時には組織の内外との折衝を重ねつつ、目的を遂行していくことが必要となります。

ここで、持続的な運用とは何なのかについて考えてみます。

持続的な運用について

まず、運用するとはどういうことなのか考えてみたいと思います。
運用の定義は「モノの機能を生かして、うまく用いること」です。システム開発における運用業務として定義されているものにはシステム運用業務運用があります。(運用業務には他にもヘルプデスクや運用統制などもありますが、ここでは触れません)

https://un4navi.com/management/19046/

システム運用の定義は「コンピューターシステムやソフトウェアを正常に機能させるための管理業務」となります。管理業務には以下のようなものが含まれ、システムが正常に動作し続けていることを保証できるようにするための作業を意味します。

  • サーバ・ネットワーク監視
  • メンテナンス
  • セキュリティ対策
  • 不具合・インシデント対応

また、運用はシステムだけでなく業務の運用についても存在します。これを業務運用と呼びます。定義としては「ビジネスや業務に関係する部分の運用」となり、以下のようなものが含まれます(分類については組織によって若干の違いはあると思います)。

  • 運用スケジュールの調整
  • 各種データ管理
  • ドキュメント・マニュアル作成
  • 権限管理

一般的な定義で言う運用業務は上記の通りですが、筆者の所属している組織についてもう少し具体的に言うと下記のような業務が挙げられます。

  • システム運用
    • 監視対象のメトリクスやアラートの整備
      • datadogやCloudWatchなど
    • インフラ関連の設定変更
      • AWSやkubernetesの各種リソース設定など
    • プラットフォームやランタイム・依存パッケージのアップデート
      • kubernetes/node.js/npm package
    • インシデント対応後の根本対応検討
      • システムの構造上の問題の解決やレギュレーション制定など
    • 開発環境・フロー改善
      • 開発環境更新の簡略化や自動化
    • システムやツールのリファクタリング・リアーキテクチャ
      • ディレクトリ構成の整理やフレームワークの刷新
  • 業務運用
    • イベントに向けのスケジュールの調整や関係者との調整
      • 関連スケジュールの突き合わせや依頼など
    • ドキュメントの整備・更新
      • ドキュメントの構成変更、古くなった内容の更新
    • 各種権限の棚卸し
      • 各種製品・ツールのアカウントに紐づく権限整理
    • 情報共有・管理体制の整備
      • 外部動向や知見の共有、公開範囲の統制など

では、持続的な運用が行えているとはどのような状態を指すのでしょうか?
システムが稼働を開始した時の状態がそのまま持続していればそれで良しとすべきかというと、それだけでは十分ではありません。時間の経過や組織の変遷によって必要なもの、求められる品質や特性は変わってくるからです。

この持続的な運用というものの定義の仕方については色々な考え方があると思いますが、本記事では以下の状態と定義します。

  • 時間が経過してもシステムや業務が組織の目的を満たせるように利用可能な状態を持続しており、品質を維持・改善できている
  • 組織や人員の構成が変わったりスケールしたとしても、それに合わせて運用が維持できている

時間が経過してもシステムや業務が組織の目的を満たせるように利用可能な状態を持続しており、品質を維持・改善できている

対象とするサービスやシステムの特性にもよりますが、時限的に公開されるものや季節・イベント限定のシステムなどを除いては長期的に稼働を続けていくことを考えていかなければなりません。場合によっては、組織やサービスが存続している限り半永久的に提供及び利用され続けるものもあるでしょう。

システムが実現すべき目的や求められるものがずっと変わらないとは限りません。時には信頼性の向上が求められるでしょうし、時にはコストを大幅に削減することが求められる場合もあります。目的に対し、やるべきことをアップデートし続ける必要があります。

また、ただシステムが利用し続けられるだけではなく品質の維持・改善が行えるようにしていかなければなりません。利用側の満足度が低下することで組織の目的を満たせなくなったり、余計にコストが発生する結果になる場合もあります。

組織や人員の構成が変わったりスケールしたとしても、それに合わせて運用が維持できている

(まず無いと思いますが全てが自動化されているような場合は除くとして)システムを最終的に管理しているのはその組織と所属している人間です。そして、開発組織を運営していく中で組織の構成は変わっていきます。新しく入ってくる人もいれば、ライフステージの変化に伴って一時的に離脱したりするケースもあるでしょう。

サービスやシステムを管理する立場の組織としては、そういった場合にも対象となるサービスやシステムが怠りなく運用を続けられることを保証し、そのために何をしなければいけないのかという観点を持っておく必要があります。

また、システムや事業の規模がスケールしたりした際に、運用自体もそれに追従させていく必要があります。少ない規模では成り立っていた運用が、事業規模やそれを扱う人が増えた途端に成り立たなくなってしまうことも十分考えられるからです。

運用における課題

上述したような持続的な運用を行う組織を運営していくにあたり、様々な課題や障壁が存在します。持続性というものが指す対象や意味合いも幅広く、どのような課題を抱えているのかは組織構造やシステムの特性によっても全く変わってきますが、ここでは以下の内容について取り上げるものとします。

  • 運用を持続すること自体の難しさ
  • 属人化していく運用
  • ドキュメントの鮮度の低下
  • 保守が後回しにされるシステム
  • 運用に回すリソースの不足

運用を持続させること自体の難しさ

突然ですが、皆さん筋トレはやっていますか?
自分ですか?最後にやったのは1年ぐらい前でしょうか...(嘘言いました多分もっと前です)

筋トレは持続させるのが難しいものの例としてよく取り上げられますが、その理由は何でしょうか。

  • 持続する確実なメリットが見込めない
    • 筋トレをやれば必ず痩せる、筋肉が付くとは限らない
    • どれぐらいやれば効果が出るかも人によって違う
  • 持続するモチベーションがない
    • 明確に目標があるわけでもない
    • 特段筋トレ自体が好きなわけでもない

そろそろ何の話だと言われそうなので、筋トレの話から離れて本題に戻りましょう。
筋トレと運用業務を一緒にするわけではありませんが、持続性の阻害要因として共通している下記の2点について見ていきます。

運用を持続する確実なメリットが見込めない

我々が日々行っている業務にはやることが決まっている業務もあれば、やるかどうかはコストやメリット次第といったものがあります。特に運用業務においてはどこまでやるべきかという判断が難しい場面も多いかと思います。
運用業務によって得られるメリットとしては下記のようなものが挙げられます。

  • コストの削減
  • 可用性や信頼性の向上
  • 作業効率の向上
  • リスクの低減

ただ、こういったメリットについて確実に定量的な向上が見込める場合というのは限られていたりします。結果が出るまでにそれなりの時間を要するものも少なくありません。そのような状況では運用を実施したり持続することに対するメリットが見出だせず、優先度を下げたり運用を途中で止めたりという判断になってしまうこともあるかと思います(これ自体は合理的な判断を含む場合もあるので、一概に良い悪いと言えるものではありません)。

取り組むべきタスクとしてTODOリストに積んではあり、できれば着手したいものの他に優先すべきタスクがあるために手が付けられていない、途中で運用を止めざるを得ない、そういったものは皆さんの手元にもあるのではないでしょうか。

運用を持続するモチベーションがない

開発リソースは有限です。ただし組織としてやるべきこと・やりたいことはいくらでも存在します。優先度の高いタスクや割り込みタスクも発生します。そういった状況下で、コストをかけてまで運用を持続させるのが難しいという状況もあるかと思います。

最低限の運用が回っていれば、+αで改善していこうというアクションに繋げるには、先述したメリットあるいは大きなモチベーションが必要になってきます。

ちなみにモチベーションには内発的モチベーション外発的モチベーションがあります。
前者は目標ややりがい、後者は報酬や罰則などが該当し、前者の方が持続しやすいという特徴があります。

https://heisei-ikai.or.jp/column/motivation/

属人化していく運用

持続的な運用を阻害してしまう要素として、まず考えられるのが属人化です。
属人化とは、「特定の業務や作業が特定の担当者や人材に過度に依存して行われている状態」を指します

https://www.nec-solutioninnovators.co.jp/sp/contents/column/20221021_individual-dependence.html

この属人化が進んでしまうと、「ある特定のメンバーや組織の元でしか運用が続けられない」という状態を引き起こします。作業の非効率化を生むばかりか、特定のメンバーが対象の業務を一時的に離脱したタイミングで運用自体が立ち行かなくなるリスクもあります。他にも、規模のスケールを阻害してしまうという問題もあります。

また、表面上は運用が回っているように見えても、ある個人に負担が集中していないか気を払っておく必要があります。自分しかできないから休みたくても休めない、巷ではよく聞く話ですがそんな状況は絶対に避けたいものです。

属人化が生まれてしまう原因はいくつかありますが、下記のようなものが挙げられます。

  1. 業務の専門性が高い
  2. 職務分掌が正しく行われていない
  3. 標準化されていない

業務の専門性が高い
文字通り専門性が高く、一部のメンバーにしか遂行できない、あるいは他のメンバーでも出来るようにしようとすると多大な学習コストを払うことになるという場合です。専門性が高いこと自体は問題ではありませんし色々なメリットもありますが、あまりにもメンバー間で格差があったり業務やサービスがそれに依存していると大きなリスクになり得ます。

当然ですが学ぶ側の学習コストだけでなく、伝達する側にもドキュメントを用意する、周知するための場を用意するなどのコストが発生します。そして、優先すべきことが日々積み重なっていく我々の日常では優先度が上がりづらいという問題もあります。

しかし、これらのナレッジストアを管理し、その構造に関するガイドラインを設定することは、明示的な注意を必要とする問題です。ドキュメントの作成や知識の伝達は、誰もが日常業務の中で行うことが期待されるタスクですが、実際には明確な指示と優先順位付けがなければ、チームがエンジニアに課すほかの要求に負けてしまいます。

Jeffery D. Smith . システム運用アンチパターン . p.246

職務分掌が正しく行われていない
特定の人員に業務や権限が集中してしまっている状態を指します。適切に権限が分けられた上で集中している場合はまだしも、棚卸しが行われていない結果として属人化が発生している場合、不要に業務の効率性や柔軟性の低下を招いてしまいます。

標準化されていない
独自のアーキテクチャや技術・知識に基づいたプロダクトや運用となっており、特定のメンバーにしか変更したり運用を行えない場合です。秘伝のタレと呼んでます

またこれは一般的な話ですが、業務の囲い込みによって属人化が進むというケースもよく聞かれます。「自分にしかできない」状態を盾にして評価や立場を維持し続けているというような話です。

属人化が発生する場所

属人化が発生しうる場所については、以下のようなものが考えられます。

  • 知識・知見
  • 考え方
  • スキル
  • 権限
  • ホスピタリティ

知識の属人化を防ぐためにドキュメント化して他者に共有するというのはよくあるアプローチですが、単に結果の情報を共有するだけではどのような考えに基づいたものなのかが伝わらず、結果として応用が効かなくなったり被共有者の学習に貢献できなくなってしまうといった懸念があります。
権限なども適切に棚卸しされていなければ、無用に特定の人員のみでしか業務が行えないという状況を生んでしまい、作業効率の低下を招きます。

そしてある意味一番厄介なのが、ホスピタリティにおける属人化です。

縁の下の力持ち

数年前、Twitter(現: X)でこんなツイートがバズりました。

「ごん、お前だったのか。いつも社内サーバーのメンテをしてくれていたのは」  
 
派遣切りされたごんの座っていた机には、もう誰もいません。  
 
エラー音とともに社内サーバーは停止しました。

— あぎ㌧【令和最新版】(@ttn_agiton) September 1, 2021

このツイートを見てどのような感情が頭を過ったでしょうか。笑っていられる方は幸せではないでしょうか。色々思い出して頭が痛くなった方もいるかも知れません。

おそらくはどこの企業、どこの組織にもある話だと思いますが、誰もあまり気にかけていなかったが実はこの人がやってくれていたんだ、という業務が(たぶんほぼ確実に)存在します。

具体的なものとしては、社内向けのドキュメントの整備、依存パッケージのマイグレーション、不要リソースの削減やコードのリファクタリング。情報共有や啓蒙活動。挙げればキリがありません。

そしてこのような仕事は職務分掌によってではなく、個人のホスピタリティによって支えられがちだったりします。こういった部分の属人化はなかなかに排除しにくいものです。

組織のインタフェース

ここで言うインタフェースとは、組織において他者からの相談や質問を受け付ける窓口など外部との接点の意味で使っています。
これが属人化するとはどのようなことでしょうか。

  • 担当者によって品質が変わる
    • 返答までの時間、判断基準など
  • 担当者によって異なる情報や対応を求められる
    • 問い合わせにあたって提供すべき情報など

あまり気に留めないことが多いと思いますが、このインタフェース部分に何か変更があった場合(多くは人員配置の変更など)に運用が従来通り円滑に進まなくなっていくケースもあります。「以前は何も説明しなくても話が通じた」「応答時間が長くなった」みたいな状態が生じてしまうと、自分たちだけでなく関係するステークホルダー全体を含めた作業効率を低下させかねません。
こうした要素も、部分的にホスピタリティに依存しているところがあります。

ドキュメントの鮮度の低下

突然物騒な物言いですが、ドキュメントは生モノです。油断すると腐ります。

ドキュメントとは、下記のような情報が記載されているものを指します。

  • 各種手順書
  • 知識・知見
  • サービス・システムの仕様

古くなってしまったドキュメントを信じて作業を進め、終わる頃に「あれ、これもしかして情報古いんじゃ...」みたいな経験をお持ちの方も中にはいらっしゃるのではないでしょうか。気付けるうちはまだ良いですが、正しい情報と古い情報が混在してしまっており、何を信用してよいか分からなくなりドキュメント丸々書き直さなければならなくなるケースもあるでしょう。

ドキュメントが腐る原因もいくつか考えられますが、よくあるケースとしては以下のようなものが挙げられます。

正しい状態を担保するのが難しい

実際に本番環境で稼働しているシステムの場合はコードを見れば正しい挙動が分かりますが、ドキュメントの場合はそうはいきません。ドキュメント間で整合性が取れてなくても誰も気付きません。その一方で、「正しいことが書かれている」というお墨付きを持っているかのように認識されがちなので、たちが悪いとも言えます。

そして、そのドキュメントが正しい内容なのか間違っているのか、今はどういった内容に変えるべきなのか、知っている人はもういないというパターンもあると思います。一つ前のセクションで述べた属人性による弊害が起きているパターンですね。

ドキュメントが多すぎる

冷蔵庫も冷凍庫もドキュメントも同じですが、中に入っているものの数が多くなってくると管理しきれなくなってきます。ひっそりと奥で腐っていても気付きません。
また、食材と違ってドキュメントは無くなっていきません。基本増えていく一方です。また、レビューが必要なコードと違って、気軽に追加できるドキュメントはその数が増えやすい傾向にあります。

ドキュメントを捨てられるのは、「その情報が未来永劫使われないことが確定した場合」です。が、そのような条件に合致するタイミングはなかなか遭遇できないものです。
また、古くなったドキュメントは検索のノイズになるという問題も引き起こします(Grepabilityの低下)。

保守コストが嵩んでいくシステムたち

所属している組織で管理している開発資産について、正しく把握できているでしょうか?
開発が頻繁に行われており毎週のようにデリバリーを実施しているプロダクトもあれば、数ヶ月リリースを行っていないプロダクト、過去に作られたスクリプトなど色々なものがあるでしょう。
その中で、持続的に利用可能であるもの、正しくアップデートが行われているものはどの程度の割合で存在するでしょうか?

外部のライブラリを読み込んで成果物を生成しているようなプロダクトの場合、ランタイムや依存ライブラリのアップデートなどを適宜行っていかなければなりません。また、これらは年月を重ねるごとにどんどん増えていきます。

管理するものを減らしていければ良いのですが、ドキュメントに同じくシステムやツールが確実に使われなくなると判断するのはなかなか難しいものです。管理しなければならない対象が増えていくことで、セキュリティアップデートをはじめとして各種アップデートやマイグレーション作業のコストがどんどん嵩んでいきます。依存関係もより複雑になっていき、コストだけでなく開発上の様々なリスクが発生する懸念もあります。

運用に回すリソースの不足

様々な課題がある一方で、それらを全て解決できるかというと大体の場合はそうではありません。
何かをするには開発リソースが必要です。そして何度か書いていますが、開発リソースは有限です。基本はやりたいことに対して不足しがちです。運用するものが増えていけばその分だけコストは嵩んでいきますし、認知不可も高くなっていきます。
何にどれだけのリソースを割くかという判断もどんどん難易度が上がっていきます。

持続的な運用を行っていくためのアプローチ

ここまでに挙げた問題はあくまでも一例に過ぎません。
異なる種別の開発の現場ではまた別の課題があるでしょう。内容も千差万別だと思います。

このセクションでは、持続的な運用を行っていくために上述した課題にどのようなアプローチで対策していくことができるか考えていきます。ただ注意してほしいのは、紹介しているアプローチはいずれも銀の弾丸ではないということです。課題に対して一対一で対応しているわけでもありません。実際には複数のアプローチを駆使して課題を解決できるかどうか試行錯誤を繰り返していく、ということが必要になると思います。

自動化する

自動化はもはやあれば良いものという位置付けではありません。成功するためには、プロジェクト・仕事・そしてツールにおいて、自動化は優先事項とする必要があります。

Jeffery D. Smith . システム運用アンチパターン . p.147

持続的な運用を実現する手段としておそらく真っ先に検討されるアプローチではないかと思います。要は人間が手動でやっている作業やタスクを機械にやらせましょうという話です。
強制力を高められる他、コストの削減や信頼性・セキュリティの向上も見込めます。属人化してしまっているようなタスクについては自動で実行することで、属人性の排除に繋がるケースもあります。
何より、要件が変わったり外部の構成変更などの影響を受けない限りは、時間が経過したとしても(基本的には)運用し続けられるというメリットがあります。

具体例としては以下のようなものが考えられます。

  • ドキュメントからコードを自動生成する
  • 手動で行っている集計や整形を定期実行する
  • 依存パッケージのアップデートが自動で行われるようにする

例えばAPI仕様書を手動で書くような運用になっている場合、APIの仕様を変更した場合に必ず仕様書も変更する必要がありますが、うっかり漏れてしまうとドキュメントの鮮度の低下に繋がってしまいます。このようなユースケースにおいては、OpenAPIとコード自動生成の仕組みを活用するなどの手法が考えられます。
OpenAPIの規格に従ってAPI仕様のドキュメンテーションを書き、そこからコードを自動生成することで仕様書作成のコストを削減しつつ、本番稼働しているコードとドキュメントが常に一致していることを担保できます。

https://swagger.io/specification/

これと同じようなアプローチで、実際に稼働しているものとドキュメントを変換するなりして同期するアプローチは持続的にドキュメントを鮮度を維持するうえでそこそこ強力なツールになります。

githubのリポジトリで管理しているパッケージについて、依存パッケージのアップデートを手動で行うのはなかなか面倒です。数が多ければなおのことです。
これを自動で行いたい場合にはdependabotrenovateなどが選択肢に上がると思います。依存パッケージのアップデートを自動で検出し、バージョンを上げるPullRequestを自動で作成したり脆弱性を検知してアラートを投げてくれたりします。

https://docs.github.com/ja/code-security/dependabot/working-with-dependabot
https://docs.renovatebot.com/

他にも自動化のための手段は色々ありますが、自動化できるのはあくまでも機械的に判断できる、あるいは社内の統制上それで良いとされている場合です。当然ながら最終的に人間の判断が必要とされるものには適用できません(手順をサポートなどの用途には使えるかもしれませんが)。

一つ注意点を書き加えておくと、自動化されたジョブがどのように動いているのか、問題が発生した際にどのようにすれば良いのかは必ずドキュメント等に書き残しておきましょう。業務が自動化したジョブに大きく依存しており、ジョブが動かなくなった時/何らかの手を入れないといけなくなった時に詰みます。

制約条件を課す

ある条件を満たさなければ特定の作業が進められないようにブロックするというアプローチです。利用できる場面は限られていますが、基本的に例外を認めない形で特定の作業に対する強制力を働かせることができます。
具体例としては、githubのPullRequestにおけるマージのブロック機構などが挙げられます。

https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule

PullRequestのマージにあたってはレビューやテストが通ることを条件にしている場合が多いかと思いますが、他にもタスクリストを活用して特定のカスタム条件を満たすまではマージできないようにすることも運用上可能です。

https://docs.github.com/ja/get-started/writing-on-github/working-with-advanced-formatting/about-task-lists

コードの修正と併せてドキュメントの更新、情報共有や周知を必須とする、といった運用を強制させるなどのユースケースが考えられます。他にはlinterで縛れないコード規約に沿っているか(例えばディレクトリ構成のレギュレーションに則っているか)、といったことを確認するのにも使えると思われます。

場合によっては業務の柔軟性が下がったりリードタイムが悪化したりしかねないので、バランスを気にしつつ取り入れる必要があります。

標準化する

属人化が進む原因の一つとして独自のシステムや運用が採用されていることを挙げましたが、社内共通であったり一般に利用されている製品やアプローチを利用できるようにすることで改善が可能になるケースもあります。それと併せて、運用コストを効率的に下げられます。

標準化の手法としては以下のようなものが挙げられます。

  • 運用について統一的な取り扱いが行われるようにする
  • 知見や運用をドキュメント化する

統一的な取り扱いとは、複数の組織やチームで運用のやり方を揃える、他にも世間一般でデファクトスタンダードとなっているような運用に切り替えるといったものが該当します。

  • 業務管理パッケージを利用する
  • 独自実装を避けて公開されているライブラリを利用する
  • 公開されている指標を使って評価する

知識や運用をドキュメント化などによって共有することで属人化を排除できます。ただ、単なる情報だけならまだしも言語化が難しいようなスキルやノウハウなど(暗黙知)をどのように共有するかが問題になってきます。
これについてはSECIモデルによるナレッジ・マネジメントの考え方が参考になるのではないかと思います。

https://it-trend.jp/knowledge_management/article/25-0019

これは暗黙知を形式知化するための共同化->表出化->連結化->内面化という4つのプロセスを繰り返し行うことで組織内の知識の形成を行うという手法です。なお、これ自体は属人化を排除するためのものというよりは組織において新たな発見を創出するためのものです。

また詳細は割愛しますが、先に述べたドキュメントが腐る問題についてはイミュータブルドキュメントモデルという考えが興味深かったので、こちらもぜひ参考にしてみてください。

https://kakehashi-dev.hatenablog.com/entry/2023/10/16/100000

集約する

運用が漏れやすいものがあるのであれば、集約したり頻繁に手が入りやすいものの近くに置いてやるのも一つの手です。一例としてMonorepo(モノレポ)は複数のリポジトリを単一のリポジトリに集約する手法です。

https://circleci.com/ja/blog/monorepo-dev-practices/

特に、依存パッケージのマイグレーション作業についてはまとめて実施できたりするので、同じような構成のアプリケーション・ライブラリを複数管理しているような場合には大幅にコストを下げることができます。

ただし、集約することで別のデメリットが生じる場合もあるので注意が必要です

  • CIの実行時間が長くなってしまう
  • リリースのライフサイクルが強制されてしまう

例えば、あるアプリケーションのみが利用している依存パッケージのアップデートを行った際に全アプリケーションのビルドやテストをCIで実行しなければならず、実行時間が長くなってしまうケースです(これ自体はフローの設計自体でなんとかなるかもしれません)。PullRequestのマージまでの時間も長くなりがちになり、結果としてリードタイムの悪化を招くケースもあります。

他のアプローチとして、頻繁に手が入りやすいものの近くに置いてやることで情報が陳腐化するアプローチもあります。例えば、リポジトリのコードの近くに関連するドキュメント(READMEやCONTRIBUTING)を配置して、仕様に変更が入った際にドキュメントも同時に更新することを促すようなアプローチです。

習慣(ルーティン)化する

自動化が難しく、かつ定期的に実施しておきたいようなものについては習慣(ルーティン)化することで持続しやすくなります。ルーティン化することのメリットとして大きいのは、モチベーションや個人の頑張りに依存せずに実施できるようになることです。

とはいえ完全に習慣化するまで時間も要しますし、漏れが発生したりするのでリマインドを入れておくようにしておくと良いでしょう。

  • 定期予定の会議を開催するか、既に定期的に行われている会議(日例や定例)のアジェンダとして加える
  • リマインダーとして通知する

コミュニケーションツールとしてslackを利用している場合は、標準のリマインダーやbotなどを使って通知してやるのも効果的です。


botに怒られる筆者の図

なお、習慣について注意が必要なのは新しく入ってきたメンバーはその習慣を知らないということを意識しておかなければならないという点です。必要なものについてはマニュアル化やオリエンテーションを実施したり、上記のようにリマインドなどする必要があります。

作業コストを下げる

一つ一つの作業のコストを下げることで、リソースが確保できずに行えなかった運用が行えるようにします。これ単体で実現すると言うよりは、上述したような自動化や集約化によって副次的にコスト削減が行われる、という形になると思います。

他にも、やることに求められる品質の閾値(SLOなど)を調整する、要件を削減するといったことでもコストが下げられる場合があります(ステークホルダーとはちゃんと合意しておきましょう)。

また、保守や管理するものの量を減らすことでコストダウンにも繋がります。既に使われていないシステムやツールについて、コストパフォーマンスが悪いものについては積極的に特定して廃止していきたいところです。そのままにしておいても勝手には減ってくれないので、定期的に棚卸しするなどしていらないものは廃止していきましょう。
(いつか使うかも、というものについてもとりあえずアーカイブしておくという手もあります)

その他

インセンティブやペナルティを設けることで運用を持続させるというアプローチも考えられます。

  • ある条件を維持することでインセンティブが与えられる
  • ある条件から外れた際にペナルティを課す

ある運用を持続的に行った場合になんらかのインセンティブを発生させるというようなものです。これにより組織、あるいは個人に対してモチベーションを発生させることができます。
サステナビリティインセンティブという概念がありますが、これと考えとしては似たようなものです。

https://scopex.tb-m.com/fxHEOHtp/incentive

ペナルティはインセンティブの逆です。持続的に行わなければ組織、あるいは個人に対して罰を与える形です。

ただ、これらの方法は一歩間違うと組織の柔軟性を害したり、それ自体が目的になってしまったりとメンバーの行動原理を歪めてしまう可能性もあるので注意が必要です。
また課題のセクションで述べたとおり、外発的なモチベーションによる行動は持続が難しいということも頭に入れておく必要があります。
可能であれば他の方法で担保するのが好ましいでしょう。

運営にあたって考えておきたいこと

ここまでで持続的な運用を行うにあたっての課題と、運用上でどのようなアプローチが取れるかについて見てきました。冒頭にも述べたように、持続的な運用がなされていくためには組織としても様々な点に注意を払っていかなければなりません。これも色々ある中の一部にはなりますが、順番に見ていきます。

一度やって終わりにしない

運用の持続化のためのアプローチを一度実施したとして、それを組織としても持続的に管理できる状態になっていなければなりません。
数カ月後、数年後には異なる運用が求められている状況になっている可能性もありますが、管理できていなければそれにも気付けません。途中で運用が想定外に行われなくなってしまっている可能性もあります。
その運用自体がちゃんと回っているかどうかを組織として把握できる状態にして、定期的にアップデートしていくのが好ましいでしょう。

一人だけでやらない

一人でやっているものは属人化しがちですし、何より持続的に行っていくには体力が続かなくなってしまいます。上述したようにスケールしない問題もあります。
とは言え、一人でやっていくのに比べて複数人でやるように規模を広げていくのは高いハードルがあります。

また、規模を広げていくにはどうやって皆でやっていくかという手段を考えるのも重要ではありますが、どうやったら皆のモチベーションを上げられるかどのようにすればメリットが伝わるかといった点についても注意しておく必要があります(決して楽な作業ではありませんが)。

何より各個人のメンタルモデルを理解しておかなければ他者を巻き込んで効率的に進めるのも難しくなってしまうため、常日頃からのコミュニケーション面での工夫なども必要になってきます。

難しければスモールスタートから、でもスコープは徐々に広げていく

紹介したようなアプローチは全てすぐに出来るものかというとそうではありませんし、組織としてちゃんと回そうとするとかなりの体力を要します。そもそも改善に向けてのアクションを実施するための時間や予算が得られないケースもあるでしょう。最初から広いスコープでやろうとすると、より難易度は高くなるものです。

セオリーとしては小規模なスコープで実践して実積を作り、それを交渉材料や判断材料としてより広いスコープに広げていくのが進めやすいでしょう。最初は個人から、いけると思ったらチームに、そしてその上位組織へという流れで発展させていくイメージです。

スモールがスモールなままで局所最適に留まってしまうのは組織として見ても勿体無いですし、適切に規模を広げていけると好ましいでしょう。狭いスコープでは見えてこなかった根本的な問題やアイディアも、広いスコープに広げていくことで見えてきたりするものです。

惰性で続けるのをやめる

ここまで運用をどう持続するかということを考えてきましたが、逆の話です。必要のない運用をどのようにやめるかという話です。もう少し詳しく言うと、何を続けるべきか、何をやめるべきか、それを考えて判断することを持続的にやっていきましょうという話です。

昔から習慣としてなんとなくやってきたが、この作業は本当に必要なのか?どの程度のコストパフォーマンスや意義があるのか?を考えた結果として捨てられる運用もあると思います。

(何度も書いていますが)リソースは無限ではありません。取捨選択が必要になってきますので、コストを圧迫しており不要な作業はなるべくなら減らしていきたいものです。常に最適化していくのが理想ですが、実際は難しいと思いますので定期的に振り返りを行って棚卸ししていくのが良いでしょう。

場合によってはリスクを受容する

状況に応じて、リスクを受け入れてしまうというのも一つの手です。
リスクマネジメント上で言うリスク受容の考えです。リスクの影響度や発生確率を考慮し、コストをかけて運用すべきかどうかを判断します。

https://www.ntthumanex.co.jp/column/riskmanagement/

リスクを受け入れられるような例としては以下のようなものが挙げられます。

  • 運用自体が短期間で終了する
  • 運用に高い品質が求められていない

対象となるものが、使い捨てるシステムやコードなのかどうかというのも一つの判断基準になるかと思います。

その運営を成り立たせているものが何なのかを意識する

少しだけ異なる観点の話です。組織で行っている運用が回っている状況があったとして、それが何によって維持されているか意識しておくことも持続性を保つ上では重要だと考えています。

統率力のあるオーナーのおかげでしょうか?
特定のメンバーのスキルや頑張りによるものでしょうか?
業務が詰まっていないタイミングだからこそ成り立っているものでしょうか?

何かの拍子に簡単に前提が崩れてしまうようでは持続性のある運用とは言えなくなってしまいます。どういった条件で成り立っているのか、あるいはどういった条件で成り立たなくなるのか、防ぐための手立てがあるのかといったことを考えておくとより堅牢さを維持し続けらるかと思います。

特に、内発的なモチベーションに頼った運用はやり方を間違えると持続性に関するリスクだけでなく、余剰労働にもなりかねませんので注意しておきたいものです。

考えることを継続的に行っていく

「今組織にとって必要とされている運用はどういったものなのか」を組織として継続的に考えていくことが重要だと考えています。

度々述べてきたように、どのような運用が適切なのかはその組織の目的や目標、メンバーやタイミング、あるいは外部の状況によって変わってきます。フェーズによっては色々なものを切り捨ててスピード優先でやっていかなければならないタイミングもあるでしょうし、運用の品質を下げざるを得ないこともあるかと思います。

運用を改善するための様々なプラクティスは世に色々溢れてますが、合う合わないもあるでしょうし、組織に適しているものでなければ余計なコストがかかってしまうだけになるリスクもあります。単に鵜呑みにするだけでは目的を見失いかねません。だからこそ、何かしらの運用を導入したり続ける限りは思考を停止せずに考え続けることが重要になってきます。

実際に結果を出すために「ベストプラクティス」を探しているなら、まずは必ず組織の具体的なニーズやゴールから始めましょう。具体的なゴールが定まってから、ゴールの達成を助けるプラクティスについて考え始めます。このようなアプローチを取らない場合、実現しようとする変化が理解されず、懐疑や抵抗を生み、最終的には失敗することになります。

Matt LeMay . プロダクトマネージャーのしごと . p.118

とはいえ、考えることのコストももちろんゼロではありません(むしろ重いまであります)。それでメインの業務に影響が出てしまっては本末転倒です。
また、ガチガチに方針を固めてやろうとするとメンバーも疲弊してしまいますし、組織の心理的安全性も低下してしまいます。少しずつでいいので、何ができるのかを組織内で考えていけると良いのではないかと思います。

実践してみたこと

最後に、私の所属する組織内のスコープで持続的な運用を行うために実施されているものについて参考までに少しだけ共有させて頂きます。
ある程度軌道に乗ってきたものもあれば、まだ検証中で結果が出ていないものもあります。課題や壁が見えてきているものもあります。

組織として優先すべき指標の定義・運用

長期的な案件などを除いて、組織として運用面で何をやっていくかは明確に定義されていません。チームとして何をやっていくかは、全体的な状況を見ながら自分たちで検討していく必要があります。
そこで、組織として重視すべき内容を個々の指標として洗い出し、達成に向けて運用するということを施策として行っています。

タスクや案件といった粒度ではなく、信頼性セキュリティコスト効率性などのカテゴリを作成し、それぞれに属する要素を指標として持続的に運用する、ということを行っています。指標の内容についてはソフトウェアの品質特性モデル、DX Criteria や AWS Well-architected などを参考に定義しています。

https://www.ipa.go.jp/archive/publish/qv6pgp0000000wkj-att/000055008.pdf

https://dxcriteria.cto-a.org/

https://aws.amazon.com/jp/architecture/well-architected/

各指標の具体的な例としては下記のようなものです。

  • 信頼性/問題を追跡可能な状態になっているか
    • コスト的な制約を除き、必要と考えられる箇所のテレメトリデータが取得できる状態になっている
    • 必要とされるテレメトリデータの洗い出しが3ヶ月に一度行われている
  • コスト最適化/キャッシュ戦略の精度向上
    • キャッシュ戦略のガイドラインが用意されている
    • 特定のタイミングでキャッシュ戦略のガイドラインを考慮した設計になっているかレビューが行われる

個々の指標については達成条件(SLO)を定義し、達成されなかった場合の影響度などを考慮して優先度付けて対応していきます。

また、これらの指標についてはある程度の期間をおいて見直しや状況確認を行うということもやっています。これにより、その組織が向かうべき方向が何であるかという情報をアップデートしつつ、達成すべき内容の陳腐化を防ぐというねらいがあります。

  • 指標の内容が適切かどうかの確認
  • 各指標が達成されているかどうかの確認

これらを一ヶ月に一度程度のスパンで行っています。
同じ時期に全ての指標が達成できるように動いていくのはなかなか難しいため、その時期に優先すべき指標を洗い出す取り組みも定期的に行っています。

  • この組織が取り組むべき指標は何なのか
  • 達成されなかった場合のリスクと影響度を考慮すると、この時期はどの指標を優先すべきなのか

これのもう一つの目的としては、組織として運用が回っているかを測る意味もありますが、組織が今現在行っている運用を必要としているか組織の運用として何が足りてないのかを考えるための機会を設けるという意味合いもあります。

デメリットとしては、この指標の管理や運用にそこそこのコストを要することです。
案件が忙しいタイミングでは個々の指標を達成することの優先度が下がってしまうこともありますし、運用自体の作業と相まって作業のバッファを食いつぶしてしまうような状況が発生してしまいます。

チーム運用の定期的な見直し

指標の運用に同じく、チームの運用自体も定期的に見直しを行っています。
チームの運用としては、下記のような内容を文書化して管理しています。

  • チームの目的・ビジョン
  • チームの運用方針
  • 管理しているプロダクトの運用方針
  • 会議体

三ヶ月に一度のスパンで運用自体が現状に合っているものなのかをチーム内で見直し、必要に応じて修正を行います。これによって現状に即していない運用になっていることを防ぎつつ、運用の課題を継続的に改善していくようにしています。

古くなったドキュメントの更新

ドキュメントの陳腐化対策です。
チーム内で管理しているドキュメントにタグを付与し、定期的に自動で検出して最終更新日から一定時間が経っていたら更新タスク(GithubのIssue)を自動で切る、ということをやっています。

修正したドキュメントはチーム内でレビューを行い、通ったものは確認・更新済みのものとして最終確認日時を記入し、鮮度が保証された状態にします。

懸念点としてはドキュメント単体の規模が大きいとそれなりに更新・確認コストを要すること、チーム外の人間が修正した箇所については都度確認が必要というところです。

おわりに

持続的な運用を支える組織を運営するために少しだけ考えておきたいことについて見てきました。

設計や実装などの開発作業と比較して、運用は考慮から漏れやすかったり本腰を入れての対応がなかなか進まなかったりするものです。正直なところ、モチベーションを維持するのもなかなか難しいという事情もあるかと思います。
とは言え、運用業務はサービスやシステムを持続的に高品質に保つのに不可分な要素です。一人で気合で頑張ろうとしても途中で体力が尽きてしまうので、少しずつで良いので組織として取り組めるようにしていきたいものです。

これを読んで下さった皆さんの所属する環境にも、運用にまつわる様々な課題や工夫があると思います。ぜひどこかでお話をお聞かせ頂けると嬉しいです。
最後までお付き合い頂き、ありがとうございました。

ところで最近運動不足すぎてさすがに危機感を覚えてきたので、筋トレを再開しようと思ってる今日この頃です(まずは1日5分ぐらいからで...)

明日は@hsjoihsさんの記事です。

Discussion