Nested loop (using github provider)

Hi @HormyAJP,

The main tools for dealing with this sort of situation are for expressions and the flatten function. With these two features, we can transform collections and flatten out nested collections for use with the repetition constructs like resource for_each.

You didn’t show how you want the collaborators to be represented in your configuration structure but I’m going to assume a variable defined like this for the sake of example:

variable "repositories" {
  type = map(object({
    allow_merge_commit = bool
    allow_squash_merge = bool
    allow_rebase_merge = bool
    branch_protection = object({
      required_approving_review_count = number
    })

    # Map from username to permission level,
    # like {"bobsmith" = "pull"}.
    collaborator_permissions = map(string)
  }))
}

To transform this into a flat set of (repository, username, permission) structures we’ll use flatten with some for expressions:

locals {
  repo_collaborators = flatten([
    for rn, r in var.repositories : [
      for un, pn in r.collaborator_permissions : {
        repo       = rn
        username   = u
        permission = pn
      }
    ]
  ])
}

resource "github_repository_collaborator" "example" {
  # Each instance must have a unique key, so we'll
  # construct them by concatenating the repository
  # name and the username.
  for_each = {
    for rc in local.repo_collaborators :
    "${rc.repo}:${rc.username}" => rc
  }

  repository = each.value.repo
  username   = each.value.username
  permission = each.value.permission
}

This will produce resource instances with addresses like github_repository_collaborator.example["repository_1:bobsmith"], allowing Terraform to correlate any changes to the collaborator permissions maps with the appropriate resource instances for ongoing updates.