📑

TerraformでGitHubを管理する

に公開

はじめまして、InfraSec Dept.の key こと佐藤です。

InfraSec Dept.はクロステック・マネジメントが提供するサービスを中心に、インフラ構築や自動処理、情報セキュリティを確保するための業務を担当しています。

今回はTerraformからGitHubを管理する方法を簡単にまとめます。

導入の背景

組織で情報セキュリティをたもつ場合に気を付けることの1つとして、さまざまな機能やサービスの設定が適切に行われていることが挙げられます。Terraformはクラウドインフラをべき等性を維持した状態で操作するためのツールですが、プロバイダを追加することでGitHubやSendGridなどのSaaSを操作することができます。

クロステック・マネジメントでは、GitHubのレポジトリ管理やメンバーの追加・削除といったオペレーションを、履歴を維持した状態で明確な定義をもって行うことを目的として、Terraformで管理するようにしています。

手順

GitHubの準備

TerraformからGitHubを扱うには認証が必要です。認証方法はPAT=Personal Access TokenとGitHub Appの導入による方法を選ぶことが出来ます。

PATは文字通り個人に属するトークンのため、担当者が組織から削除されると使用できなくなる問題があるため、GitHub Appを導入して進めることにしました。

GitHub Appの作成方法はインターネットに存在する数多のエントリに任せるとして…要点を下記します。

  • GitHub Appには必要最低限の権限をもたせる
  • アプリIDインストールID秘密鍵の3つの情報を取得、適切に管理する

権限の一部を抜粋すると次のようになっています。

  • メンバー管理(とても強い権限なので、クレデンシャルの漏洩に注意!)
  • GitHub Organization全体で使う秘密情報を扱えるように。共通化しておくと楽ですからね

Terraformの下準備

プロバイダの定義は次のように記述します。 integrations/github を使うこと、プロバイダの初期化時に app_auth を使ってGitHub Appの情報を渡す点がポイントです。

providers.tf
terraform {
  required_version = "~> 1.13.3"

  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 6.6"
    }
  }
  # 省略
}

provider "github" {
  owner = "example-organization"
  app_auth {
    id              = var.app_id
    installation_id = var.app_installation_id
    pem_file        = var.app_pem_file
  }
}

app_auth に渡すパラメタは変数で定義しておくといいでしょう。

variables.tf
variable "app_id" {
  type        = string
  description = "The GitHub App ID."
  default     = ""
}

variable "app_installation_id" {
  type        = string
  description = "The GitHub App Installation ID."
  default     = ""
}

variable "app_pem_file" {
  type        = string
  description = "PEM string of the GitHub App."
  default     = ""
  sensitive   = true
  ephemeral   = true
}

リソース定義

メンバー定義

メンバー定義を行うには github_membership リソースを使います。このリソースをapplyすると、指定したGitHubユーザアカウントが招待されます。ユーザが承認するとOrganizationに追加されるというわけですね。

members.tf
resource "github_membership" "key" {
  username = "key"
  role     = "admin"
}

GitHub Actions Environment Secrets定義

以下はAWSやGCPのクラウドリソースを定義し、その値をGitHub Actions Environment Secretsに登録するサンプルです。

resource "github_actions_environment_secret" "workload_identity_pool_id" {
  repository      = "repo_name"
  environment     = "dev"
  secret_name     = "WORKLOAD_IDENTITY_POOL_ID"
  plaintext_value = data.tfe_outputs.example_project.values.iam_workload_identity_pool_id
}

resource "github_actions_environment_secret" "workload_identity_pool_provider_id" {
  repository      = "repo_name"
  environment     = "dev"
  secret_name     = "WORKLOAD_IDENTITY_POOL_PROVIDER_ID"
  plaintext_value = data.tfe_outputs.example_project.values.iam_workload_identity_pool_provider_id
}

TerraformでGitHubを管理すると、クラウドリソースをプロビジョニングした値を、GitHub Actionsなどでシームレスに利用できる点は大きなメリットだと思います。

業務上の適用範囲

Terraform GitHubプロバイダで定義可能なリソースおよびGitHub Appの権限がある範囲であれば、どんなことでも設定することが出来ます。一方で、GitHub Appの権限は最小化しておく必要があり、2025年10月現在では次のリソースを管理するために使用しています。

  • メンバー、チーム管理
  • レポジトリの作成、初期化
  • 業務で共通で使用するGitHub Actions Workflowファイルの追加
  • GitHub Actions Environment / Secretsの管理
  • Issueラベルの設定

組織ごとに「これがベスト」という形は異なるので、業務に対して適用範囲をうまく見極め、上手く扱えるようにするのが良いでしょう。

実装上のポイント

教訓その1 取り扱うリソース数を考慮する

メンバ数やレポジトリ数がある程度あると取り扱うリソース数はリニアに増えます。

例えば、1つのユーザーが3つのチームに所属する場合、1ユーザー増やすごとに4リソースずつ増えるわけですが、メンバーが100名存在すると400リソースになります。

Terraformが実行計画を作る際にGitHubのAPIを呼び出しますが、リソース数が多い=API呼び出し回数が増えることとなり、APIレートリミットにヒットする可能性が上がります。短時間に何度もTerraformを実行した結果、APIレートリミットにヒットし、エラー終了するという問題に当たります(当たりました)。

リソース量を見極めながら、作業ディレクトリとワークスペースを分割して管理することを強く推奨します。

教訓その2 リソースのドキュメントをよく読む

GitHubプロバイダのリソースにはいくつかクセのあるものが存在します。

github_repository リソースは文字通りGitHubのレポジトリを作成することが出来ます。組織によっては maindevelop という複数のブランチを取り扱い、後者をデフォルトブランチにしたいケースがあると思うのですが、 github_repository リソースではデフォルトブランチを指定することが出来ません。

厳密に言えば default_branch 属性を指定することで可能なのですが、この属性は Deprecated なため将来的に利用できなくなる可能性があります。レポジトリの初期コミットを行う auto_init を指定すると、 main ブランチが自動作成するなど、ブランチの運用上やや混乱するケースがあるかも知れません。

今は次のように対応しています。

  • main ブランチは使おうと使わずとも、存在するものとして扱う
  • 追加のブランチは github_branch リソースを使って作成する
  • デフォルトブランチは、ブランチが全て作成されたあとに github_branch_default リソースで指定する

導入後の混乱とその後

さて、このような仕組みを導入してどうだったかというと、初期に混乱を生みましたがおおよそ良い結果が得られたように感じています。

初期の段階では、TerraformでGitHubを管理していることが伝わっておらず、Terraformでレポジトリ設定を更新する→レポジトリの管理者が手動で設定を変更する→Terraformの再実行で元に戻される…などの問題がありました。管理手法の周知や勉強会を行うことでこの問題は解決することが出来ました。

Terraformのリソース定義をコピペで作れるように作り込んだ結果、開発チームの方がメンバーの追加や削除、レポジトリの新規作成といった定義を含むPull Requestを作成してくれるようになり、インフラ担当者が確認を行う形で業務効率化できました。インフラ担当者は少なく、障害発生時はワークアラウンドにつきっきりになってしまうため、メンバーが並行で業務を進められるように鳴ったことは大きなメリットと感じています。

おわりに

もし興味を持ってくださったそこのあなた!
クロステック・マネジメントではInfraSec Dept.のインフラエンジニアを募集していますので、ぜひご応募ください。

クロステックマネジメント(京都芸術大学)

Discussion