30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

短いサイクルで意思決定を繰り返してデータガバナンスを漸進的に改善していく

自分の現在の主業務はデータプラットフォームの構築や運用だが、その文脈でここ数ヶ月取り組んでいたことのひとつに、データガバナンスがある。

データを利活用したい人がより安全かつ便利に利活用できるようにしていくこと、データ利活用体験を向上させていくことが、データチームの重要な役割のひとつだと思うが、データの利活用を推進するためには、データを管理できていなければならない。データを適切に管理しているからこそ、データの利活用に関して適切な判断や意思決定ができるようになる。

この記事では、データガバナンスに関してどのようなことをどのように取り組んできたのかについて書いていく。

前史

現在のデータプラットフォームが作られた際、明確なニーズが存在した。というより、強いニーズがあったからこそ「データプラットフォームを作ろう」という動きが生まれたと理解している。
そのため、そのニーズを満たすための機能開発が優先された。そして無事、ニーズを満たすようなデータプラットフォームを作ることができた。完璧ではないかもしれないが、ニーズを満たすことができ、一定の成果を出すことができた。社内でのデータ利活用も進んだ。データ利活用の課題としてよく「データプラットフォームを作ったはいいが利用されない」という事例が挙げられるが、そのような状態にはなっていない。
しかし機能要件を優先し続けたトレードオフとして、非機能要件の欠如が顕著になり、それにより様々な問題が起きていた。この頃に私がデータプラットフォームに関わるようになり、信頼性や可観測性などを高めていった。
それが一段落したあと、次はデータマネジメントに取り組むのがよいだろうと判断し、リソースを割くことにした。

やったこと

状況を把握する、状況を把握する能力を組織として獲得する

何をするにしてもまずは状況を把握しないと始まらないので、データの利用状況を調べて整理することから着手した。
勤務先である HERP ではデータウェアハウスとして BigQuery を使っているので、そこにに入っているデータをどのような用途で利用しているのかを調べていった。
用途ごとに Google Cloud のサービスアカウントを発行する運用になっているので、どのサービスアカウントがどのテーブルに対してクエリを発行しているのかを調べれば、ある程度のことはわかる。
そして「どのサービスアカウントがどのテーブルに対してクエリを発行しているのか」は BigQuery のINFORMATION_SCHEMAを使って調べることができた。

利用状況を把握できたことは収穫だが、「INFORMATION_SCHEMAを使えば調べることができる」ということが分かったことにも価値がある。
INFORMATION_SCHEMAの存在は知っていたし、それを使えばできるだろうとは思っていたが、実際に使ってはおらず活用できていなかったので、実際にやりたいことをできると証明できたことは大きい。
そして、調査方法をドキュメントに書き残したことで、権限さえあれば私以外の人間でも調査できるようになった。組織としての能力が少し広がった。

調査においては、社外提供しているサービスからの依存を重点的に調べた。
データプラットフォームは単に社内から使われているだけでなく、 HERP が公開し提供しているサービスの一部からも依存されている。そのためデータプラットフォームに不具合が起きると、不具合の内容や箇所によっては、社外提供しているサービスに影響が出てしまう。
そのため、社外提供しているどのサービスからどのように依存されているのかを、特に重点的に確認した。

社外提供しているサービスから依存されている dbt model を識別できるようにする

HERP のデータプラットフォームでは dbt を利用している。
dbt では model という単位で SQL を書き、その実行結果が BigQuery にテーブルやビューとして出力される。

既に多くの model が存在するが、その重要度は model によって異なる。
前述した「社外提供しているサービス」から依存されている model は重要度が高く、問題が起きた場合はすぐに対応する必要がある。一方で、社内での分析業務にのみ使われている model は、処理が失敗したとしても緊急性は必ずしも高くない。

これまでは model 毎の重要度を管理できていなかったので、その状況を改善したかった。変更を加えたいときや更新に失敗したときなどに、重要度や影響度を判断できるようにしたかった。
特に、「社外提供しているサービスから依存されているか」はすぐに把握できるようにしたかった。

dbt にある exposure という機能とタグという機能を使い、これを実現した。
この改善により、任意の model が社外提供しているサービスの依存関係に含まれるかどうかを、コマンドひとつで調べられるようになった。

不要なリスクや依存を取り除いていく

データガバナンスの問題に取り組み始めた当初、アクセスポリシーの包括的なルールや方針を作ろうと考えていた。

具体的には、「データ」と「ロール」をそれぞれ分類し、ロールごとにアクセスできるデータを設定していくことを考えていた。
まずデータを階層化する。「A, B, C」「Tier1, Tier2, Tier3」、名前はなんでもよいが、データを分類する枠組みを用意する。そして階層ごとに、「どのようなロールがアクセスできるか」を決める。例えば「データ管理者」は全てにアクセスできるが「データ利用者」は B と C のみアクセスできる、といった具合に。
このような手法はよく見かけるしよさそうに思えたので、ルールを策定すべく、調査や法務への質問などを行っていった。

が、断念した。
データもロールも、そう簡単に類型化できないことが分かった。データは多種多様だし、データの種類によって取得経路も異なる。
そしてそれ以上にデータの用途があまりにも多様であり、そのため妥当なロールを用意するのが難しかった。
妥当なロールを用意するためにはまず、各人の業務プロセスを理解し整理しないといけない。どのようなプロセスを何のために実行しており、そこにおいてどのようなデータを何のためにどのように使っているか、理解しないといけない。そうでないと、過不足のない適切なロールや権限を設定することはできない。

この方向で進めていくのは、明らかに時期尚早に思えた。リソースもケイパビリティも足りないし、今多大な労力を掛けて取り組んでも上手くいくとは思えず、費用対効果も悪そうに思えた。
そこで方針を切り替え、目の前の事象ひとつひとつに取り組みボトムアップに改善していくことにした。そうすれば、少しずつかもしれないが改善を積み上げていくことができる。そしてそうすることで、経験や知見を得ていくこともできる。どのようなケースにおいてはどのような手法や技術を使えるのか、それを実行する際に発生するタスクやリスクはどのようなものか、といったことについて学習が進む。また、数をこなすことでデータ利活用に対する理解が深まり、パターンを見出し上手く抽象化できるようになるかもしれないという期待もある。それができれば、将来的に原則や方針を作る際に役立つ。

まずできること、そして価値がありそうなこととして、不要なリスクの排除があった。
典型的には、あるデータが datamart 層に含まれており、そのことによって管理や利活用の難易度が高まってしまっているが、そもそもそのデータは使われておらず datamart に入れる必要が無いようなケース。
私が把握しているだけでもそういった可能性があるケースが複数あったので、ひとつひとつ対応していった。
利用状況を調査し、テーブル自体が使われていないなら当該カラムを消していき、テーブルの利用実態がある場合は関係者にヒアリングを行っていった。ヒアリングして不要だと分かればそのまま削除し、他のデータで代替できそうであればそれを提案し適用していった。

そういった model の地道な改善以外にも、サービスの廃止やアーキテクチャの改善も行った。
例えば、データ可視化機能の PoC として試験的に提供していたとあるサービスは、既に役割を終えており、利用実態も無さそうだった。このサービスで使っているデータに何らかのリスクがあったわけではないし、だからこそ放置されていたのだと思う。しかし、こういったものを放置し続けると管理コストが上がっていくし、予期せぬ障害の遠因にもなりかねないので、廃止できるときに廃止しておきたい。社外に提供しているサービスなので、担当者を通して顧客とコミュニケーションを取った上で、サービスを停止した。
また、ある機能を成立させているアーキテクチャ、データパイプラインについて、安全性の高い仕組みに移行できることが分かっていたので、その移行も推進した。対象の機能の性質上、事業責任者による意思決定が必要だったので、適宜コミュニケーションや情報提供を行い、移行の意思決定をしてもらった。現在は移行が完了している。

秩序が自律的に保たれる仕組みをデータプラットフォームに埋め込んでいく

上記したように私がオーナーシップを発揮することで状況が改善されていったが、このやり方だと、私がリソースを割かなくなった途端に改善は止まり、そしてまた元の状態に戻っていくことが容易に想像できた。
そのため次は、「望ましい状態」が自律的に作られていくような仕組みを目指していくことにした。

まず、既に述べた「社外提供しているサービスから依存されている dbt model の管理」が自動的に更新されるようにした。スクリプトを書きそれを週次で定期実行させることで、依存されている model が増えたときにそれを検知できるようにした。

また、 datamart に入れたくないデータが入ってしまうのを防ぐため、CI を拡充した。具体的には、 dbt で特定のタグが打たれているカラムを datamart に入れようとする PR が出された場合に、CI が落ちるようにした。

しかしこの仕組みは、打たれるべきタグが打たれていないと機能しない。そしてタグに限らず、メタデータを拡充していくことが、データガバナンス、そしてデータ利活用をさらに推進していく上で重要になるので、メタデータをいかに増やすかという問題にも取り組む必要がある。
メタデータの入力を促していく上で、 dbt-osmosis という機能を使えると便利なので、これを GitHub Actions のワークフローから実行できるようにした。GitHub Actions を使うことで、各々が手元で環境構築する必要がなく、非開発者でも使えるようになる。
そしてメタデータのなかでも、 dbt のデータリネージの最上流である source のメタデータを拡充していくことが特に重要だと考えているので、新規に source を追加する際に description を入力することを必須にした。これも CI を拡充し、入力されていないときは落ちるようにした。
これらの施策により、少しずつではあるが、以前に比べれば格段にメタデータが入力されるようになってきている。

それ以外にも、 Sensitive Data Protection のデータプロファイル機能の定期実行などの施策を行った。

短いサイクルで意思決定を繰り返す

以上、これまでの取り組みを紹介してきた。
この成果を「大きい」と見做すか「小さい」と見做すか、そして妥当な内容だと思うかどうかは、人それぞれだと思う。だが何にせよ、開始時点と比較して、確実に進捗が生まれ学習も進んだのは間違いない。
その要因は、常に目的に立ち返り、状況を見ながら、短いサイクルで意思決定してきたことだと思う。手段を目的化せず、以前立てた計画や方針に縛られず、柔軟に思考できたと思う。最新の技術を導入することや派手なアウトプットを作ること自体を目的とせず、その時々で必要なこと、効果があると期待できることを、取り入れていった。
組織内に知見がなく、個人や組織にとって経験や前例がないことに取り組む場合は、このように短いサイクルで意思決定や学習を繰り返していくやり方が有効なのではないかと思っている。