Terraforming GitHub repositories to get basic features like branch protection, disabling wiki/projects/etc, and configuring account-wide defaults.
Repositories are discovered with the GitHub search query user:<github_owner> archived:false is:public. Entries in the repositories input override discovered metadata or compliance options for individual repositories.
To safely start with a single repository, pass -var='managed_repository_names=["app-test-py"]'. This set is the complete desired scope for the current Terraform state, so rollout must be cumulative: add repository names without removing ones already applied. For example, expand the next run to -var='managed_repository_names=["app-test-py", "iac-ci"]'. Removing a previously managed name plans destruction and is blocked by prevent_destroy. An empty set manages every discovered repository.
- Ensure default branch is "main"
- Disable Wikis
- Disable Discussions
- Disable Projects
- Keep Issues enabled
- Configure template-repository status per repository
- Preserve existing repository descriptions
- For private
iac-repositories, only users with access can create pull requests
- Allow auto-merge
- Allow merge, squash, and rebase PR merge methods
- Require the
RequiredGitHub Actions status check before changes can reachmain - Automatically delete head branches
- Add "Protect Main"
- Allow repository administrators to bypass "Protect Main"
- Require pull requests with no minimum approving review count
- Use the
Requiredstatus check from GitHub Actions as the merge gate for every managed repository
- Allow all actions and reusable workflows
- Require approval for all external contributors on workflows
- Workflow permissions allowed to read repository contents and packages permissions
- Add
APP_CLIENT_IDas an Actions variable andAPP_PRIVATE_KEYas an Actions secret toapp-*andiac-*repositories - Add
APP_PRIVATE_KEYas a Dependabot secret toapp-*andiac-*repositories - Keep the GitHub App installation ID internal to Terraform; do not publish it as a repository variable or secret
- Add all development and production SSH secrets to Actions for
iac-ansibleandiac-cd - Add development SSH secrets to Dependabot for
iac-cd
- Complete webhook URL is read from OCI Secrets
- GitHub App private key and webhook URL are pulled from OCI Secrets Management
iac-ansibleandiac-cdreceive all configured development and production SSH Actions secretsiac-cdalso receives the three development SSH secrets for Dependabot
- Repository is applied via GitHub workflow on change
terraform.tfvars is intentionally committed. It contains repository policy inputs, public GitHub identifiers, and OCI Secret OCIDs, but never secret contents. OCI returns secret bundle content as Base64, and Terraform decodes the CURRENT version only while running.
Authenticate the OCI provider using ~/.oci/config or workload identity. Terraform reads the GitHub App private key from OCI Secrets and uses the configured App ID and installation ID to authenticate the GitHub provider. No GitHub credential is required in .env. Then run:
terraform init
terraform plan
terraform applyThe OCI principal running Terraform needs read secret-bundles permission for the compartment containing the GitHub App private-key and webhook-URL secrets.
Public, non-archived repositories owned by github_owner are discovered automatically and imported during the first apply. Add an explicit entry only to override repository-specific settings:
repositories = {
"iac-example" = {
existing = true
}
}After adding it to the map, review and apply:
terraform plan
terraform applySet existing = false only when Terraform should create a repository that does not exist yet. If an existing repository already has a ruleset or webhook that should be adopted, import that separate resource to avoid creating a duplicate. Webhooks require their GitHub numeric hook ID, while rulesets require their numeric ruleset ID. Singleton settings such as Actions permissions and workflow permissions are updated in place by their respective resources.
The Terraform resources are ready for automation, but the workflow needs two deployment-specific decisions before it can be safely added: the remote state backend and the OCI authentication method. Prefer GitHub OIDC/workload identity over storing a long-lived OCI API private key in GitHub. The GitHub credential used by the workflow must have administration access to every managed repository; the default per-repository GITHUB_TOKEN normally cannot administer sibling repositories.