🐢
GitHub ユーザ管理を Terraform で IaC 化して Base Permission=none に備える
こんにちは、secondz digital の SRE 兼情シス kame3t です。
背景
GitHub Organization を安全に運用するには least‑privilege(最小権限)が欠かせません。最終目標は Base Permission を none
に設定し、すべてのリポジトリ権限を コードで明示的に付与 できる状態にすることです。
まずは ユーザとチーム、外部コラボレーター の管理を Terraform で IaC 化し、段階的に Base Permission を none
へ移行する土台を整えます(現時点の既定値は記事では公開しません)。
この記事のスコープ
- ユーザ/チーム をコード化し、外部委託メンバー (Outside Collaborator) を プロジェクト単位で複数リポジトリへ付与 するパターンを紹介します。
- 組織内メンバーのリポジトリ権限(
github_team_repository
など)は必要になった際に扱う予定です。
アーキテクチャの要点
要素 | 現状 | 目的 |
---|---|---|
Base Permission | 組織デフォルト値 (非公開) | 段階的に none へ移行するための一次措置 |
管理対象 | ユーザ / チーム / Outside Collaborator | 変更履歴と監査証跡を確保し、GUI 操作を排除 |
Provider 構成 | モジュール不使用・直書き | 構成をシンプルに保つため |
台帳形式 |
locals (HCL) |
外部 YAML を増やさず HCL だけで完結 |
運用 | GitHub Actions で plan →apply
|
PR レビューで差分確認&自動反映 |
ディレクトリ構成
.
├── provider.tf # backend & provider
├── user_list.tf # 社員メンバー台帳
├── membership.tf # github_membership
├── teams.tf # チーム定義 & 所属付与
├── collaborator.tf # Outside Collaborator 台帳 (projects 属性で束ねる)
├── prj_<project>.tf # プロジェクトごとのリポジトリ × Collaborator
└── versions.tf # required_version 等
provider.tf (抜粋)
terraform {
required_version = ">= 1.10.0"
# backend は S3 / Azure Storage などに合わせて設定
required_providers {
github = {
source = "integrations/github"
version = "~> 6.6.0"
}
}
}
provider "github" {
token = var.github_oauth_token
owner = var.github_owner
}
1. ユーザ台帳 (user_list.tf)
locals {
github_members = {
"first_name.family_name" = {
username = "dummy" # GitHub username
role = "member" # admin / member
teams = ["fulltime"]
}
}
}
resource "github_membership" "org_member" {
for_each = local.github_members
username = each.value.username
role = each.value.role
}
2. チーム定義 (teams.tf)
resource "github_team" "fulltime" {
name = "fulltime"
privacy = "closed"
}
resource "github_team_membership" "fulltime_members" {
for_each = {
for id, v in local.github_members : id => v if contains(v.teams, "fulltime")
}
team_id = github_team.fulltime.id
username = each.value.username
}
3. Outside Collaborator 台帳 (collaborator.tf)
projects
配列に 論理プロジェクト名 を列挙し、複数リポジトリ へ権限を付与する設計です。
locals {
outside_collaborator = {
# key は社内 ID / 契約 ID など一意な値
"first_name.family_name" = {
username = "dummy-ext-a" # GitHub username
permission = "push" # pull / triage / push / maintain / admin
projects = ["ai-native"] # 関与するプロジェクト
}
"first_name.family_name" = {
username = "dummy-ext-b"
permission = "read"
projects = ["search", "ai-sales"]
}
}
}
4. プロジェクトごとの Collaborator 付与 (prj_<project>.tf)
例: AI Native プロジェクトで 1 リポジトリだけ付与する場合
# prj_ai_native.tf
resource "github_repository_collaborator" "ai_native_pmo" {
for_each = {
for id, v in local.outside_collaborator : id => v
if contains(v.projects, "ai-native")
}
repository = "ai-native-pmo"
username = each.value.username
permission = each.value.permission
}
例: Search プロジェクトで複数リポジトリに同一 Collaborator を付与する場合
# prj_search.tf
locals {
search_repos = [
"doc-search",
"doc-search-app",
"list-search-dev",
]
}
resource "github_repository_collaborator" "search_collab" {
for_each = {
for repo in local.search_repos : repo => repo
}
repository = each.value
username = local.outside_collaborator["ext_b"].username
permission = local.outside_collaborator["ext_b"].permission
}
ポイント
- Collaborator 台帳 は一元管理、リポジトリ側は プロジェクト単位で疎結合 に記述
projects
キーに論理名を付けることで オンボーディングも 1 行追加で完了
5. CI/CD フロー
- PR 作成で plan 差分をレビュー
- Merge すると
apply
が自動実行し、ユーザ/チーム/Collaborator が即時更新
今後のロードマップ
-
全リポジトリの権限を HCL 化 (
github_team_repository
等) - Plan で差分ゼロを確認後、Base Permission を
none
へ - SAML/SCIM 連携でアイデンティティ管理を自動化
まとめ
-
Users / Teams / Outside Collaborator を IaC 化し、Base Permission
none
移行を見据えた運用土台を整備 -
projects
配列 による “プロジェクト → 複数リポジトリ” 付与でスケールしやすい -
更新時に触るファイルは最小限 —
-
正社員(fulltime) の入退社・異動:
user_list.tf
だけを編集 -
外部委託 (Outside Collaborator) のオン/オフボーディング:
collaborator.tf
と該当プロジェクトのprj_*.tf
を編集
-
正社員(fulltime) の入退社・異動:
-
PR + CI で差分を可視化し、監査性と安全性を両立
ご意見・ツッコミはコメントでお待ちしています 🙌
Discussion