integrations / terraform-provider-github

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

[BUG]: github_enterprise_organization and github_organization_settings deployment conflict #2249

Open dejongm opened 2 months ago

dejongm commented 2 months ago

Expected Behavior

No errors should occur when deploying a github_enterprise_organization followed by github_organization_settings.

Actual Behavior

When deploying both resources github_enterprise_organization and github_organization_settings deployment in the same apply, we get the following error:

╷
│ Error: PATCH https://api.github.com/orgs/xxxxxx: 422  []
│ 
│   with module.organization["xxxxxx"].github_organization_settings.main,
│   on modules/organization/main.tf line 101, in resource "github_organization_settings" "main":
│  101: resource "github_organization_settings" "main" {
│ 
╵
ERRO[0021] 1 error occurred:
        * exit status 1

This seems to be because the setting for billing_email is managed at the enterprise level and cannot be modified at the org level. Importing the settings and adding a lifecycle policy is a workaround after the resource has been deployed.

lifecycle {
  ignore_changes = ["billing_email"]
}

Marking the billing_email field in github_organization_settings as optional should resolve this issue.

Terraform Version

Terraform 1.5.7 on Linux AMD64 using provider 6.2.1

Affected Resource(s)

Terraform Configuration Files

data "github_enterprise" "main" {
  slug = "xxxxxx"
}

resource "github_enterprise_organization" "main" {
  for_each = local.organizations
  enterprise_id = data.github_enterprise.main.id
  name          = each.key
  display_name  = each.value.settings.name
  description   = each.value.settings.description
  billing_email = each.value.settings.billing_email
  admin_logins  = each.value.membership.admin
}

resource "github_organization_settings" "main" {
    billing_email = lookup(local.settings, "billing_email", null)
    blog = lookup(local.settings, "blog", null)
    email = lookup(local.settings, "email", null)
    twitter_username = lookup(local.settings, "twitter_username", null)
    name = lookup(local.settings, "name", null)
    description =lookup(local.settings, "description", null)
    has_organization_projects = lookup(local.settings, "has_organization_projects", null)
    has_repository_projects = lookup(local.settings, "has_repository_projects", null)
    default_repository_permission = lookup(local.settings, "default_repository_permission", null)
    members_can_create_repositories = lookup(local.settings, "members_can_create_repositories", null)
    members_can_create_public_repositories = lookup(local.settings, "members_can_create_public_repositories", null)
    members_can_create_private_repositories = lookup(local.settings, "members_can_create_private_repositories", null)
    members_can_create_internal_repositories = lookup(local.settings, "members_can_create_internal_repositories", null)
    members_can_create_pages = lookup(local.settings, "members_can_create_pages", null)
    members_can_create_public_pages = lookup(local.settings, "members_can_create_public_pages", null)
    members_can_create_private_pages = lookup(local.settings, "members_can_create_private_pages", null)
    members_can_fork_private_repositories = lookup(local.settings, "members_can_fork_private_repositories", null)
    web_commit_signoff_required = lookup(local.settings, "web_commit_signoff_required", null)
    advanced_security_enabled_for_new_repositories = lookup(local.settings, "advanced_security_enabled_for_new_repositories", null)
    dependabot_alerts_enabled_for_new_repositories=  lookup(local.settings, "dependabot_alerts_enabled_for_new_repositories", null)
    dependabot_security_updates_enabled_for_new_repositories = lookup(local.settings, "dependabot_security_updates_enabled_for_new_repositories", null)
    dependency_graph_enabled_for_new_repositories = lookup(local.settings, "dependency_graph_enabled_for_new_repositories", null)
    secret_scanning_enabled_for_new_repositories = lookup(local.settings, "secret_scanning_enabled_for_new_repositories", null)
    secret_scanning_push_protection_enabled_for_new_repositories = lookup(local.settings, "secret_scanning_push_protection_enabled_for_new_repositories", null)
    lifecycle {
      ignore_changes = [
        "billing_email",
        "name",
        "description"
      ]
    }
}

Steps to Reproduce

No response

Debug Output

No response

Panic Output

No response

Code of Conduct

ljw4010 commented 1 month ago

Expected Behavior

No errors should occur when deploying a github_enterprise_organization followed by github_organization_settings.

Actual Behavior

When deploying both resources github_enterprise_organization and github_organization_settings deployment in the same apply, we get the following error:

╷
│ Error: PATCH https://api.github.com/orgs/xxxxxx: 422  []
│ 
│   with module.organization["xxxxxx"].github_organization_settings.main,
│   on modules/organization/main.tf line 101, in resource "github_organization_settings" "main":
│  101: resource "github_organization_settings" "main" {
│ 
╵
ERRO[0021] 1 error occurred:
        * exit status 1

This seems to be because the setting for billing_email is managed at the enterprise level and cannot be modified at the org level. Importing the settings and adding a lifecycle policy is a workaround after the resource has been deployed.

lifecycle {
  ignore_changes = ["billing_email"]
}

Marking the billing_email field in github_organization_settings as optional should resolve this issue.

Terraform Version

Terraform 1.5.7 on Linux AMD64 using provider 6.2.1

Affected Resource(s)

  • github_enterprise_organization
  • github_organization_settings deployment

Terraform Configuration Files

data "github_enterprise" "main" {
  slug = "xxxxxx"
}

resource "github_enterprise_organization" "main" {
  for_each = local.organizations
  enterprise_id = data.github_enterprise.main.id
  name          = each.key
  display_name  = each.value.settings.name
  description   = each.value.settings.description
  billing_email = each.value.settings.billing_email
  admin_logins  = each.value.membership.admin
}

resource "github_organization_settings" "main" {
    billing_email = lookup(local.settings, "billing_email", null)
    blog = lookup(local.settings, "blog", null)
    email = lookup(local.settings, "email", null)
    twitter_username = lookup(local.settings, "twitter_username", null)
    name = lookup(local.settings, "name", null)
    description =lookup(local.settings, "description", null)
    has_organization_projects = lookup(local.settings, "has_organization_projects", null)
    has_repository_projects = lookup(local.settings, "has_repository_projects", null)
    default_repository_permission = lookup(local.settings, "default_repository_permission", null)
    members_can_create_repositories = lookup(local.settings, "members_can_create_repositories", null)
    members_can_create_public_repositories = lookup(local.settings, "members_can_create_public_repositories", null)
    members_can_create_private_repositories = lookup(local.settings, "members_can_create_private_repositories", null)
    members_can_create_internal_repositories = lookup(local.settings, "members_can_create_internal_repositories", null)
    members_can_create_pages = lookup(local.settings, "members_can_create_pages", null)
    members_can_create_public_pages = lookup(local.settings, "members_can_create_public_pages", null)
    members_can_create_private_pages = lookup(local.settings, "members_can_create_private_pages", null)
    members_can_fork_private_repositories = lookup(local.settings, "members_can_fork_private_repositories", null)
    web_commit_signoff_required = lookup(local.settings, "web_commit_signoff_required", null)
    advanced_security_enabled_for_new_repositories = lookup(local.settings, "advanced_security_enabled_for_new_repositories", null)
    dependabot_alerts_enabled_for_new_repositories=  lookup(local.settings, "dependabot_alerts_enabled_for_new_repositories", null)
    dependabot_security_updates_enabled_for_new_repositories = lookup(local.settings, "dependabot_security_updates_enabled_for_new_repositories", null)
    dependency_graph_enabled_for_new_repositories = lookup(local.settings, "dependency_graph_enabled_for_new_repositories", null)
    secret_scanning_enabled_for_new_repositories = lookup(local.settings, "secret_scanning_enabled_for_new_repositories", null)
    secret_scanning_push_protection_enabled_for_new_repositories = lookup(local.settings, "secret_scanning_push_protection_enabled_for_new_repositories", null)
    lifecycle {
      ignore_changes = [
        "billing_email",
        "name",
        "description"
      ]
    }
}

Steps to Reproduce

No response

Debug Output

No response

Panic Output

No response

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

Hey Friends, Just asking you a question, when you use this provider to create an enterprise organization, do you use PAT token or something else? What permissions are required when using PAT token? my error shows : "xxxx user does not have the correct permissions to execute CreateEnterpriseOrganization"