terraform-provider-github: managing GitHub as code, with the support caveat spelled out
Terraform GitHub provider
At a glance
- What is it?
- The GitHub Terraform provider manages repositories, teams, branch protections, Actions secrets and variables, organization settings, rulesets, deploy keys and webhooks over both the REST and GraphQL APIs, for GitHub.com and GitHub Enterprise Server. It is a community-supported project, and the README says plainly that GitHub Support does not cover it.
- Who is it for?
- The GitHub Terraform provider fits a team that already runs Terraform and wants organisation level configuration, branch protections and Actions secrets to live in the same state file as the rest of the infrastructure, and that is willing to treat it as a community dependency.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The resource list, and why the API split matters
The provider manages GitHub resources, and the list in the README names them: repositories, teams, branch protections, actions secrets and variables, organization settings, rulesets, deploy keys, webhooks, and more. It supports both GitHub.com and GitHub Enterprise Server, via the REST and GraphQL APIs.
That API split is the design fact that explains the shape of the code. GitHub's REST API is the older, more universal one, and GraphQL is the query oriented API that returns exactly the fields you ask for. A Terraform provider has to read the current state of a resource to compute a diff, and a REST endpoint that returns a fixed payload often does not return everything the provider needs to detect drift. GraphQL lets the provider ask a precise question, which is why a provider that supports both is more accurate on the resources it can query that way.
The consequence for a user is that not every resource behaves identically. Some are read through GraphQL, some through REST, and the import behaviour and the drift detection differ accordingly. The go.mod file shows the split concretely: go-github v92 for the REST API, and shurcooL/githubv4 for GraphQL, plus a separate rate limit package, gofri/go-github-ratelimit/v2, and a conditional HTTP transport package from bored-engineer with a bbolt variant.
The rate limit package is the one to know about. A provider that manages an entire organisation makes a lot of API calls, and GitHub's rate limits are per token and per resource type. A dedicated rate limit package means the provider can wait rather than fail, and the conditional HTTP transport, which is also the thing behind the bbolt variant, exists to avoid re-fetching resources whose ETag has not changed.
The module path is github.com/integrations/terraform-provider-github/v6, so the major version is in the import path, and the SDK is terraform-plugin-sdk/v2 rather than the newer framework. The Go version required is 1.26.0.
The quick start, and what the owner field is doing
The quick start is the whole getting started story, and it is short:
provider "github" {
owner = "my-org"
}
resource "github_repository" "example" {
name = "example-repo"
description = "Managed by Terraform"
visibility = "private"
}Two things are worth reading carefully in that block. The first is the owner attribute on the provider block, which sets the default organisation or user that resources are created under, so a configuration does not have to repeat the organisation name on every resource. The second is the visibility attribute on the repository resource, set to private, which is exactly the kind of thing you want to be explicit about in code, because a repository that defaults to public and then gets created by an automation is a real incident.
The requirements are Terraform 1.x and Go 1.26.x, the latter only if you want to build the provider plugin yourself. In normal use you consume the provider from the Terraform Registry rather than compiling it, and the README directs you to the GitHub Provider page on the Terraform Registry for installation and for the detailed documentation of every resource and data source.
The provider block in the example does not show authentication, and that is a real thing to think about rather than an omission in the docs. The go.mod includes jferrl/go-githubauth and golang.org/x/oauth2, and the examples directory has separate directories for app_authentication, app_token, and app_installation_repository, which between them cover the three ways you can authenticate: as a user, with a personal access token, and as a GitHub App installation. The choice between them is a permissions question, not just a convenience one.
The examples directory is extensive and it is the best map of what the provider actually supports. Alongside the authentication examples there are directories for data-sources, emu, enterprise_settings, hosted_runner, organization_security_manager, provider, release, repository_collaborator, repository_delete_branch_on_merge, repository_non_org_owner, repository_org_internal, repository_security_and_analysis, repository_team, repository_visibility, resources and secret_drifting.
A few of those names point at real operational features. repository_security_and_analysis is the security settings panel of a repository. organization_security_manager is the security manager at organisation level. hosted_runner is self-hosted Actions runners. repository_delete_branch_on_merge is a housekeeping behaviour you would otherwise have to script. And secret_drifting is an example of how to detect that a secret has drifted from what Terraform set, which is a genuinely hard problem given that Terraform cannot read a secret's value back.
Community supported, and what that means operationally
The support section is the most important paragraph in this README for an organisation, and it is short.
GitHub Support does not provide support for this integration. This is a community-supported project. GitHub's SDK team triages issues and PRs periodically.
That is a different model from a commercial provider, and the difference is not cosmetic. With a commercial provider you have a support contract, an SLA, and a named channel. Here, the triage is periodic rather than continuous, so the practical consequence is that a regression introduced by a GitHub API change may sit in the issue tracker for a while before someone picks it up.
The project is hosted under the integrations organisation, which is the Terraform provider integrations programme, and the repository carries MAINTAINERS.md, which names who maintains it, plus RELEASE.md for the release process, DECISIONS.md for recorded design decisions and SECURITY.md for disclosure. That set of documents is a good sign of process, and it is also the difference between community supported and community abandoned.
The roadmap is expressed through milestones, and the stated policy is that issues which receive the most recent discussion or the most reactions are more likely to be included in an upcoming release. That is a reasonable triage heuristic for a volunteer project, and it also tells you how to get a feature in: engage with the issue rather than filing and waiting.
The release cadence is visible in the tags. The three most recent are v6.13.0 on 2026-07-08, v6.12.1 on 2026-04-28 and v6.12.0 on 2026-04-23, so a minor version every few months and a patch when something needs fixing. The last push was on 2026-10-15 and the repository is not archived, so the branch is active even though the newest release is three months old.
The licence is MIT, and the repository has a .goreleaser.yml for the release pipeline and a GNUmakefile for the build, along with a .golangci.yml and a .golangci.strict.yml, which suggests a stricter lint profile is applied somewhere in the pipeline.
What the repository layout tells you about the internals
The top level listing is unusually well organised for a provider, and it tells you where to look for a specific behaviour.
The github/ directory is the provider implementation, and internal/ is for the parts that are not part of the public provider surface. The main.go file is the plugin entry point, and the go.mod and go.sum sit at the root as expected.
Then there is a set of directories that are not typical of a provider and that signal how seriously the project takes its own process. templates/ is for generating documentation and the registry content, tools/ is for the tool binaries, docs/ is the documentation source, and examples/ is the example configurations. terraform-registry-manifest.json is what the registry build consumes.
The three Markdown files at the root are the ones worth reading before you write configuration. ARCHITECTURE.md explains how the provider is put together, RESOURCES.md is the list of what it can manage, and DECISIONS.md records the design decisions that were made and why. A provider with a recorded decisions log has a much better chance of behaving predictably across its own major versions, which for a v6 provider matters.
The tooling configuration is also worth noting. There is a .rumdl.toml, which is a linter configuration for Markdown, and a .yamlfmt.yaml for formatting the YAML files in the repository. The .golangci.strict.yml sitting next to .golangci.yml is the pattern used when a project wants a stricter lint set for some directories, typically the generated or template code, so that a large amount of generated content does not drown the linter output for hand written code.
There is also a VERIFY_ATTESTATIONS.md file, which points at release provenance. A provider that manages credentials and deploy keys is a good candidate for supply chain attacks, and the combination of goreleaser, attestation verification and a MIT licence with a security policy is the baseline you would want from a dependency with that much reach.
The code quality tooling in go.mod is worth a mention for what it says about the runtime behaviour. The provider pulls in sethvargo/go-retry, hashicorp/go-cleanhttp and go-retryablehttp, so it retries transient failures rather than failing a plan on a single 502, and hashicorp/golang-lru/v2 is a cache, which is where the conditional HTTP transport's ETag knowledge would be kept.
Where this provider is the wrong tool
There are three honest reasons not to reach for this provider, and they are worth stating before the enthusiasm.
The first is the support model, which has already been covered. If your organisation has a rule that production infrastructure changes must have a support contract behind them, this provider does not satisfy that rule as written, because GitHub Support explicitly does not cover it. That is a policy question, but it is a real one for regulated environments, and the README's own sentence is the thing your risk team will read.
The second is the GraphQL and REST split, which is a fidelity question. Where a resource is managed through GraphQL, drift detection is precise, because the provider asks for exactly the fields it manages. Where it is managed through REST, the provider works with a fixed API response, and there are resources where the API response does not contain a field the provider wants to manage, or contains it in a shape that has to be normalised. The practical symptom is that some arguments behave as expected and others do not, and the documentation per resource is where you find out which.
The third is that the provider is a lot of machinery for a small job. A single personal repository does not need Terraform, and a team with a handful of repositories may find that a small script using the same API is less work than adopting a provider, a state backend and a lock file. The provider earns its overhead when you are managing dozens of repositories, several organisations, team permissions, branch protection rules and Actions secrets as a set, and the value comes from those being reviewed as code alongside the rest of the estate.
There is also a question of scope that the provider does not cover. It manages GitHub configuration. It does not manage the contents of your repositories in the way a pipeline would, and it does not replace GitHub Actions. If you are looking to apply a common set of files across many repositories, that is a different tool.
What the provider is genuinely good at is the tedious, high-count, reviewable surface: branch protection rules, team permissions, rulesets, organisation settings, Actions secrets and variables, and repository level security settings. That is a lot of configuration to hold in a repository of YAML by hand, and this is where a provider with an accurate diff earns its keep.
Editorial conclusion
The GitHub Terraform provider fits a team that already runs Terraform and wants organisation level configuration, branch protections and Actions secrets to live in the same state file as the rest of the infrastructure, and that is willing to treat it as a community dependency. It is the wrong choice if you need a supported contract from GitHub, because the README states GitHub Support does not provide support for this integration, and the wrong choice for a single repository where the Terraform overhead exceeds the benefit. Before adopting, read the RESOURCES.md and ARCHITECTURE.md files in the repository, check the release notes for the version you pin, and confirm the enterprise support claim against your GitHub Enterprise Server version, since the REST and GraphQL APIs behind it differ between GitHub.com and GHES.
Frequently asked questions
Which GitHub resources can the Terraform GitHub provider manage?
Repositories, teams, branch protections, Actions secrets and variables, organization settings, rulesets, deploy keys and webhooks, among others. The examples directory also shows data sources, enterprise settings, hosted runners, the organization security manager, repository collaborators, visibility, team membership and secret drift examples. The RESOURCES.md file in the repository carries the full list.
Does the GitHub Terraform provider support GitHub Enterprise Server?
Yes. The provider supports both GitHub.com and GitHub Enterprise Server, via the REST and GraphQL APIs. The Go dependencies show both clients in use, go-github v92 for REST and shurcooL/githubv4 for GraphQL.
Is the GitHub Terraform provider officially supported by GitHub?
No. The README states that GitHub Support does not provide support for this integration, that it is a community-supported project, and that GitHub's SDK team triages issues and pull requests periodically.
How do I authenticate the GitHub Terraform provider?
The examples directory has three separate authentication examples, app_authentication, app_token and app_installation_repository, covering user authentication, token based access and GitHub App installation access. The quick start shows the provider block with an owner attribute and a github_repository resource, and points to the Terraform Registry for the full documentation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/integrations-terraform-provider-github)Was this useful?