Access management for github at scale

In order to manage multiple users in a github organization, it is best to create multiple teams with different access and add users to the necessary teams.

Example:
  OrgName: example
  Teams: # each team will have different repo access
  - frontend
  - backend
  - devops 
  Members:
  - name: dineshba
    teams: devops, backend
  - name: another-dev
    teams: frontend
  - name: some-tech-lead
    teams: frontend, backend,devops

Hope the above yaml explains the concept of organization, teams and team-memberships at high level

So the steps will be:

  1. Add user to the organization (1 time per user)
  2. Create a team if needed or reuse the team (only 1 time)
  3. Give repo access to newly created team (only 1 time)
  4. Add user to the team (1 time per user)

So, number of steps for 10 users will be 10 + 1 + 1 + 10.

To be generic, 2 + 2n steps

At Scale:

We had an usecase, where we have to add more than 100 users to group of repos in our github organization immediately and also add users in future on demand basis.

So we created a automation to do this for us using terraform (yes, terraform is not only for infra management, we can do lot more with terraform). And it took less than 50 min (but this blog took more than 50 min 🤪)

Lets talk using terraform. Even if you dont know about terraform, you should be able to understand things a high level.

provider "github" {
  token        = var.github_token
  organization = var.github_organization
}

with this, terraform knows how to interact with github apis.

terraform {
  required_version = ">=0.12.6"
  required_providers {
    github = "~> 2.9.2"
  }
}

Note: Please use the latest version if you copying from here

variable "github_token" { # var used in first step
  type = string
}

variable "github_organization" { # var used in first step
  type    = string
  default = "some-org"
}

variable "github_members" { # var used in next steps
  type = list(string)

  default = ["dineshba"]
}
resource "github_membership" "membership_for_users" {
  for_each = toset(var.github_members)
  username = each.key
  role     = "member"
}

Note: organization name and token to interact with github apis is given in first step

If we run terraform plan and apply with above content, terraform will invite dineshba to join some-org github organisation

# use data-block to read team information, as team is already present
data "github_team" "some_team" { 
  slug = "some-team"
}
# use this resource-block to create/update team as team is already not present
resource "github_team" "some_team" { 
  name        = "some-team"
  description = "Some cool team"
  privacy     = "closed"
}

# provide necessary repository access to the team
resource "github_team_repository" "some_team_repo" {
  team_id    = "${github_team.some_team.id}"
  repository = "some-repo"
  permission = "pull"
}

If we run terraform plan and apply with above content, terraform will create a team called some-team and provide pull access to this team members for the repo some-repo

resource "github_team_membership" "some_team_team_membership" {
  for_each = toset(var.github_members)
  team_id  = data.github_team.some_team.id  # use resource instead of data if team is created by terraform
  username = each.key
  role     = "member"
}

Create github token and provide to terraform, so that terraform can do things on our behalf

export TF_VAR_github_token=<your-personal-github-token-created-in-UI>

Run terraform

terraform init
terraform plan
terraform apply

Please try and share your feedbacks below

Comments

comments powered by Disqus