alex_mav
alex_mav

Reputation: 23

Terraform - GitHub Provider | scalable methods in managing organizations

I'm trying to manage GitHub Enterprise with 200+ organizations using Terraform. Here's what I've achieved so far:

I've used the GitHub Provider (integrations/github) in Terraform to create/modify 10+ organizations by creating a custom organizations module.

The module I built does as follows:

variable "team-configuration" {
  description = "Define the GitHub Teams organization configuration."
  type = map(object({
    entraid-group-name  = string
    gh-team-name        = string
    gh-team-description = optional(string, null)
    gh-team-privacy     = optional(string, "secret")
    gh-team-parent_id   = optional(string, null)
    gh-team-ldap-dn     = optional(string, null)
  }))
}
locals {
  ## Following local will iterate with the value entered in variable -> `team-configuration` and get the value entered to `entraid-group-name`.
  target_groups = {
    for k, v in var.team-configuration : k => {
      group_id = [for g in data.github_external_groups.idp-groups.external_groups : g.group_id if g.group_name == v.entraid-group-name][0]
    }
  }
}

Which ensured the data is validated from the following data block:

data "github_external_groups" "idp-groups" {}

It will then apply to the following resource mapping:

resource "github_emu_group_mapping" "map-team-with-idp" {
  for_each  = var.team-configuration

  team_slug = github_team.org-teams[each.key].slug
  group_id  = local.target_groups[each.key].group_id
}

followed by creating the github teams:

resource "github_team" "org-teams" {
  for_each    = var.team-configuration

  name        = each.value.gh-team-name
  description = each.value.gh-team-description
  privacy     = each.value.gh-team-privacy
}

That is the module done and how it works

---

Calling the module:

module "gh-teams" {
  source = "../modules/gh_teams"

  team-configuration = var.team-configuration
}

will eventually building the module successfully.

  # module.gh-teams.github_emu_group_mapping.map-team-with-idp["this"] will be created
  + resource "github_emu_group_mapping" "map-team-with-idp" {
      + etag      = (known after apply)
      + group_id  = 1234
      + id        = (known after apply)
      + team_slug = (known after apply)
    }

  # module.gh-teams.github_team.org-teams["this"] will be created
  + resource "github_team" "org-teams" {
      + create_default_maintainer = false
      + etag                      = (known after apply)
      + id                        = (known after apply)
      + members_count             = (known after apply)
      + name                      = "xyz"
      + node_id                   = (known after apply)
      + privacy                   = "secret"
      + slug                      = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

while I am pointing to the following organization in provider:

provider "github" {
  token = var.GITHUB_TOKEN
  owner = "x-org"
}

---

Help needed:

I want to provision Teams in multiple GitHub Organizations with the smoothest way possible and single state file as possible.

provider "github" {
  token = var.GITHUB_TOKEN
  alias = "this"
  owner = "x-org"
}
provider "github" {
  for_each = toset(var.orgs)
  token = var.GITHUB_TOKEN
  owner = each.key
}

Also to note that Tofu doesn't acknowledge my token as organization.

Any recommendations, so I can provision GitHub Organization Teams to specific Organization without all of them having applied the same configuration?

Upvotes: 1

Views: 73

Answers (1)

nmishin
nmishin

Reputation: 3064

I can suggest four options here - first one, to use TF stack, as Rui Jarimba mention in comments.

Second one - to use a different git branches to the different projects. Cons that it can be difficult to manage, you need to have some automation, and terraform modules should be managed outside of your main repo. But pros here, that you will have fully independent projects - mistakes in one branch won’t affect other branches.

And third one is to use Terragrunt. With Terragrunt, you can organize a flat structure with your projects, using a single branch. It will be only one branch and it should be simpler to use than branching strategy. The only downside I see is that Terragrunt is one more tool, which bring one more layer of obstruction, and one more tool that you should learn.

You can also check Terraform Workspaces, but I don't think it will be suitable here, for my understanding it works better for small number of projects.

Upvotes: 0

Related Questions