How do I manage all GitHub repository collaborators in a single repository

Hi everyone. I’ve been using GitHub Terraform provider for a while now and I want to manage repository collaborators using it. The problems is that I can’t manage all repository collaborators using a single resource. Which means, if someone manually adds a collaborator, Terraform can’t detect the change.

Here’s how a repository collaborator resource looks like:

resource "github_repository_collaborator" "a_repo_collaborator" {
  repository = "our-cool-repo"
  username   = "SomeUser"
  permission = "admin"
}

What I want is, something like

resource "github_repository_collaborators" "repo_collaborators" {
  repository = "our-cool-repo"
  collaborator {
    username   = "SomeUser"
    permission = "admin"
  }
  collaborator {
    username   = "AnotherUser"
    permission = "push"
  }
 .
 .
 .
}

This will enable me to manage all of the collaborators in single place and if someone goes to GitHub and manually adds a collaborator using the web interface, the next terraform plan command will show that remote changes occurred which will allow me to override the changes or add them to code.

I know this might be provider-specific thing but I wanted to ask anyways because I learn new things about terraform everyday and I thought there might be a trick to do this without having to make a feature request to the provider’s developers.

It is totally up to the provider how they handle this. Some providers will have a single resource which covers all members in a list, while others will have a different resource for each member, while some have both.

In general this is down to how the underlying APIs work - for example if there is no API that allows individual control then it becomes hard/impossible to offer the same in Terraform.

It is probably worth raising a feature request in the provider’s GitHub repo to see what the maintainers think.

2 Likes

Indeed, the usual approach is to follow the lead of the remote API design as closely as possible within Terraform’s model, and so if the remote API models repository-collaborator relationships as separate resources (with their own API calls to create/destroy) then the provider typically will too.

With other APIs the typical answer to this sort of requirement is to reconfigure the access policies of the remote system so that only certain special administrative credentials (which no humans routinely use) and Terraform’s credentials have access to perform the operation. That then means that it’s essentially impossible for this situation to occur in the first place, rather than allowing it to happen and then remediating it in retrospect.

However, I don’t know if GitHub’s access permissions are granular enough for that; removing access to add collaborators to a repository may also require removing access to perform other actions that Terraform isn’t responsible for, in which case I unfortunately don’t have a ready answer.

The GitHub Terraform provider is maintained by GitHub themselves and so there are some additional possibilities here compared to some other providers, such as adding something to the remote API that the provider could use to meet your use-case, or making the Terraform provider intentionally mismatch the separation of resources in the remote API if that would create a more ergonomic answer. Ultimately though it will be up to the provider maintainers at GitHub to decide, and if they choose to keep the current structure then there won’t be any solution directly within Terraform to achieve your desired goal, and so you’ll need to invest in some other separate system to monitor the GitHub API and detect if the full set of collaborators doesn’t match a desired state.

2 Likes