dbt-steampipe を検証した

はじめに

たまたま steampipe のサポートプラグインを見たら、結構充実していた。ちょっと調べたら dbt-steampipe プラグインも作られており、これを使ってクラウドサービス関連のデータ収集が dbt 上で管理できれば便利なんじゃないかと思ったので検証してみた。

Steampipe とは何か

Steampipe はいろんなクラウドサービスの API をラップして SQL でデータ取得できるインターフェイスを用意してくれる OSSSQLインターフェイスPostgreSQL を立てることで提供している。

Steampipe is the universal interface to APIs. Use SQL to query cloud infrastructure, SaaS, code, logs, and more.

GitHub - turbot/steampipe: Use SQL to instantly query your cloud services (AWS, Azure, GCP and more). Open source CLI. No DB required.

Developers | Documentation | Steampipe

ちなみに HCL でダッシュボードを構築・管理する機能も開発されていて割と面白い。

dbt-steampipe を動かしてみる

dbt-steampipe プロジェクトをクローンして、 Getting Started に従って steampipe が動くコンテナを立ち上げる。

docker compose build steampipe
docker compose up

steampipe でクエリできるか確認する。. でコマンドを補完してくれる。無事に起動して steampipe が用意している gcp 用のテーブルは確認できたが、 credential 情報がなかったのでクエリには失敗した。

$ docker compose exec steampipe steampipe query
Welcome to Steampipe v0.16.4
For more information, type .help
> .tables
 ==> gcp
+---------------------------------------------------------+--------------------------------------------------------------+
| table                                                   | description                                                  |
+---------------------------------------------------------+--------------------------------------------------------------+
| gcp_audit_policy                                        | GCP Audit Policy                                             |
| gcp_bigquery_dataset                                    | GCP BigQuery Dataset                                         |
| gcp_bigquery_job                                        | GCP BigQuery Job                                             |
| gcp_bigquery_table                                      | GCP Bigquery Table                                           |
...
+---------------------------------------------------------+--------------------------------------------------------------+

To get information about the columns in a table, run .inspect {connection}.{table}

> select * from gcp_bigquery_table;
Error: rpc error: code = Internal desc = hydrate function listBigQueryDatasets failed with panic /home/steampipe/.config/gcloud/application_default_credentials.json: no such file or dir (SQLSTATE HV000)

gcloud auth application-default login を実行して credential を生成。改めてクエリしたが、次は gcp 上のプロジェクトを指定していなかったので失敗した。

$ docker compose exec steampipe steampipe query
Welcome to Steampipe v0.16.4
For more information, type .help
> select * from gcp_bigquery_table;
Error: googleapi: Error 404: Not found: Project your-project, notFound (SQLSTATE HV000)

steampipe のコネクション情報は dbt-steampipe/conf/config.spc で指定されている。

connection "gcp" {
  plugin      = "gcp"
  project     = "your-project"
  credentials = "/home/steampipe/.config/gcloud/application_default_credentials.json"
}

example の例ではこのようになっているが、 project を書き換えて再度実行する。

$ docker compose exec steampipe steampipe query
Welcome to Steampipe v0.16.4
For more information, type .help

> select * from gcp_bigquery_dataset
+------+-----------------+-------------------------------------------+------------------+----------------------+-------------+--------------------------+---------------------------------+----------->
| name | dataset_id      | id                                        | kind             | creation_time        | description | etag                     | default_partition_expiration_ms | default_ta>
+------+-----------------+-------------------------------------------+------------------+----------------------+-------------+--------------------------+---------------------------------+----------->
...
+------+-----------------+-------------------------------------------+------------------+----------------------+-------------+--------------------------+---------------------------------+----------->

クエリに成功した。

次は dbt-steampipe を使った dbt の実行。まずは dbt の依存性をインストール。

$ pip install -r requirements.txt

中を見ると dbt-postgres を用意している。

dbt-postgres==1.3.0

と思ったら、dbt-core 1.4 以下では python3.11 はサポートされていないようだった。 なので普通に pip で dbt-postgres をインストールして 1.4.5 を入れた。やっと dbt-steampipe の example を実行する。

$ cd steampipe_example
$ dbt seed --full-refresh
...
$ dbt run
13:36:57  target not specified in profile 'default', using 'default'
13:36:57  Running with dbt=1.4.5
13:36:57  Found 2 models, 0 tests, 0 snapshots, 0 analyses, 291 macros, 0 operations, 1 seed file, 427 sources, 0 exposures, 0 metrics
13:36:57
13:36:58  Concurrency: 1 threads (target='default')
13:36:58
13:36:58  1 of 2 START sql table model public.bq_billable_bytes .......................... [RUN]
13:37:01  1 of 2 OK created sql table model public.bq_billable_bytes ..................... [SELECT 0 in 2.88s]
13:37:01  2 of 2 START sql table model public.top_most_expensive_bq_jobs ................. [RUN]
13:37:01  2 of 2 OK created sql table model public.top_most_expensive_bq_jobs ............ [SELECT 0 in 0.18s]
13:37:01
13:37:01  Finished running 2 table models in 0 hours 0 minutes and 3.68 seconds (3.68s).
13:37:01
13:37:01  Completed successfully
13:37:01
13:37:01  Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2

exmaple の profile.yml はローカルの postgres を指しているようだ。

default:
  outputs:
    default:
      type: postgres
      host: localhost
      user: steampipe
      password: steampipe
      port: 9193
      dbname: steampipe
      schema: public
      threads: 1

なので接続して確認する。

$ psql -h localhost -p 9193 -U steampipe -d steampipe
Password for user steampipe:
psql (14.7 (Homebrew), server 14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

steampipe=> \d
                                      List of relations
 Schema |                          Name                           |     Type      |   Owner
--------+---------------------------------------------------------+---------------+-----------
 gcp    | gcp_audit_policy                                        | foreign table | root
 gcp    | gcp_bigquery_dataset                                    | foreign table | root
...
 gcp    | gcp_sql_database_instance_metric_cpu_utilization_hourly | foreign table | root
 gcp    | gcp_storage_bucket                                      | foreign table | root
 public | bq_billable_bytes                                       | table         | steampipe
 public | bq_pricing                                              | table         | steampipe
 public | top_most_expensive_bq_jobs                              | table         | steampipe
(87 rows)

steampipe が用意している gcp 用のテーブル以外に、example プロジェクトで dbt の model として用意されている bq_billable_bytestop_most_expensive_bq_jobs がテーブルとして生成されていることが確認できた。

aws プラグインを使って aws のコストデータを取得する

aws プラグインを試してみる。 例えば aws のコスト管理するような状況を想定して、コストデータを取得してみる。 docker-compose.yml を確認すると、既にインストール対象になっている。credential は ~/.aws/credentials を参照させているようだ。

services:
  steampipe:
    build:
      context: .
      args:
        PLUGINS: aws gcp
    command: ["service", "start", "--foreground", "--show-password"]
    ports:
      - 9193:9193
    volumes:
      - ~/.aws/credentials:/home/steampipe/.aws/credentials:ro
      - "~/.config/gcloud/:/home/steampipe/.config/gcloud/"
      - ./conf:/home/steampipe/.steampipe/config
    environment:
      - STEAMPIPE_DATABASE_PASSWORD=steampipe

conf/config.spc に下記を追加してコンテナ再起動。(ここでprivateは~/.aws/credentialsに追加されているプロファイル名である)

connection "aws" {
  plugin = "aws"
  profile = "private"
}

aws のコスト関連のテーブルはいくつか用意されているが、今回は aws_cost_usage を incremental に追加するよう sql ファイルを用意する(本当はユーザー定義タグごとに集計したデータも見たかったが、現時点でサポートしていないみたい。PRはあるのですぐにサポートされそうではある)。models/example/aws_cost_usage.sql に下記のようなクエリを追加する(granularityと二つのdimensionは要指定らしい)。

{{
    config(
        materialized='incremental'
    )
}}

select
*
from aws.aws_cost_usage
where granularity = 'DAILY'
and dimension_type_1 = 'SERVICE'
and dimension_type_2 = 'OPERATION'
{% if is_incremental() %}
and period_start > (select max(period_start) from {{ this }})
{% endif %}

dbt runをする。

dbt run
03:04:28  target not specified in profile 'default', using 'default'
03:04:28  Running with dbt=1.4.5
03:04:29  Found 3 models, 0 tests, 0 snapshots, 0 analyses, 291 macros, 0 operations, 1 seed file, 427 sources, 0 exposures, 0 metrics
03:04:29
03:04:29  Concurrency: 1 threads (target='default')
03:04:29
03:04:29  1 of 3 START sql incremental model public.aws_cost_usage ....................... [RUN]
03:05:00  1 of 3 OK created sql incremental model public.aws_cost_usage .................. [SELECT 9617 in 30.90s]
03:05:00  2 of 3 START sql table model public.bq_billable_bytes .......................... [RUN]
03:05:01  2 of 3 OK created sql table model public.bq_billable_bytes ..................... [SELECT 0 in 0.95s]
03:05:01  3 of 3 START sql table model public.top_most_expensive_bq_jobs ................. [RUN]
03:05:01  3 of 3 OK created sql table model public.top_most_expensive_bq_jobs ............ [SELECT 0 in 0.25s]
03:05:01
03:05:01  Finished running 1 incremental model, 2 table models in 0 hours 0 minutes and 32.71 seconds (32.71s).
03:05:01
03:05:01  Completed successfully
03:05:01
03:05:01  Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3

成功した。postgres に繋いで生成されたテーブルを確認してみる。

$ psql -h localhost -p 9193 -U steampipe -d steampipe
Password for user steampipe:
psql (14.7 (Homebrew), server 14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

steampipe=> \d
...
 public | aws_cost_usage                                               | table         | steampipe
 public | bq_billable_bytes                                            | table         | steampipe
 public | bq_pricing                                                   | table         | steampipe
 public | top_most_expensive_bq_jobs                                   | table         | steampipe

steampipe=> \x
Expanded display is on.
steampipe=> select * from aws_cost_usage limit 10;
dimension_1               | Amazon Route 53
dimension_2               | AAAA
granularity               | DAILY
search_start_time         |
search_end_time           |
dimension_type_1          | SERVICE
dimension_type_2          | OPERATION
period_start              | 2022-03-19 00:00:00+00
period_end                | 2022-03-20 00:00:00+00
estimated                 | f
blended_cost_amount       | 0.000136
blended_cost_unit         | USD
unblended_cost_amount     | 0.000136
unblended_cost_unit       | USD
net_unblended_cost_amount | 0.000136
net_unblended_cost_unit   | USD
amortized_cost_amount     | 0.000136
amortized_cost_unit       | USD
net_amortized_cost_amount | 0.000136
net_amortized_cost_unit   | USD
usage_quantity_amount     | 340
usage_quantity_unit       | N/A
normalized_usage_amount   | 0
normalized_usage_unit     | N/A
partition                 | aws
region                    | global
_ctx                      | {"connection_name": "aws"}
...

ということで、steampipe で取得した aws のコストデータがこのように dbt の出力先の postgres にテーブルとして追加されたのを確認した。

さいごに

データの変換は dbt を使って DWH で実行するようになってきているが、 steampipe を使って各種データソースからのデータ取得も dbt 上で管理できるようになったら便利かもしれないと思い、検証してみた。Salesforce、Zendesk、Slack、Jira、Google Sheet などのプラグインはあるのでシンプルな用途では使えそうだが、実際にどんなデータがサポートされているかは要確認かな。Redditとか LinkedIn とかのプラグインがあるのは興味深い。ぱっと見、 steampipe のプラグインは developer 向けのサービスが多いため、real world な用途にはもうちょっとプラグインが拡充されて欲しい気がしなくもない。

一方で、各種データソースのためのプラグインは dbt にもそれぞれ存在することもあるので(e.g. dbt-salesforce)、間に steampipe を挟むことのメリット・デメリットをどう捉えるかは議論の余地がある。エコシステムの大きさを考えると dbt プラグインの拡充に期待する方が順当かなどうかなー。

2022年振り返り

PMへの転向

2022年のイベントとして個人的に大きかったのは、プロダクトマネージャーへロールチェンジしたことだ。

6月-7月くらいから具体的に考え始めて元上司に相談して、8月に実際にHiring Managerと話をして社内面接を進めて、9月半ばに結果が出て、10月から異動先で働き始めたって感じのタイムラインだった。所属企業が変わったわけではないので大きな手続きは必要なかった。現職ではCREとして2年くらいデータ活用周りで社内システムのエンジニアリングをやっていたが、その過程で得られた知見をもとに直接的に製品開発に関わってみようと思ったのがざっくりとした異動理由だった。一方で、PMという職種にそこまで強い思い入れがあるわけではなく、現職では自分がやったほうが組織にとって良いやろっていう気持ちがあり、たまたまポジションが空いていたため入れてもらったくらいの認識でいる。そのため、しばらく試行錯誤してもあまりフィットしないようならいつでもエンジニア関連の職種に戻れるだろうというくらいの気持ちではある。

現職のPMチームメンバーは基本USに居て、自分の現在のマネージャーもUSに居る。時差あり少数派リモートワークをしているが、まあ働きやすくはない。日本と勤務時間がかぶるのは午前中の2-3時間程度でミーティングの時間を合わせるのも一苦労だ。さらに今回は新しい職種への挑戦もはらんでしまっているので、なおハードモードだ。リモート時差ありだと仕事を見て盗むということはかなりしにくい。そして、PMは割とプロジェクトベースでアサインされそれぞれ動くことが多く、同僚のPMと協働することが少ないので、そう言う面でも同僚の仕事を真似しにくい。かつ、みな奥ゆかしいからか、オープンなチャットコミュニケーションはあまり活発ではなく、人が何を考えているかわかりにくい。日本で働くエンジニアは多いので、将来的には日本ブランチでdirector立てて独立して動けるPMチームなんかを作っても良いのかもしれない。もしくは移住するか。

これまでの三ヶ月で人と話してきて、技術がわかるPMへの期待とその需要は感じている。市場でも希少でやはり採りにくいのだろう。また、プロダクトとしてのTDをマネジメントする困難さみたいなものも分かってきた。世界的に見て大変な時期でありそれがいつ自分の身に降りかかってくるかもわからないが、少しずつ成果を出しながらみなが成果を出せるよう仕組みも良くしていければなと思う。

副業

夏くらいからPMとしての副業を始めた。支援先と現職とのステージの違いもあり、学ぶことも多い。少しはなんらか貢献できていれば嬉しいが、一方で余剰時間での貢献は不安定でもどかしい気持ちにもなる。余剰時間は本業やプライベートの忙しさや心の余裕なんかに左右されてしまうため、なかなか安定的に副業をするのは難しい。自分の時間管理をしっかりできる人じゃないと向いていないと思うので(自分が向いているとは決して思っていない)、万人にはおすすめ出来ないなと感じる。

勉強会の発表

二件、データ関連のトピックで発表させていただく機会をいただけた。

2022年読んで良かった本、愛用したもの

2022年読んで良かった本

ServiceNow CEO -> Snowflake CEO の Frank Slootman の経営本。創業者じゃないプロCEOの本は読んだことなかったので面白かった。

2022年のノーベル物理学賞の対象がベルの不等式の破れの実証だったので読んだ。丁寧に議論が進められていたので読みやすかった。量子の非局所的相関にまつわるあれこれ分かれて良かった。自然の真のランダム性が与える自然観は奥深かった。

2022年に愛用したもの

自宅でチャイが簡単に飲めるようになって良かった。

www.kaldi.co.jp

カルディで見つけたピリ辛ドレッシング。サラダに掛けて無限に食べてる。

よく磨けて気に入って使ってる。

プロダクトをマネージしたい話

先月から某 SaaS スタートアップで Product Manager の副業をさせていただいている。

本業でも最近は Product チームと一緒に働いたり、Product Management 領域の仕事をしており、その中でプロダクトをマネージすることに興味が湧いてきている。なので、これまでの経験を活かして Product Manager にトランスファーができるか少しずつ検討している(この意思決定は特段急いではいない)。

Product Manager 業を体験するのに一番早いのは、プロダクトを自分で作ることかなと思ったので、サイドプロジェクトで何か出来ないものかと考え始めている。

プロダクトを作る前に実際に引き合いがあるかを確認するのには基本のようなので、コンサルとかで入って悩みを聞いたりするのが良いのかなと思い、まずは個人事業用のサイトを作って公開した。

作るプロダクトのテーマとしてはできれば、システム運用を楽にしてひとりのエンジニアにレバレッジをかけられるようなサービスがいいかな。何か新しいことをしようとしているスタートアップは好きだし、SaaS も好き。人手が少ないそういう会社を手助けできれば嬉しい。特に自分の出自周りのクラウドインフラ、データエンジニアリングあたりに関連したもので。

いまいま考えたアイディアとしては、クラウドリソースのコスト管理やアセスメントができるサービス。例えば、企業によってはAWS のリソースにタグを付けてチームごとコンポーネントごとのインフラコストを算出してコスト管理をしていたりする。きちんとルールを策定して運用できている企業ばかりではないと思うので、その運用やコスト分配の設定を楽にできたり可視化やwarningが自動でできたり、サービスの利用状況や設定を見て適切なインスタントタイプや使い方をサジェストしてくれるようなサービス。無駄なリソースや微妙な設定を見えやすくしてITや開発部の作業時間の削減とシステムコストをスリム化して良いプラクティスを適用する。ってのをAWS以外のクラウドサービスにも対応できたら嬉しそう。

作ったら買っても良いよって人がもしいたらご連絡ください。 もしくは、話を聞きたいよ、困ってることがあって相談したいよ、ってのでも良いのでご連絡ください。

勉強会でモダンデータスタックの話をした

先週、Data Engineering Study という勉強会でざっくりとモダンデータスタックの話をした。

イベント参加登録者は400人超で最大同時接続数は180くらいだったそうな。

forkwell.connpass.com

感想

発表のために調査して自分も色々勉強になった。良い反響もいただけて、準備したかいがあったと感じられた。 本当は、プロダクトの紹介のみならず、実際の使用感や活用事例を含めて紹介できれば良かったのだが、そこまで調べ切ることはできなかった。

今回紹介したようなプロダクトが全てうまくいくとは思っていないけれど、その試行錯誤で得られたプラクティスはその他のプロダクトや現場の運用にも徐々に反映されていくのだろうとは思う。日本においてもデジタル化が進んでデータ活用・管理の機会が増える一方でエンジニアの供給はそこまで増えていないだろうから、ツールの進化で成果をレバレッジできるような世の中になれば良いなと思う。

Q&A

1 どうやって情報を仕入れているか?

基本的に Twitter で流れてきた意見や記事を読んでいるだけ。気になる記事の author なんかを探してフォローしたりしている。やっぱりトレンドということもありデータスタートアップ界隈で議論は活発になされている。

e.g. Modern Data Stack (@moderndatastack) | Twitter

2

組織の状況によって分かれるかなと思う。DWH にデータが存在することが Reverse ETLの前提なので、データエンジニア的なロールの人がいる組織という前提ではある。

  1. ある程度リテラシーがある非エンジニアリング部門の人が、エンジニアの手間を減らしてデータ活用を行うために Reverse ETL を活用するケース
  2. データエンジニアが、データ連携の実装・運用コスト軽減のために自分でデータの用意から Reverse ETL の設定までを行うケース

1 の場合はマーケターとかが必要なデータを調べて、データエンジニアにテーブル作成までを依頼するようなフローになると思うし、2 の場合は、データエンジニアが全部自分で実装してきた処理を一部 Reverse ETL に任せるようなフローになるかな。

3

んー、Reverse ETL の有無にかかわらず、DWH 上のデータ品質を上げる方法を実施していく感じじゃないかしら。Reverse ETL の利用者が誤ったデータの使い方をしてしまうような場合は、ドキュメントやメタデータを充実させるなどして地道にエデュケーションするしかなさそう。

4

MDMを意識的に組織で実践したことがないからわからないけれど、MDM的なものはDWH上で引き続き実施されて、Reverse ETL的な処理はマスターデータやファクトデータのその時々のスナップショットを同期するみたいなイメージを持っている。

5

へーAWS DMSがCDCしてくれるの知らなかった。

AWS Database Migration Service による Change Data Capture: 前編 - public note

6

調べたらとりあえず debezium は Transformation とか Filtering には対応しているっぽいですね。 Transformations :: Debezium Documentation

7

運営の方いわく、アンケートをとったところ発表者には昼間の開催が人気の一方、参加者には夜の発表が人気だったとのこと。個人的には昼間の方が嬉しいですねー。

8

やっぱり Airbnb みたいな、かなりデータ活用が組織に広がって管理が大変になってきた大きい企業じゃないとメリットだしにくそうな感じはしますよねー。dbt で管理して活用先に Reverse ETL するくらいの形が一番運用しやすいかもですね。

組織のカルチャーを維持する方法について

背景

この前、Openness というカルチャーに関する記事を書いた。

Openness について - satoshihirose.log

組織のカルチャーについてこれまで思いを馳せることも多く、何となく考えを文章にしてすっきりしたくなったので記事にする。

組織のカルチャーとはどういうものか

自分が想定する「組織のカルチャー」ってのは、ざっくり「組織にとって好ましい振る舞いを規定することで生産性を向上させるためのもの」だ。人によってそうでない捉え方をする人もいるかもしれないが、ここでは無視する。

カルチャーは、その個別の内容に関わらず、メンバーに共通の価値観を与えることで共通のプロトコルを用意し、コミュニケーションをスムーズにするという効果がある。 組織内の多様性が求められる昨今においても、まあ人間が自分と似た人を好きになるのは避けられないので、ますますカルチャーを作って維持する重要性は大きくなっていくかもしれない。そのような性質のものであるので、強いカルチャーというのは、規範として人々の行動を変える、つまりそれにより人々の意志決定に影響を与えるものだ。 逆に言うと、それによって人々の日々の意志決定が左右されないものなら、それは組織のカルチャーではないと個人的には思う。

また、組織が大きくなるにつれ、カルチャーがどれだけ組織の生産に貢献したかROIを測ることは難しくなると思うので(探せば研究なんかは出てくるかもしれないが)、カルチャーを維持する行為は一種のカルトみたいなものだとは思う。そのような集団がどうやって形成・維持されるかってところに自分の興味が惹かれる理由があるのかもしれない。それもあり、今回の記事では、どうやって組織に合ったカルチャーを規定するかには言及せず、ただ維持するための一般的な方法について考えていく。

ちなみに、自分が初めて本物の企業文化とはこういうものなのだなと強く実感したのは AWS Japan で働いたときで、自分の考えはそこでの体験に大きく影響を受けているので悪しからず。 (更に言うと、自分は企業の経営者でもマネージャーでもなく、企業文化の研究者でもない。ここで述べる理解はただのICの感想でしかないので、それも悪しからず)

組織のカルチャーを維持する方法

組織のカルチャーを維持する方法として、「明文化する」「日常的に繰り返し言及する」「評価の軸とする」でまとめた。

明文化する

明文化されていないカルチャーは社内外関わらず参照できず、理解が進まない。人々が同じものを目指していると思える原典として、その定義が必要だ。社外に対しても公開していると採用前に候補者の心構えになるし、フィルタリングをする役割にもなるだろう。

定義は具体的すぎず、適用範囲がある程度は広くなければならない。抽象的になることで解釈の余地があるとメンバー間での議論を生む。異なる運用が発生する可能性を生むので善し悪しではあるが、そのような議論は真剣にカルチャーが捉えられていて意志決定に取り入れられている証でもあり、そこまで問題視する必要はないと思う。

キャッチーで使いやすいくらい短いエイリアスがあると良い。日常で言及しやすくなる。

日常的に繰り返し言及する

人は日常的に言及しないと忘れてしまうので、しつこいと思うくらいに日常で言及する必要がある。特にリーダーシップ層が日々繰り返し言及することが大事だ。企業の責任ある人が重要視しないものはもちろん大事にはされない。これは All Hands なんかでカルチャーを交えた個人の体験を語るでも良いと思う。

カルチャーを維持するには仕組みで担保する必要がある。大小色々考えられるが、例えば、

みたいなものだ。まあともかく、日常的に意識される仕組みが無いと、ただ掲げられているだけのカルチャーは形骸化してしまう。形骸化したカルチャーはそれに惹きつけられた人を落胆させるし、それはロイヤルティの低下に繋がる。

評価の軸とする

人の行動は、賞罰によって変わる。カルチャーに沿った行動を称揚することで、人の行動を変えることはまあ出来るだろう。 例えば、

  • 面接時に「○○のような行動をとった時のエピソードを訊かせてください」のような質問をし評価に使う
  • 定期評価時、もしくは昇格評価時に、カルチャーに沿った行動によるアチーブメントを軸に評価をつける
  • カルチャーに従った行動を表彰する制度を用意する

など。もちろん程度も問題であり、評価に10%程度の影響しかなければその効果は少ないだろう。

さいごに

もうちょっと書けるかと思っていたが、こんなもんか。

カルチャーが強く表れているからと言ってすべての人が働きやすいわけではなく、そのカルチャーが自分に合うかもどうかは別問題である。ある種のカルト的な集団は合わない人には合わない。また、強いカルチャーがある組織に所属する経験がないと、その効果や機微は中々理解しにくいとも思う。

自分はそのような組織でとても働きやすかったと感じた経験があり、カルチャーの色が強そうな組織を見ると応援したくなる。IC とマネージャーとでもちろん違いはあるが、カルチャーを組織内で涵養させるためにできることは少なからずあるので、自分の気に入った組織の気に入ったカルチャーがあるならそれを大事にしたいものだ。

Openness について

"不必要なコミュニケーションを制限する"

チームトポロジーを読んでいる。 一環して、逆コンウェイの法則に従うように、つまり理想のシステムアーキテクチャに沿うように組織設計をしようと主張する本である。 チャプター2 で、不必要なコミュニケーションを制限する という節がある。

コンウェイの法則の示す重要な点は、すべてのコミュニケーションとコラボレーションがよいとは限らないということだ。したがって「チームインターフェイス」を定義し、どんな仕事には強力なコラボレーションが必要で、どんな仕事には必要ないのかという期待値を設定することが重要になる。多くの組織はいつでもコミュニケーションは多いほうがよいと考えるが、実際にはそうではない。

必要とされるのは、特定のチーム間における集中的なコミュニケーションだ。予期せぬコミュニケーションを探し、その原因に取り組むことが必要なのだ。

ソフトウェアエンジニアとしては、まあどんなインターフェイスやデータを公開するべきかをしっかり考えて API 設計するって発想はとても自然に感じる。すべてのメソッドや変数がオープンになっていると困るので、情報の流れに制限をかけて、振る舞いを制御する。そういう組織設計も経験的にまったく理にかなっているように感じられる。

一方で、その制限のついたコミュニケーションってものは、組織文化において良く尊ばれる「オープンなカルチャー」みたいなものを阻害したりしないのかな、って疑問が沸いた。その辺をどう整理して整合性をとれば良いか、今回考えたことをまとめる。

オープンなカルチャー

各社の Culture Doc からオープンネスに関する箇所を引用する。

「無私の心」の項目には、「大切な仲間をサポートするために時間を割ける。情報はオープンかつ積極的に共有できる」とあります。私たちは新しくチームに加わる仲間を心から歓迎し、存分に能力を発揮できるようにあらゆる面でサポートします。

Netflix Jobs

メルカリは相互の信頼関係を大切にしています。信頼を前提にしているからこそ、情報の透明性が保たれ、組織もフラットに構築。メンバーを縛るルールも必要以上に設けていません。一人ひとりの自発的な思考や行動が、個人の成長や組織の強さにつながると信じているからです。私たちは、このカルチャーを“Trust & Openness”と呼び、メルカリらしい人と組織の理想のあり方を追求していきます。

カルチャー | 採用情報 株式会社メルカリ

# 率直、建設的にオープンな場で議論する 誰かがそれを既に知っていたり、同じ検討をしてたり、活用したいかも知れない。集合知のインプットを活用しやすくし、議論のアウトプットを利用しやすくし、議論の組織ROIを最大化する

Ubie Discovery カルチャーガイド (社外公開版)

As One Team チームの成果に集中しよう 人、チームに対し、オープンさを貫こう

10X 採用情報

とまあ、こんな感じだ。

オープンネスは「信頼を育み、成果を最大化するため、意志決定の過程なんかの情報を積極的に公開すること」を示していそうだ。

DACI フレームワーク

ちょっと考えて、DACI フレームワークを使って「不必要なコミュニケーション」と「オープンなカルチャー」みたいなものをつなげられそうだと思った。

DACI フレームワークは意志決定における各人の役割の決め方についてのフレームワークで、関係者を Driver / Approver / Contributors / Informed に割り当て、意志決定を円滑にするためのものだ。 (DACI フレームワークの詳細は、この記事あたりを参照ください)

たぶん、逆コンウェイの法則で整理される「不必要なコミュニケーション」は Driver / Approver / Contributors を最小減にしてコミュニケーションを減らしましょうみたいな話であり、「オープンなカルチャー」で尊ばれる積極的な情報の公開は、Informed な関係者を積極的に広げましょうという話だ。

ということで、両立は可能であるし、またどちらも同時に損なうことも可能である。組織が小さいうちはすべての人が Driver / Approver / Contributors で良いが、組織が大きくなってくるとそうもいかなくなり、誰がどこまで Informed になるかを決めなきゃ行けなくなる。それを決める仕組みが必要になるので、まあそれが Driver / Approver / Contributors は逆コンウェイの法則で、Informed はオープンなカルチャーと呼ばれる何かなんだろう。

まとめ

ソフトウェア設計のアナロジーだと、変数の隠蔽みたいなクローズな情報の発生を連想してしまってナイーブな発想をしてしまったが、ちゃんと考えるとそりゃ違うことを言っているよなという話だった。

情報を公開できる形に整えるのもコストだし、反響に応えるにもコストが掛かる。そのコストに見合うだけの何らかの価値があるとする信念が組織のカルチャーであるのでしょう。やっぱり組織が大きくなるにつれて、伝える情報を制限して混乱を招かないようにしたり人を操作したりするムーブはどうしても増えいく一方なので、オープンという価値観を重視するなら、この辺の情報公開のポリシーやメッセージングについて振り返って考え続けることは大事だ。

なるべくオープンにやっていきたいものだ。