GitHub 設定を Terraform で IaC 化しました
本記事は MIXI DEVELOPERS Advent Calendar 2024 のシリーズ2 14日目の記事です。
サロンスタッフ予約サービス minimo のソフトウェアエンジニアをしている yhamano0312 です。
minimo に異動してくる前は事業部横断でエンジニアリングを支援する部署に所属していたのですが、その時に支援していたソーシャルベッティングサービス TIPSTAR で行なった GitHub 設定を Terraform で IaC 化したことについて紹介します。
はじめに
MIXI では 2023 年より全社的に GitHub Enterprise Cloud (以下、GHEC)の導入を進めています。GHEC の導入に伴って既存の Organization から新しい Organization にリポジトリやユーザーを移行する必要があったので、これを機に GitHub に関する設定を Terraform でコード管理することにしました。
コード管理にした目的
単純に Infrastructure as Code (以下、IaC)のメリットを享受したいためです。目的をざっと挙げると例えば以下のようなものがあります。
- 他メンバーにレビューしてもらってから反映したい
- Admin 権限を持っている人への作業依頼を少なくしたい
IaC のツールには GitHub provider が用意されている Terraform を利用しました。
Terraform 実行環境
Terraform 実行環境には HCP Terraform を採用しました。
Terraform コードを管理するリポジトリと VCS 連携した Workspace を作成して environment に GitHub との認証情報を入れるだけで Terraform パイプラインが使えるようになるのでとても便利です。
GitHub との認証情報には GitHub Apps を利用しました。Workspace の environment には改行を含めることができないので、pem_file
に含まれる改行を\n
に replace して設定する必要があるので注意してください。
コード管理対象リソース
GitHub 設定を全てコード管理してしまうと煩雑になってしまいますし、 GUI から設定変更したいケースも考えて対象リソースは以下のみとしました。
- メンバー招待
- チーム管理
- https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team
- https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository
-
https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_members
- チームのメンバー管理には github_team_membership リソースもあります。
github_team_membership
は 1 つの resource 定義で特定チームに1人のメンバーを設定するのに対し、github_team_member
は 1 つの resource 定義で特定チームの全メンバーを設定します。github_team_member
を使うとコード定義と実態に差分があった場合にコード定義されている内容に強制的に上書きます。今回は Terraform 以外からメンバー変更するケースは想定しないため、github_team_member
を採用しました。 - HCP Terraform はリソース数課金なので、1つのリソース定義で複数のメンバー定義が可能な
github_team_member
を使った方が利用料的には安く済みます。
- チームのメンバー管理には github_team_membership リソースもあります。
- リポジトリ
-
https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository
- リポジトリを管理しているチームのリーダーやマネージャーが GUI からリポジトリの設定(branch protection 等)を変更したいという要望もあったため、リポジトリについてはコードと設定が一致しないことを許容しました。そのため、
ignore_change=all
を設定してリポジトリ作成のみを Terraform から行えるようにしました。
- リポジトリを管理しているチームのリーダーやマネージャーが GUI からリポジトリの設定(branch protection 等)を変更したいという要望もあったため、リポジトリについてはコードと設定が一致しないことを許容しました。そのため、
-
https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository
以下はこれらリソースを使った設定例です。
locals {
owners = ["owner1", "owner2"]
members = ["member1", "member2"]
}
resource "github_membership" "owner" {
for_each = toset(local.owners)
username = each.value
role = "admin"
}
resource "github_membership" "member" {
for_each = toset(local.members)
username = each.value
}
resource "github_repository" "api" {
name = "api"
visibility = "private"
has_issues = true
has_wiki = true
has_projects = true
archive_on_destroy = true
lifecycle {
ignore_changes = all
}
}
resource "github_team" "server" {
name = "server"
privacy = "closed"
}
resource "github_team_members" "server" {
team_id = github_team.server.id
dynamic "members" {
for_each = toset([
github_membership.owner["owner1"].username,
github_membership.owner["owner2"].username,
github_membership.member["member1"].username,
github_membership.member["member2"].username,
])
content {
username = members.value
# org owner は必ず maintainer となる仕様のため
role = contains(local.owners, members.value) ? "maintainer" : "member"
}
}
}
resource "github_team_repository" "server" {
for_each = toset([github_repository.api.name])
team_id = github_team.server.id
repository = each.value
permission = "push"
}
まとめ
GHEC 移行をきっかけに GitHub 設定を Terraform 管理にしました。これによりメンバーが設定変更を行う PR を作成し、リーダーやマネージャは PR を approve してマージすることで設定を反映できるようになりました。またコード化したことで設定内容を網羅的に確認できるようになり棚卸し等もやりやすくなりました。
GitHub 設定の IaC 化を検討している方の参考になれば幸いです。
最後に
MIXI では一緒に働く仲間を募集中です!詳細は採用ページをご覧ください。
Discussion