Terraform GitHub Providerを導入した

Table of Contents

Introduction

個人の運用でTerraform GitHub Providerを導入したのでメモしておく。

Motiviation

長年ソフトウェアエンジニアをやってたらリポジトリが増えていく。特に最近のLLMの流行で検証用に作るリポジトリが顕著に増えている。 「Automatically delete head branchesは必ず有効にする」など、統一的な環境を宣言的にしたいという欲求があった。

また、SSH keysの設定など個人の設定も可能な限り宣言的に記述したい。

作業手順

こちらのproviderを使って導入する。 https://registry.terraform.io/providers/integrations/github/latest

0. Access Tokenを用意する

「Personal access tokens > Fine-grained personal access tokens」で必要に応じて権限を付与してTokenを発行する。

1. provider定義

sops にGitHub API Tokenを保存して terraform-provider-sops 経由で入れる。

terraform {
  required_providers {
    sops = {
      source  = "carlpett/sops"
      version = "~> 0.5"
    }
    github = {
      source  = "integrations/github"
      version = "~> 6.0"
    }
  }
}

provider "sops" {}

data "sops_file" "secret" {
  source_file = "./secrets.yaml"
}

provider "github" {
  token = data.sops_file.secret.data.github
}

2. ssh key定義

github_user_ssh_key で定義できる。

resource "github_user_ssh_key" "main" {
  title = "main"
  key   = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG9NCQp8KbNmdCQohUKzAJsNKe+Rz4IYDdthVX9Hzymi"
}

ここで確認できる。 https://github.com/takeokunn.keys

3. gpg key定義

github_user_gpg_key で定義できる。

resource "github_user_gpg_key" "main" {
  armored_public_key = <<EOT
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBGCPIQMBEAC+pajm1AKxI+aUdEgyDnJk4KZzz9G92sE/BqEr4pru4VGGuIZ8
L54olQLbbI6Epz8U8gRd6sfqf6ku4HmLWAtrtTNBwCqPpI7JDcLdKZM8w8HcI3/1
rdK3ZjCi1UTnkMHoKqKzYyIuum3qAQM8qEJIrW6miYfepT9KgitdpLY4jmCCeqv6

中略

-----END PGP PUBLIC KEY BLOCK-----
EOT
}

ここで確認できる。 https://github.com/takeokunn.gpg

4. repository定義

github_repositorygithub_repository_topics あたりで定義できる。

resource "github_repository" "blog" {
  name                   = "blog"
  description            = "This is a Zettelkasten blog generated by org-roam and ox-hugo."
  visibility             = "public"
  has_issues             = true
  homepage_url           = "https://www.takeokunn.org/"
  delete_branch_on_merge = true

  pages {
    build_type = "workflow"
    cname      = "www.takeokunn.org"
  }
}

resource "github_repository_topics" "blog" {
  repository = github_repository.blog.name
  topics     = ["blog", "hugo", "org-mode", "zettelkasten", "org-roam"]
}

上記の設定をすると takeokunn/blog のようにtopicが反映される。

既存のリポジトリは terraform import で帳尻を合わせればよい

$ erraform import module.github.github_repository.blog blog

CI構築しているなら sops で秘密鍵を管理しつつ、 github_actions_environment_secret などで流すのも良さそう。

作業結果

メインで使っている個人リポジトリはすべてTerraform管理に移行した。 また、新規リポジトリもTerraform経由で宣言的に作成できることを確認した。

終わりに

使用感は非常に良く、移行も一晩で終わったので良かった。

TerraformはPrivateリポジトリで管理しており、ほかにも Cloudflare Provider NextDNS Provider を管理している。 外部サービスは可能な限りTerraformで管理できるようにしていきたい。