integrations / terraform-provider-github

Terraform GitHub provider
https://www.terraform.io/docs/providers/github/
MIT License
907 stars 748 forks source link

github_repository resource fails when visibility is set to private. #1440

Closed bimlendu closed 6 months ago

bimlendu commented 1 year ago

With the following terraform files, resource github_repository.private fails to create with 500 error.

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "= 5.12.0"
    }
  }
}

provider "github" {}

resource "github_repository" "private" {
  name       = "test-private-visibility"
  visibility = "private"
}

resource "github_repository" "explicit-public" {
  name       = "test-explicit-public-visibility"
  visibility = "public"
}

resource "github_repository" "public" {
  name = "test-public-visibility"
}

Init logs

bimlendu@Bimlendus-MacBook-Air gh-bug % terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of integrations/github from the dependency lock file
- Using previously-installed integrations/github v5.12.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Plan output

bimlendu@Bimlendus-MacBook-Air gh-bug % terraform plan -out=tfplan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # github_repository.explicit-public will be created
  + resource "github_repository" "explicit-public" {
      + allow_auto_merge            = false
      + allow_merge_commit          = true
      + allow_rebase_merge          = true
      + allow_squash_merge          = true
      + archived                    = false
      + default_branch              = (known after apply)
      + delete_branch_on_merge      = false
      + etag                        = (known after apply)
      + full_name                   = (known after apply)
      + git_clone_url               = (known after apply)
      + html_url                    = (known after apply)
      + http_clone_url              = (known after apply)
      + id                          = (known after apply)
      + merge_commit_message        = "PR_TITLE"
      + merge_commit_title          = "MERGE_MESSAGE"
      + name                        = "test-explicit-public-visibility"
      + node_id                     = (known after apply)
      + private                     = (known after apply)
      + repo_id                     = (known after apply)
      + squash_merge_commit_message = "COMMIT_MESSAGES"
      + squash_merge_commit_title   = "COMMIT_OR_PR_TITLE"
      + ssh_clone_url               = (known after apply)
      + svn_url                     = (known after apply)
      + visibility                  = "public"
    }

  # github_repository.private will be created
  + resource "github_repository" "private" {
      + allow_auto_merge            = false
      + allow_merge_commit          = true
      + allow_rebase_merge          = true
      + allow_squash_merge          = true
      + archived                    = false
      + default_branch              = (known after apply)
      + delete_branch_on_merge      = false
      + etag                        = (known after apply)
      + full_name                   = (known after apply)
      + git_clone_url               = (known after apply)
      + html_url                    = (known after apply)
      + http_clone_url              = (known after apply)
      + id                          = (known after apply)
      + merge_commit_message        = "PR_TITLE"
      + merge_commit_title          = "MERGE_MESSAGE"
      + name                        = "test-private-visibility"
      + node_id                     = (known after apply)
      + private                     = (known after apply)
      + repo_id                     = (known after apply)
      + squash_merge_commit_message = "COMMIT_MESSAGES"
      + squash_merge_commit_title   = "COMMIT_OR_PR_TITLE"
      + ssh_clone_url               = (known after apply)
      + svn_url                     = (known after apply)
      + visibility                  = "private"
    }

  # github_repository.public will be created
  + resource "github_repository" "public" {
      + allow_auto_merge            = false
      + allow_merge_commit          = true
      + allow_rebase_merge          = true
      + allow_squash_merge          = true
      + archived                    = false
      + default_branch              = (known after apply)
      + delete_branch_on_merge      = false
      + etag                        = (known after apply)
      + full_name                   = (known after apply)
      + git_clone_url               = (known after apply)
      + html_url                    = (known after apply)
      + http_clone_url              = (known after apply)
      + id                          = (known after apply)
      + merge_commit_message        = "PR_TITLE"
      + merge_commit_title          = "MERGE_MESSAGE"
      + name                        = "test-public-visibility"
      + node_id                     = (known after apply)
      + private                     = (known after apply)
      + repo_id                     = (known after apply)
      + squash_merge_commit_message = "COMMIT_MESSAGES"
      + squash_merge_commit_title   = "COMMIT_OR_PR_TITLE"
      + ssh_clone_url               = (known after apply)
      + svn_url                     = (known after apply)
      + visibility                  = (known after apply)
    }

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

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

Apply output

bimlendu@Bimlendus-MacBook-Air gh-bug % terraform apply "tfplan"
github_repository.explicit-public: Creating...
github_repository.private: Creating...
github_repository.public: Creating...
github_repository.explicit-public: Still creating... [10s elapsed]
github_repository.public: Still creating... [10s elapsed]
github_repository.public: Creation complete after 13s [id=test-public-visibility]
github_repository.explicit-public: Creation complete after 13s [id=test-explicit-public-visibility]
╷
│ Error: POST https://api.github.com/user/repos: 500  []
│
│   with github_repository.private,
│   on main.tf line 1, in resource "github_repository" "private":
│    1: resource "github_repository" "private" {
│
╵

Directly calling the github API with the minimal payload works as expected and the repo gets created.

bimlendu@Bimlendus-MacBook-Air gh-bug % cat payload.json
{
    "name": "test-api-visibility-private",
    "visibility": "private"
}%
bimlendu@Bimlendus-MacBook-Air gh-bug % curl \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_TOKEN"\
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/user/repos \
  -d @payload.json
{
  "id": 579447057,
  "node_id": "R_kgDOIompEQ",
  "name": "test-api-visibility-private",
  "full_name": "bimlendu/test-api-visibility-private",
  "private": false,
  "owner": {
    "login": "bimlendu",
    "id": 1873727,
...
}
bimlendu commented 1 year ago

And looks like visibility is not a valid parameter in POST /user/repos API.

https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-for-the-authenticated-user

visibility is allowed for creating organization repos though.

https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-an-organization-repository

But removing visibility and using private attrbiute in terraform results in a deprecation warning. Even though I am creating a personal repo.

╷
│ Warning: "private": [DEPRECATED] use visibility instead
│
│   with github_repository.private,
│   on main.tf line 1, in resource "github_repository" "private":
│    1: resource "github_repository" "private" {
│
│ (and one more similar warning elsewhere)
stephenh-dev commented 1 year ago

Not sure if it's the same, but I ran into this issue when using the "Fine-grained personal access tokens (beta)" with this provider. As described on the GitHub docs (Creating a personal access token), they don't support creating a repository for the authenticated user.

Switching to use a PAT created with "Personal access tokens (classic)" fixed the issue for me (even when using the visibility parameter). Hope that helps.

kfcampbell commented 1 year ago

Oh, this is interesting! I've also run into obnoxious situations where the beta fine-grained tokens don't work...hopefully those get full support soon.

github-actions[bot] commented 7 months ago

👋 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!