integrations / terraform-provider-github

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

[BUG]: Github Repository Template is also "applied" to existing repositories #2090

Open StefanLobbenmeierObjego opened 8 months ago

StefanLobbenmeierObjego commented 8 months ago

Expected Behavior

Template is only used for creation of new repositories. Applying a template to an existing repository does nothing.

Actual Behavior

template is also applied to existing repositories this seems to also stick for some time

but then after a few hours, terraform will see this as a difference and apply the template to existing repositories again

Terraform Version

v5.44.0

Affected Resource(s)

github_repository

Terraform Configuration Files

variable "repos" {
  type = list(object({
    name                = string
    owners              = optional(set(string), [])
    admins              = optional(set(string), [])
    enable_environments = optional(bool, true)
    enable_actions      = optional(bool, true)
    checks              = optional(set(string), [])
    type                = optional(string, "default")
    is_template         = optional(bool, false)
  }))
}

repos = [
  { name = "objego-client" }
]

locals {
  repos_by_name = {
    for r in var.repos : r.name => r
  }
}

resource "github_repository" "repository" {
  for_each = local.repos_by_name

  name       = each.key

  # this was added later, so new repos are set up with a template
  template {
    owner      = "objego"
    repository = "repository-template"
  }

}

Steps to Reproduce

Create a repository using terraform without a template Change the repository configuration in terraform to include a template

Debug Output

# github_repository.repository["objego-client"] will be updated in-place
  ~ resource "github_repository" "repository" {
        id                          = "objego-client"
        name                        = "objego-client"
        # (34 unchanged attributes hidden)

      + template {
          + include_all_branches = false
          + owner                = "objego"
          + repository           = "repository-template"
        }
    }

Panic Output

No response

Code of Conduct

arunsathiya commented 7 months ago

Am I understanding correctly that with the template configuration, if the repository already exists, the request should fail and show an appropriate error?

StefanLobbenmeierObjego commented 7 months ago

Actually I would prefer it to be ignored for repository, since it makes it easier to manage new and existing repositories like this. It should just be considered for repository creation.

As a workaround for now, I could add an extra parameter to my repository configuration whether this is a new repository and only apply the template in that case, but that is a really odd thing to store in configuration.

nuclearsandwich commented 5 months ago

I was perusing the GitHub documentation to see whether the template repository used to create a repository is persisted after creation and the answer is, perhaps regrettably, yes but it's only visible in the GraphQL v4 API. (Edit: Nope, it's there in the REST API as well, I just didn't have a template repository to check against)

I think this means that the behavior that @StefanLobbenmeierObjego prefers: template blocks are used to initialize a non-existent repository and ignored afterwards is preferred and probably the most straightforward thing to implement.

If this provider were ever to switch to using the GraphQL API, the template repository provenance of a repository would be visible and we'd have to then decide how much to care about it.

I can imagine a use-case where different behavior is configured if a repository was created from a specific template or not but I have no such use case as I want to treat all of mine the same whether they're generated from a template or from scratch.

In my case, I'm managing an organization of 615 repositories (and growing) that are all managed in a massive for_each as they are all meant to be governed the same way. I've only just introduced the template repository so these 615 are all without a template and there will still be non-template repositories imported into this process on occasion as well. So having some way to handle this cleanly would cut down on plan churn in a big way.