integrations / terraform-provider-github

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

[BUG]: Provider produced inconsistent result after apply #1999

Closed prashant-rathi closed 2 months ago

prashant-rathi commented 1 year ago

Expected Behavior

We are using Github module to setup the Github repository where we pull a few files from one repository and write it to second repository.

We use data resource to pull the file

data "github_repository_file" "gitignore" {
  provider    = github.my
  repository  = "my-github-repo-1"
  file        = "my_dir/dot-gitignore"
  branch      = var.archetypes_repo_branch_name
}

And github_repository_file resource to write this to another repo

resource "github_repository_file" "gitignore" {
  repository          = local.repository_name
  file                = ".gitignore"
  content             = data.github_repository_file.gitignore.content
  commit_author       = local.commit_author
  commit_email        = local.commit_email
  commit_message      = local.commit_message
  overwrite_on_create = true
}

Out of 100 tries, around 10-20 times we would get inconsistent result error otherwise it works fine. We were not able to figure out the issue. Should we add depends_on between data and another resource that is writing to new repo?

Actual Behavior

The deployment failed with inconsistent result error while writing file to the Github repo.

Terraform Version

Terraform v1.5.0

Github v >5 <6

Affected Resource(s)

Terraform Configuration Files

#version.tf

terraform {
  required_version = ">= 1.3, <1.6"

  required_providers {
    github = {
      source  = "integrations/github"
      version = ">=5, <6"
    }
  }
}

Steps to Reproduce

No response

Debug Output

Provider produced inconsistent result after apply

When applying changes to
 module.repository.github_repository_file.gitignore, provider
 "module.repository.provider[\"registry.terraform.io/integrations/github\"]"
 produced an unexpected new value: Root resource was present, but now
 absent.
 This is a bug in the provider, which should be reported in the provider's
 own issue tracker.
Operation failed: failed running terraform apply (exit 1)

Panic Output

No response

Code of Conduct

github-actions[bot] commented 1 year ago

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

scott-doyland-burrows commented 1 year ago

It's hard to tell from the two resources you supplied whether there is a missed dependency.

This config:

resource "github_repository_file" "gitignore" { 
repository = local.repository_name
...
}

shows you are using a local variable value for the repo name. Should this actually be dependent on the repo creation, eg:

resource "github_repository_file" "gitignore" { 
repository = github_repository.example.repo_id
...
}
prashant-rathi commented 1 year ago

It's hard to tell from the two resources you supplied whether there is a missed dependency.

This config:

resource "github_repository_file" "gitignore" { 
repository = local.repository_name
...
}

shows you are using a local variable value for the repo name. Should this actually be dependent on the repo creation, eg:

resource "github_repository_file" "gitignore" { 
repository = github_repository.example.repo_id
...
}

Hey @scott-doyland-burrows

Thanks for the response and sorry for the confusion. I don't think that is the issue. As explained in the ticket we pull files from one Github Org repository and write it to another repository that is why both of them are kept different. Also, code works fine most of the times but the success rate is not 100% because of inconsistency of the provider.

To give you a bit more details: Here is the sanitised code.

data.tf

data "github_repository" "this" {
  full_name = "myorg1/myrepo1"
}

######## Pull .gitignore file content #########
data "github_repository_file" "gitignore" {
  provider    = github.serverless
  repository  = "my-personal-repo"
  file        = "dot-gitignore"
  branch      = "main"
}

######## Pull .prettierignore file content #########
data "github_repository_file" "prettierignore" {
  provider    = github.serverless
  repository  = "my-personal-repo"
  file        = "dot-prettierignore"
  branch      = "main"
}

######## Pull .prettierrc.json file content #########
data "github_repository_file" "prettierjson" {
  provider    = github.serverless
  repository  = "my-personal-repo"
  file        = "dot-prettierrc.json"
  branch      = "main"
}

locals.tf

locals {
  commit_author   = "svc-account"
  commit_email    = "myteam@myorg.com"
  commit_message  = "chore: managed by Terraform [skip ci]"
  repository_id   = data.github_repository.this.node_id
  repository_name = data.github_repository.this.name
}

providers.tf

provider "github" {
  owner = "myorg"
}

// Since we are pulling files from one org and writing to another we have to keep separate provider section with alias 
provider "github" {
  alias       = "serverless"
  owner       = "MY-Internal"
  token       = var.github_internal_token
}

versions.tf

terraform {
  required_version = ">= 1.3, <1.6"

  required_providers {
    github = {
      source  = "integrations/github"
      version = ">=5, <6"
    }
  }
}

main.tf

resource "github_repository_file" "gitignore" {
  repository          = local.repository_name
  file                = ".gitignore"
  content             = data.github_repository_file.gitignore.content
  commit_author       = local.commit_author
  commit_email        = local.commit_email
  commit_message      = local.commit_message
  overwrite_on_create = true
}

resource "github_repository_file" "prettierignore" {
  repository          = local.repository_name
  file                = ".prettierignore"
  content             = data.github_repository_file.prettierignore.content
  commit_author       = local.commit_author
  commit_email        = local.commit_email
  commit_message      = local.commit_message
  overwrite_on_create = true
}

resource "github_repository_file" "prettierjson" {
  repository          = local.repository_name
  file                = ".prettierrc.json"
  content             = data.github_repository_file.prettierjson.content
  commit_author       = local.commit_author
  commit_email        = local.commit_email
  commit_message      = local.commit_message
  overwrite_on_create = true
}
github-actions[bot] commented 3 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!