This is a part of my guide to how I manage multiple GitHub repositories. This post focuses on configuring repository settings on GitHub using Terraform. Back to main guide.
Repository Management with Terraform I use Terraform to declaratively configure:
Repo metadata: description, topics, features Branch settings: default branch and protection rules GitHub Actions secrets: shared credentials for NuGet and Docker Example Configuration Github.tf defines:
locals { github_owner = "LordMike" github_token = "REPLACE_ME" repositories = jsondecode(file("repos.json")).repositories repos = keys(local.repositories) repos_public = [for r in local.repos : r if lookup(local.repositories[r], "public", true)] nuget_repos = [for r in local.repos : r if lookup(local.repositories[r], "nuget", true)] docker_repos = [for r in local.repos : r if lookup(local.repositories[r], "docker", false)] docker_username = "lordmike" docker_key = "REPLACE_ME" nuget_key = "REPLACE_ME" } provider "github" { owner = local.github_owner token = local.github_token } resource "github_repository" "repository" { for_each = toset(local.repos) name = split("/", each.key)[1] description = lookup(local.repositories[each.key], "description", "") topics = lookup(local.repositories[each.key], "topics", null) has_issues = lookup(local.repositories[each.key], "has_issues", true) has_wiki = lookup(local.repositories[each.key], "has_wiki", false) has_projects = lookup(local.repositories[each.key], "has_projects", false) has_downloads = lookup(local.repositories[each.key], "has_downloads", false) delete_branch_on_merge = lookup(local.repositories[each.key], "delete_branch_on_merge", true) } resource "github_branch_default" "default_branch" { for_each = toset(local.repos) repository = split("/", each.key)[1] branch = "master" } resource "github_branch_protection" "protect_master" { for_each = toset(local.repos_public) repository_id = split("/", each.key)[1] pattern = "master" enforce_admins = false allows_deletions = false allows_force_pushes = false } resource "github_actions_secret" "nuget_key" { for_each = toset(local.nuget_repos) repository = split("/", each.key)[1] secret_name = "NUGET_KEY" plaintext_value = local.nuget_key } resource "github_actions_secret" "docker_username" { for_each = toset(local.docker_repos) repository = split("/", each.key)[1] secret_name = "DOCKER_USERNAME" plaintext_value = local.docker_username } resource "github_actions_secret" "docker_key" { for_each = toset(local.docker_repos) repository = split("/", each.key)[1] secret_name = "DOCKER_KEY" plaintext_value = local.docker_key } Tips Use for_each and filtered locals (e.g. docker_repos) to simplify resource declarations Use lookup to define defaults and override per-repo settings Terraform Imports (for existing repos) Use terraform import with escaped resource keys:
...