数あるサーバのタスクをNotionで一元管理する
現状
弊社では様々なサーバが稼働しています。それを限られた人数で運用するため、サーバの管理が属人化してしまう傾向にあります。さらに、担当者ごとに設計・監視ポリシーが異なっていたり、ドキュメントやコードの保管場所もバラバラという問題もありました。
オンプレもクラウドもあったり、コンテナ化されていたりいなかったりと、サーバの用途に合わせて運用・コストを当初最適化すべく設計されてきたものなので、統一されていなくても仕方ありません。
しかし、属人化している現状はさすがに改善すべきですので、今更全ての設計思想を統一するよう再設計するまではせずとも、まずは部員全員が、どんなサーバがあって日々どんな運用をしているのかを把握し、今後新設・更新する時に参照しやすくなるよう、日々の運用で随時発生するタスクをどこかで一元管理してみようと思い立ちました。
一元管理の方法
部内ではコードはGitHubで、ナレッジや各人のタスクはNotionで管理する、というなんとなくの共通認識があります。
そこで、最終的にはサーバ管理に関するタスクもNotionで一元管理できた方が、サーバ管理以外のタスクも併せて把握するのに優れていると考え、
-
サーバの設定やソースコード的なものは、サーバの種類ごとにリポジトリを分けてGitHubに
-
全リポジトリの情報を横断して最終的にタスクはNotionで一元管理
とすることにしました。
ここで迷ったのが、タスクそのものをどこで作成するかです。
結論から申し上げると、GitHub Issueとして作成することにしました。タスクごとにブランチをきった場合にGitHub Issueとの連携がとりやすかったり、コードを見ながら議論する際にGitHub Issue内ではリンクを貼ればコードで表示してくれることから、Notionのページを作成するよりも視認性が高く扱いやすそうと感じたためです。
まとめると、
-
サーバごとにGitHubリポジトリを用意
-
タスクが発生したらGitHub Issueを作成
-
GitHub IssueをNotionページと同期
という仕組みで管理する方針としました。
Notionページとの連携
NotionにはGitHubインテグレーションが用意されており、これを組み込むだけで簡単にNotion上にGitHub Issueを一覧表示させることができます。非常に便利ですね👍🏽
しかしながら、リポジトリごとにNotion DBが分かれてしまうため、これではリポジトリを完全に横断してGitHub Issueを管理できているとは言えません。つまり、「『未着手』のタスクだけ抽出したい」となった場合には、リポジトリの数だけNotion上でフィルタを適用しなければいけません。これでは不便さが残ってしまうので、GitHubActionsとNotion APIを活用して、GitHubでのIssueの作成・更新・削除をトリガにNotionページを作成・更新・削除する仕組みを作ることにしました。
最終成果物は下図のようになりました。
各サーバ用リポジトリのGitHubWorkflow (sync-issues2notion_dispatcher
) が Notion APIリクエスト用のGitHubWorkflow (sync-issues2notion
) を呼び出してNotionのサーバ管理用DBにページを作成・更新・削除するという流れです。Notion APIへのリクエスト部分はNotion SDKを使用してNode.jsで実行しています。
設計のポイントは、 「サーバごとのリポジトリ作成時における作業をできるだけ増やさない」 ことです。そのため、sync-issues2notion_dispatcher
側の操作は、GitHub Issueの作成・更新・削除をトリガにsync-issues2notion
を呼び出すのみとしています。
Notion API TokenやNotion DatabseIDなどの環境変数はsync-issues2notion
のRepository secrets
で保持するするのはもちろん、GitHub Token用の環境変数もOrganization secrets
に設定しています。これにより、サーバごとのリポジトリにはGitHubWorkflowのファイルを追加するだけでNotionページと連携できるようにしています。万が一NotionとのI/Fが変更となった場合でも、sync-issues2notion
を改修するだけで済みます👏
ちょっとした工夫
構築にあたって、他にもいくつか工夫したポイントがあります。
まずはセキュリティ面です。sync-issues2notion
を呼び出す場合に必要なGitHub Tokenの取得には、3rd Party製のGitHubActionsがよく使用されています。しかし、今回は社内サーバを管理するためのリポジトリということで、3rd Party製のGitHubActionsを使用するのは気がひけたため、手間を惜しまずにGitHub APIへリクエストしてTokenを取得するところから実装することにしました。また、使用終了次第Tokenは破棄するようにしています。
※ 作り終わってから気づいたのですが、最近GItHub公式からもToken取得用のGItHubActionsが公開されていたようです。先に気づいていれば甘んじて使用していたところでした。
次に、Labelの活用です。せっかくインテグレーションを組み込むだけでなくGItHubActionsで連携の仕組みを構築するので、インテグレーションでは連携されないLabelによるフィルタリングをできるようにしたいと思い、GitHub IssueのLabelをNotionページのプロパティに同期できるようにしました。さらにサーバ管理でよく使用するであろうLabelはGitHubのOrganizationレベルにあらかじめ追加しておくことによって、Labelがリポジトリ間でも統一でき、「『セキュリティアップデート』のLabelが付与された『未着手』のタスク」や「『優先度:高』となっている『進行中』のタスク」など、Notion上でリポジトリを横断してタスクをフィルタリングできるようにしています。新たなLabelを追加する場合もGitHub側で追加すれば、Notion側は自動作成されるようになっていますので、運用しづらさもなさそうです。
こんな感じでリポジトリを横断してタスク管理ができるかつ、フィルタしやすいDBになりました。
どうにかしたい点
一方で、あまりスマートではないな🤔 と思うポイントもあります。
最もどうにかしたい点はsync-issues2notion_dispatcher
のトリガです。
前述のとおり、sync-issues2notion_dispatcher
はGitHub Issueの作成・更新・削除がトリガになっていますが、LabelやAssigneeの付与は更新として検知するようにしており、Labelが1つ付与されたり、Assigneeが1人付与されるたびにトリガされます。つまり、Labelが3つ付与されたGitHub Issueを作成した際には、作成 + 更新 x 3 = 4回トリガされることになります。GitHubWorkflowは非同期で処理されるので、このままでは作成前に更新が実行されるということが起こり得ます。そこで仕方なく更新の際には5秒間のsleepを入れることで対処していますが、スマートな方法ではありませんし、GitHubActionsの無料枠を蝕んでいくので、打開策を講じたいところです。
次に、GitHub IssueのAssigneeにNotionのゲストユーザが設定されるとNotionのプロパティには表示できない点です。LabelのついでにAssigneeでもフィルタできた方が便利なのでAssigneeも連携するようにしました。連携にあたってはNotionユーザとGitHubユーザのID対応を設定ファイルで管理するという方法をとっています。部署異動等でユーザが追加・削減となった場合に設定ファイルを都度編集しなければいけないのも面倒ですし、NotionのゲストユーザにはIDが払い出されないので連携することができません。ユーザ名で管理する方法も考えましたが、現段階ではゲストユーザの人数は少ないので、いったんユーザIDでの管理としています。インテグレーションではAssigneeを連携できるので、これもなんとか打開策を講じたいところです。
最後に、GitHub IssueのDescriptionをNotionには連携していない点です。
Notoin APIではページプロパティの更新はできるものの、ページ本文の更新というのはあくまでブロック単位の更新になってしまいます。そのため、GitHub IssueのDescriptionをページ本文にきれいに表示させようとすると少し複雑な処理が必要になってしまいます。Notionではタスクの整理が主な目的ですので詳細まで確認することはあまりないでしょうし、GitHub Issueへのリンクは貼っているので、詳細が気になったらリンクからアクセスして確認するというフローで十分と判断しました。これは必要性が増したら連携させようと思います。
おわりに
属人化してしまっているサーバ管理を部員全員が把握しやすくなればと、GItHubActionsとNotion APIを利用して、Notion上でタスクを一元管理する仕組みを考えてみました。
とりあえず第一歩を踏み出すという段階にも関わらず、構築にそこそこ工数がかかってしまったので、多少の不便さがあってもインテグレーションを組み込むだけでよかった説もありますが、GitHubActionsとNotion APIのいい勉強になったし、かゆいところに手が届かなかったものが補えたとポジティブに考えるようにしています🙃
これからの運用で改善点はたくさんあがってくると思われるので、スピード感を意識して改良を重ねていきたいところです💪🏽