こんにちは。ソフトウェアエンジニアの坂井 (@manabusakai) です。
今月でカミナシに入社してちょうど 1 年が経ちました。前職では 6 年間 SRE チームにいたのでプロダクト開発はブランクがありましたが、さまざまな挑戦をさせてもらっていたらあっという間に 1 年が経っていました。
カミナシのエンジニアリング組織もこの 1 年で急拡大しており、入社当初から比べると正社員のエンジニアも倍以上に増えました。
GitHub の権限管理、どうしていますか?
ところで、みなさんが所属されている組織ではどのように GitHub の権限管理を行なっていますか?
カミナシではつい先日まで、ほとんどのエンジニアが Organization の Owner 権限を持っていました。理由は、メンターになったエンジニアがニューカマーのユーザーを招待していたからです。
しかし、統制が取れていないことでいくつか問題も発生していました。
- 不必要に強い権限を持ってしまっている
- Organization への招待や権限付与が適切なものかレビューされていない
- GitHub のユーザー名と従業員名簿が突き合わせできない
実際に、アカウントの棚卸しを依頼されたエンジニアリングマネージャーが Slack で聞いて回るという事態が発生していました。
エンジニアリング組織が拡大していくと、いつか破綻してしまうのは目に見えていたので、このタイミングで Terraform を使った権限管理に移行しました。
Terraform で行う GitHub 権限管理
Terraform というと AWS や GCP などの Infrastructure as Code をイメージされる方が多いと思いますが、実は GitHub のリソースを管理する GitHub provider も存在します。
これは HashiCorp が直接メンテナンスしている Official provider ではなく、パートナーシップを結んだ企業がメンテナンスしている Partner provider のひとつです。
カミナシではこの provider を利用して、次の GitHub リソースを Terraform で管理しています。
- メンバー (github_membership)
- チーム (github_team)
- チームメンバー (github_team_members)
- コラボレーター (github_repository_collaborators)
今のカミナシのフェーズだとリポジトリごとの細かい権限管理は必要ないので、チームはもっぱら他チームにコードレビューを依頼するときに使っています(Organization に所属していれば、基本的にすべてのリポジトリが見れて誰でも Pull request を出せるようにしています)。
Terraform のコードは次のようなフラットな構成になっています。
$ tree . ├── README.md ├── memberships_of_full_time.tf ├── memberships_of_outsourcing.tf ├── memberships_of_part_time.tf ├── provider.tf ├── repository_collaborators.tf ├── team_members_of_xxxxxx.tf ├── team_members_of_xxxxxx.tf ├── teams.tf ├── terraform.tfvars └── variables.tf
“Manage GitHub Users, Teams, and Repository Permissions” のように CSV ファイルをマスターにすることはせず、愚直に tf ファイルに定義しています。
CI は Terraform Cloud を利用しており、GitHub App で認証を行っています。 GitHub provider は OAuth Token / Personal Access Token で認証することもできますが、Organization の強い権限を与える必要があるため、永続的な token は漏洩したときのリスクが大きすぎます。
これまで手動で管理されていたリソースは、Terraform 1.5 で追加された import
ブロックと -generate-config-out
フラグを組み合わせて一気にインポートしました *1。
アカウント管理を Pull request で行う
Terraform でコード化することの最大のメリットは、すべての作業をプロダクト開発と同じように Pull request で行えるようになることです。
Pull request で行うことで、最初に挙げた課題を解決することができました。ひとつずつ見ていきましょう。
Owner 権限は一部のメンバーにだけ付与する
本来 Organization の Owner 権限は全員が持つべき権限ではありません。
今回 Terraform で権限管理ができるようになったことで、Organization への招待や権限付与は Pull request を作成するだけで良くなりました。なので、このタイミングで Owner 権限を持っているのは CTO とエンジニアリングマネージャーだけにしました。
認証を行うための GitHub App も最小権限に絞っています。
Organization への招待や権限付与は必ずレビューされる
適切なレビューサイクルを作るために、GitHub のコードオーナーを活用しています。
具体的には、tf ファイルのコードオーナーをエンジニアリングマネージャーにして、マージするにはコードオーナーのレビューを必須としています(Branch protection rule の “Require review from Code Owners” の設定)。
こうすることでメンターは Pull request を作成し、マネージャーがその内容をレビューするというサイクルが作れます。チーム異動が発生した際もマネージャーの作業を待つ必要はなく、メンバー自らが Pull request を作成すれば良いのです。
またコードで管理されているので、あとから意図を汲み取るのも git blame
するだけで済みます。
GitHub のユーザー名と従業員名を紐付ける
GitHub のユーザー名は本名と結びついていないケースも多いので、Terraform のリソース名を従業員名と一致させ、コメントに従業員番号も書くルールにしました。
例えば、次のような感じです。
# 0056 resource "github_membership" "tori_hara" { role = "admin" username = "toricls" } # 0070 resource "github_membership" "manabu_sakai" { role = "member" username = "manabusakai" }
こうしておけば、棚卸しするときも聞いて回る必要はなく、誰でも簡単に従業員名簿と突き合わせすることができます。
おわりに
まだそこまで規模が大きくなかったこともあり、実質的な作業は 1 日もかからずに終わらせることができました(インポート作業が一番大変でした)。
直接的なプロダクトへの価値提供ではありませんが、組織内の課題を仕組みでうまく解決できたのは良かったです!
最後に宣伝です 📣
カミナシでは絶賛採用中です! 一緒に強いチームを作っていく仲間を募集しています!
*1:詳しくは「Terraform 1.5 で実現する config-driven なインポート作業」もご覧ください。