Skip to content

feat: add opt-in separate-App enterprise organization bootstrap - #3700

Draft
luth2 wants to merge 3 commits into
integrations:mainfrom
luth2:feat/enterprise-app-lifecycle
Draft

luth2 wants to merge 3 commits into
integrations:mainfrom
luth2:feat/enterprise-app-lifecycle

Conversation

@luth2

@luth2 luth2 commented Oct 23, 2026

Copy link
Copy Markdown

Refs #3699. Related: #3109, #2886.


Before the change?

Enterprise installation credentials can create an organization but cannot read its organization-scoped fields. Default owner discovery also treats the enterprise slug as a user. Installing an organization App does not extend the enterprise token.

After the change?

This draft explores an explicit enterprise_app_auth mode with separate creation, installer and automation credentials. It retains identity before bootstrap, then uses verified organization installations for Read/Import. The opt-in mode does not upgrade or unsuspend existing installations and blocks Update/Delete. Default resource routing remains unchanged. Installation-token refresh additionally gains operation cancellation and a total timeout while retaining renewal.

This overlaps #3671 (same-App lifecycle routing) and #3535 (installation resources). Maintainer agreement on the separate-App API and ownership boundary is needed before this should be considered merge-ready. #3697 remains a separate billing fix.

Branch: https://github.com/luth2/terraform-provider-github/tree/feat/enterprise-app-lifecycle

Pull request checklist

  • Schema migrations have been created if needed: not required for the additive opt-in provider block and computed installation identifier; existing addresses remain.
  • Tests for the changes have been added (unit and SDK protocol tests).
  • Docs have been reviewed and added / updated, including generated docs and example.

Does this introduce a breaking change?

  • Yes
  • No

The new mode is opt-in. Its unsupported Update/Delete operations fail before API mutation. This limitation is intentional and is not a claim of full CRUD support.

Validation and remaining gates

  • Go 1.26.10: go test ./... -skip '^TestAcc' -parallel=4 -count=1 -timeout=120s passed.
  • Mocked API and SDK protocol tests cover pagination, identity/permission checks, partial-create state retention, read/import isolation and token-body stall recovery.
  • Live local plan with Terraform 1.17.0 for two existing orgs and settings: 4 to import, 0 to add, 2 to change, 0 to destroy; no apply or import executed.
  • Enterprise creation and App installation were verified via separate API calls, not end-to-end Terraform Create with this implementation.
  • Missing: approved live Create/apply and Terraform Core recovery test, verified Update/Delete contract, real HCP pilot and maintainer approval of the API shape.

AI assistance

This implementation and draft were substantially AI-assisted with GitHub Copilot. Automated tests and live read/import plans were run, but personal contributor review and testing required by CONTRIBUTING.md are not asserted on the contributor's behalf. Keep this PR in draft until that review is completed.


Lucas Theisen added 2 commits October 23, 2026 16:47
Use operation-scoped cancellation and a total token-request timeout to prevent stalled refreshes from blocking resource operations. Preserve renewable token caching.
Separate creation, installer and organization App credentials for enterprise organization creation, bootstrap, read and import. Retain identity on partial failure. Block unverified update and delete operations in the opt-in mode.

Refs integrations#3109
@github-actions

Copy link
Copy Markdown

👋 Hi, and thank you for this contribution!

This repo is maintained by GitHub and community members on a best-effort basis. We'll get to this as soon as we can.

You can help us prioritize by joining the discussion on open issues and PRs, sharing details on the changes you need, and reviewing other contributions.


🤖 This is an automated message.

@github-actions github-actions Bot added the Type: Feature New feature or request label Oct 23, 2026
@luth2

luth2 commented Oct 23, 2026

Copy link
Copy Markdown
Author

Fixes #3699

Prove successful bootstrap and tainted-create reconciliation with a real Terraform CLI and mocked GitHub API. Require explicit TF_CORE_TEST_BINARY so normal unit runs stay independent of a local CLI.

Refs integrations#3699
@luth2

luth2 commented Oct 23, 2026

Copy link
Copy Markdown
Author

Validation update

The previously missing live Create/bootstrap and Terraform Core recovery
checks have now been completed.

Live pilot

  • Created one explicitly authorized organization on GitHub Enterprise Cloud
    with Data Residency using only the three separate GitHub Apps.
  • Terraform 1.16.4 saved plan: 1 add, 0 change, 0 destroy.
  • Applying that exact plan successfully created the organization and
    installed the automation App.
  • Fresh discovery verified Enterprise membership, organization identity
    and an active automation installation.
  • A subsequent lifecycle plan reported no changes.
  • The organization is retained in an isolated local state. No existing
    organization, Settings resource or HCP state was changed.

Regression coverage
Commit 5480389 adds opt-in tests using a real Terraform CLI against a
local mocked GitHub API. Both scenarios pass with Terraform 1.16.4:

  • Successful Create/bootstrap followed by a no-op plan.
  • Failed bootstrap retains the organization ID, database ID and tainted
    state. prevent_destroy blocks replacement; after verified access is
    restored, an explicit operator untaint allows a no-op plan without
    repeating Create.

No deliberate live failure or live untaint was performed.

The full offline provider suite passed with Go 1.26.10, including these
Core tests when TF_CORE_TEST_BINARY points to Terraform 1.16.4:

go test ./... -skip '^TestAcc' -parallel=4 -count=1 -timeout=120s

Remaining limitations

  • Update/Delete remain blocked in the opt-in App mode.
  • The follow-up Settings configuration was rendered only, not applied.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant