Terraform GitHub Org Management Module Prompt
Manage a GitHub organization as code with repos, teams, memberships, and branch protection via for_each, importing existing repos safely.
- Target user
- Platform and DevEx engineers codifying GitHub org governance
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior DevEx engineer codifying a GitHub organization with the `integrations/github` provider (>= 6.2). Manage repositories, teams, memberships, and branch protection from typed maps with `for_each`, and make destroying a repo effectively impossible by accident.
Work through these steps in order:
1. Configure the provider with `owner = "<org>"` and a token/GitHub App installation (`GITHUB_TOKEN` or app auth) that has org admin scope. Prefer a GitHub App for higher rate limits and auditability.
2. Model typed variables: `repositories` as `map(object({ visibility, description, topics, template? }))`, `teams` as `map(object({ privacy, description }))`, and `members` as `map(string)` mapping username -> role. Drive each with `for_each` keyed by name.
3. For every `github_repository`, set `lifecycle { prevent_destroy = true }` and enable `archive_on_destroy = true` so a removal archives rather than permanently deletes. Deleting a `github_repository` DESTROYS the repo, its issues, PRs, and wiki irreversibly.
4. Add `github_branch_protection` (v4/v6 uses `pattern` + `repository_id`) requiring status checks, required reviewers, `required_linear_history`, and `enforce_admins`. Bind teams to repos with `github_team_repository`.
5. Manage org membership with `github_membership` (role `member`/`admin`). Warn that removing a `github_membership` resource REVOKES the person's org access, and removing an owner can lock out administration.
6. Import strategy: existing repos, teams, and memberships must be `terraform import`ed BEFORE the first apply, or Terraform will try to create duplicates (repo name collision) or, worse, reconcile by recreation. Provide the exact import IDs.
7. Enumerate DESTRUCTIVE operations: removing a repo from the map, flipping visibility public->private on a repo with forks, removing a member, and deleting a team that owns repos.
Input template:
```
Org: <org-name>
Auth: <PAT | GitHub App installation id>
Repos to manage (and which already exist): <list>
Teams and privacy: <list>
Members and roles: <user -> member/admin>
Branch protection baseline: <required checks, reviewers>
```
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
A GitHub org managed by Terraform concentrates enormous blast radius: a single deleted github_repository resource permanently destroys code history, issues, and PRs. The common failure is applying against an org with pre-existing repos without importing them first, causing collisions or destructive reconciliation. This prompt bakes in prevent_destroy, archive_on_destroy, and an explicit import-first workflow so codifying governance never becomes an irreversible mistake.
How to use it
Provide your org name, auth method, the repos/teams/members to manage (flagging which already exist), and a branch-protection baseline. Ask the model for the typed variable definitions, the for_each resources with lifecycle guards, and a list of exact terraform import commands to run before the first apply. Always run terraform plan and reject any will be destroyed on a repository.
Useful commands
# Auth (prefer a GitHub App installation token in CI)
export GITHUB_TOKEN=ghp_...
export GITHUB_OWNER=my-org
# Import existing objects BEFORE first apply
terraform import 'github_repository.this["service-api"]' service-api
terraform import 'github_team.this["platform"]' 4567890
terraform import 'github_membership.this["octocat"]' my-org:octocat
terraform import 'github_branch_protection.main["service-api"]' service-api:main
# Plan and hard-fail on any repository destruction
terraform show -json tfplan \
| jq -e '[.resource_changes[]
| select(.type=="github_repository" and (.change.actions|index("delete")))]
| length == 0'
# Reconcile: list org repos via API to find drift
gh api "orgs/$GITHUB_OWNER/repos?per_page=100" --paginate \
| jq -r '.[].name'
Patterns
Repositories with destruction guards and branch protection, driven by for_each:
variable "repositories" {
type = map(object({
visibility = string
description = string
topics = optional(list(string), [])
}))
}
resource "github_repository" "this" {
for_each = var.repositories
name = each.key
visibility = each.value.visibility
description = each.value.description
topics = each.value.topics
archive_on_destroy = true
lifecycle {
prevent_destroy = true
}
}
resource "github_branch_protection" "main" {
for_each = github_repository.this
repository_id = each.value.node_id
pattern = "main"
enforce_admins = true
required_linear_history = true
required_pull_request_reviews {
required_approving_review_count = 2
dismiss_stale_reviews = true
}
required_status_checks {
strict = true
contexts = ["ci/build", "ci/test"]
}
}
Teams, membership, and team-to-repo binding:
resource "github_team" "this" {
for_each = var.teams
name = each.key
privacy = each.value.privacy # "closed" or "secret"
description = each.value.description
}
resource "github_membership" "this" {
for_each = var.members # map(username => "member"|"admin")
username = each.key
role = each.value
}
resource "github_team_repository" "platform_api" {
team_id = github_team.this["platform"].id
repository = github_repository.this["service-api"].name
permission = "push"
} Related prompts
-
Terraform Cloudflare DNS Module Design Prompt
Design a Cloudflare provider module that manages a zone and many DNS records via a for_each map while guarding apex and NS records from accidental deletion.
-
Terraform TFLint Custom Ruleset Authoring Prompt
Author a custom TFLint ruleset — .tflint.hcl config, the terraform + aws bundled rulesets, and Go rules built on the TFLint plugin SDK to enforce naming conventions and required tags, then wire it into pre-commit and CI.
-
Terraform Azure Naming Convention Module Prompt
Design a Terraform naming/abbreviation module for Azure that produces compliant, length-limited, globally-unique resource names with deterministic outputs.
-
Terraform VPC Network Module Design Prompt
Design a reusable, greenfield VPC/network module with clean variable inputs, computed subnet layout, and stable outputs other stacks can consume.
More Terraform prompts & error guides
Browse every Terraform prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.