Destroy-Time Failures when Terraforming GitHub
In my experience building AT-AT modules — Terraform modules designed to “automate the automation” — I’ve found that automating infrastructure and tools must extend to the automation setup itself. The silent “W” in “automation” is deliberate; it’s about creating systems that minimize manual intervention even in the deployment of automation processes. These modules enable teams to quickly provision everything from cloud skeleton environments to fully integrated automation pipelines using platforms like Azure DevOps and GitHub Actions.
However, no automation journey is without its hiccups. One challenge I encountered recently involved provisioning and managing a GitHub repository within the context of an organization using the Terraform GitHub Provider. Here’s how I solved it, along with some insights to help you automate more effectively.
Logging in with GitHub CLI
Before diving into Terraform, ensure you’re authenticated with the GitHub CLI. This is especially important if you’re interacting with private repositories or GitHub organizations.
gh auth login
This command prompts you to authenticate with your GitHub credentials, setting the stage for Terraform to manage your GitHub resources seamlessly.
Setting up the GitHub Provider
When working within a GitHub organization, it’s crucial to inform Terraform about the organization you’re working with. In the GitHub Terraform Provider, this is done by setting the owner attribute to the name of your GitHub organization.
provider "github" {
owner = var.github_organization
}
This declaration ensures Terraform directs its operations to the correct organization. Forgetting this step can result in Terraform trying to operate on your personal GitHub account by default.
Creating a Repository
With the provider configured, creating a repository becomes straightforward. Here’s an example Terraform resource to create a private repository:
resource "github_repository" "main" {
name = var.repository_name
description = "My awesome codebase"
visibility = "private"
auto_init = true
}
This snippet automates the creation of a new private repository within your GitHub organization, initializing it with a default README file.
The Issue with Destroying Repositories
While provisioning worked seamlessly, I encountered an issue during the destroy phase. Terraform attempted to delete the repository but failed with an error message that wasn’t particularly helpful. After digging into the issue, I discovered that the GitHub CLI lacked the necessary permissions to delete repositories by default.
Error: DELETE https://api.github.com/repos/org_name/repo_name: 403 Must have admin rights to Repository. []
The error? Terraform required explicit permissions to perform a delete operation, something not granted out of the box.
Fixing the Permissions Issue
After doing a bit of research I discovered that the permissions required to do this operation are not granted by default. You need to explicitly request them.
This can be done by executing the following command:
gh auth refresh -h github.com -s delete_repo
This command updates your authentication token with the required permissions, enabling Terraform to manage the full lifecycle of your GitHub repositories, including deletions.
That’s it!