30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

Terraform で GitHub の Branch protection rule を定義する

Terraform では GitHub の Branch protection rule を管理する resource が提供されている。この記事ではそれを使って rule を定義する方法について扱う。
動作確認は Terraform のv1.7.4で行った。

Branch protection rule は、指定したブランチに対してルールを設定する仕組みで、pull request に対してレビューを必須にする、特定のテストをパスしないと merge できないようにする、などのルールを設定することができる。

GitHub の UI から設定可能だが、Terraform で管理していくこともできる。
Terraform には GitHub Provider が提供されており、その中には Branch protection rule を扱う resource もある。そのためそれを使えば、Terraform で Branch protection rule を管理することができる。

registry.terraform.io

今回はtf-testというリポジトリを作り、そのmainブランチに対して「Status Check にパスしないと merge できない」という rule を作成することにする。

Branch protection rule はリポジトリのページの Settings から見れるが、最初は何の rule も存在しない。

まずはリポジトリに.github/workflows/ci.yamlというファイルを追加し、そこに Status Check として行いたい処理(自動テストや型チェックなど)を書いておく。
これで、記述したトリガー条件に基づいてワークフローが実行されるようになるが、この時点ではまだ Status Check として設定されていない。そのため、このワークフローが失敗しても pull request の merge はできてしまう。

今回は Terraform Cloud で Terraform の state 管理を行うので、Terraform Cloud の設定を行う。
github-workspaceという workspace を作り、その workspace にTF_VAR_GITHUB_TOKENという Environment Variable を設定する。TF_VAR_GITHUB_TOKENに必要な権限を持ったトークンを設定することで、Terraform から GitHub を操作できるようになる。

あとは、以下のような Terraform ファイルを書けばよい。

terraform {
  cloud {
    organization = "your-org-name"
    workspaces {
      name = "github-workspace"
    }
  }
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 5.0"
    }
  }
}

variable "GITHUB_TOKEN" {
  type        = string
  sensitive   = true
}

provider "github" {
  owner =  "your github account name"
  token = var.GITHUB_TOKEN
}

resource "github_branch_protection" "example" {
  repository_id = "tf-test"
  pattern       = "main"

  enforce_admins = true
  required_status_checks {
    strict   = true
    contexts = ["ci"]
  }
}

GitHub の Organization にリポジトリがある場合も、provider "github"organizationではなくownerを書く。
今回は自分が作った Organization にtf-testを作ったのだが、上記の記述で問題なく動作した。
organizationという引数もあるのだが、2024/03/03 現在非推奨になっている。
https://registry.terraform.io/providers/integrations/github/latest/docs#organization

この状態で$ terraform init$ terraform applyを実行すると rule が作られる。

リポジトリのページで確認してみると、mainブランチを対象に以下が有効になっていることが分かる。

  • Require status checks to pass before merging
  • Require branches to be up to date before merging
    • ciという status check が必須になる
  • Do not allow bypassing the above settings