Invalid provider configuration reference

Hello Team,

I have a requirement to clone the github repository from one github organization to multiple github organizations, organization details are in the following yml format.
during plan, we are receiving the following error, myaccount is owner for all github orgs and using owner token to clone repo, can you please help me here?

ERROR: Invalid provider configuration reference 
   
   on man.tf line 43, in module "clone_github_repo":
   43:  providers  = { github = each.value.github_provider }
  

CODE:

orgs_file.yml:

==============
---
- organizations:
     - name: myorg1
	   github_provider: "github.MYORG1"
	 - name: myorg2
	   github_provider: "github.MYORG2"
locals {
   rawdata = yamldecode(file("orgs_file.yml"))
   org_list = local.rawdata.organizations
}	   

provider "github" {
   alias = MYORG1
   owner = myorg1
}
provider "github" {
   alias = MYORG2
   owner = myorg2
}

main.tf:

module "clone_github_repo" {

  source  = "./module/clone_repo/"
  for_each = { for k,v in local.org_list : k => v }
  providers = { github = each.value.github_provider }
  github_orgname = "${each.value.name}"
}

Hi @vburamdo,

Provider configuration references are not strings, so it isn’t possible to load a string from a YAML file and pretend it is a reference to a provider configuration.

Terraform needs to associate resources with provider configurations before evaluating any expressions, and so it is generally not possible to make a dynamic decision about provider configuration like this.

What you can do is write an expression to transform that flat collection of objects from the yaml into two separate collections, where each one only comtains the entries for one of the provider configurations, and then write one module block for each where you specify the appropriate provider configuration statically in each one.

The effect of this is that each module will contain its own separate resource(s) and Terraform can see which provider configuration each one belongs to, and so the only thing that is decided dynamically is how many instances there will be is each of those resources, which is what for_each is designed to handle.

Hi @apparentlymart , Thank you , It would be great if you can provide some sample for the reference.

Hi @vburamdo,

Looking at your question again now I’m realizing that something isn’t clear to me but I missed it the first time I read your comment.

You have a data structure which contains a list of organizations, and you’re using that as the for_each collection for a module block, but the module itself seems to be called “clone repo” and so when I read the first time I assumed you would have one instance of it for each repository, not for each organization. Since there are not actually any repositories mentioned in your example, I conclude that I misunderstood what you intend to achieve here.

Is the example you shared complete? Is there something more to the real module "clone_github_repo" block to specify repositories?


Taking the configuration you shared exactly as you presented it, without any other assumed requirements, the solution I suggested of switching to a separate module block per provider actually doesn’t require any significant transformation of the data structure at all, because you already have one element in your collection for each of your provider configurations. You therefore don’t need a YAML file or for_each at all to achieve this result; you can just write a pair of simple module blocks, like this:

provider "github" {
   alias = MYORG1
   owner = myorg1
}
provider "github" {
   alias = MYORG2
   owner = myorg2
}

module "clone_github_repo_org1" {
  source = "./module/clone_repo"
  providers = {
    github = github.MYORG1
  }

  github_orgname = "myorg1"
}

module "clone_github_repo_org2" {
  source = "./module/clone_repo"
  providers = {
    github = github.MYORG2
  }

  github_orgname = "myorg2"
}

@apparentlymart , Thank you.