GitLabのリポジトリ管理をTerraformで自動化する

# はじめに
GitLabをポリレポで運用していると、リポジトリ数が増えてきて管理が煩雑になったりガバナンスが効かせにくくなることがある。
特に、ブランチ戦略をGitLabFlowにしている場合など、固定のブランチ名を消さないために保護設定をしたりするものの、ちょっとした事情でresetしたいことがあり、保護解除をしてそのまま忘れてしまったりしたら事故を起こす可能性も出てしまう。

なるべく運用を画一的にできるよう、Terraformで作成から運用までを自動化してみよう。

なお、Terraformを書くにあたってはGitLabの公式ドキュメントもあるが、記載の例だけでは分かりにくいので、補足しつつコードに落としていってみる。

https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs

# アクセストークンの準備
今回、リポジトリやグループ作成を行うので、Admin権限のあるユーザのトークンを作っておこう。
以下の通り、rootユーザログイン後のGitLabのコンソールから作成をすることが可能だ。

![キャプチャ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/4c5d31ab-0e41-8ae6-54fb-99f701ff0008.png)

# TerraformのGitLabプロバイダ設定
GitLabプロバイダは、Hashicorp社公式のものではなく、```terraform```の中で宣言をしなければ使えないため、以下の通り設定しよう。

```cacert_file```は、サーバ証明へのパスを設定しよう。
もしくは、```insecure = true```で証明書無しでの通信を行うことも可能だ。しかし、非推奨の方式なので、d系る限り```cacert_file```を使おう。

```HCL
terraform {
  required_providers {
    gitlab = {
      source = "gitlabhq/gitlab"
    }
  }
}

provider "gitlab" {
  token = "上記で払い出したGitLabのトークン"

  base_url    = "https://GitLabを運用しているドメイン/api/v4/"
  cacert_file = "${path.module}/サーバ証明書のファイル名"

  # insecure = true
}
```

# グループの作成
グループの作成は```gitlab_group```のリソースを用いる。
特に難しい設定部分はない。

```HCL
resource "gitlab_group" "example" {
  name        = "terraform-example-group"
  path        = "terraform-example-group"
  description = "An example group for Terraform"
}
```

これで```terraform apply```すると、以下のようにグループが作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/ba0879d6-53a7-3865-1643-f3de8b0e06cf.png)

# リポジトリの作成
リポジトリ(＝プロジェクト)は```gitlab_project```のリソースを用いる。
こちらも特に難しい設定はない。先ほど作成したグループ配下に作成するように、```namespace_id```を指定しておこう(指定しないとAdministrator領域(たぶんトーク払い出ししたユーザの領域？)に作成されるようだ)。

```HCL
resource "gitlab_project" "example" {
  namespace_id = gitlab_group.example.id
  name         = "terraform-example-project"

  description = "An example project for Terraform"

  visibility_level = "private"
}
```

これも、Applyすると以下のように想定通りのパスに作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/4b655240-e657-785f-5830-dc676be89b1c.png)

# ブランチと保護設定の作成
ブランチと保護設定は```gitlab_branch```と```gitlab_branch_protection```のリソースを用いる。
こちらも普通にプロジェクトに紐づけながら設定していくだけだ。
アクセスレベルは適宜設定をしよう。

```HCL
resource "gitlab_branch" "example_preproduction" {
  project = gitlab_project.example.id
  name    = "pre-production"

  ref = "main"
}

resource "gitlab_branch_protection" "example_preproduction" {
  project                = gitlab_project.example.id
  branch                 = gitlab_branch.example_preproduction.name
  push_access_level      = "developer"
  merge_access_level     = "maintainer"
  unprotect_access_level = "maintainer"
}

resource "gitlab_branch" "example_production" {
  project = gitlab_project.example.id
  name    = "production"

  ref = "main"
}

resource "gitlab_branch_protection" "example_production" {
  project                = gitlab_project.example.id
  branch                 = gitlab_branch.example_preproduction.name
  push_access_level      = "maintainer"
  merge_access_level     = "maintainer"
  unprotect_access_level = "maintainer"
}
```

これをApplyすることで、ちゃんとリソースが反映されていることが確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/8a2e3099-0566-d781-287b-bf71aa7dbf19.png)

これで、GitLabのリポジトリの見通しを良くしてガバナンスを効率よく効かせることができそうだ！