https://github.com/happypathway/terraform-github-repo
Terraform Module
https://github.com/happypathway/terraform-github-repo
module terraform terraform-managed
Last synced: over 1 year ago
JSON representation
Terraform Module
- Host: GitHub
- URL: https://github.com/happypathway/terraform-github-repo
- Owner: HappyPathway
- Created: 2024-04-17T16:39:21.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-02-14T21:07:01.000Z (over 1 year ago)
- Last Synced: 2025-02-14T21:32:23.567Z (over 1 year ago)
- Topics: module, terraform, terraform-managed
- Language: HCL
- Homepage:
- Size: 84 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
# Terraform GitHub Repository Module
A comprehensive Terraform module for managing GitHub repositories with advanced features like branch protection, file management, and team access control. You can use this module to create new repositories or manage existing ones.
## Features
- Create new repositories or manage existing ones
- Complete GitHub repository management
- Branch protection rules
- File content management
- Team access configuration
- Action secrets management
- Repository collaborator management
- Automated README generation
- Issue management
## Usage
### Creating a New Repository
```hcl
module "new_repository" {
source = "HappyPathway/repo/github"
name = "my-repository"
repo_org = "MyOrganization"
create_repo = true # Default, can be omitted
force_name = true
github_repo_description = "Repository description"
github_repo_topics = ["terraform", "automation"]
github_is_private = false
}
```
### Managing an Existing Repository
```hcl
module "existing_repository" {
source = "HappyPathway/repo/github"
name = "existing-repository"
repo_org = "MyOrganization"
create_repo = false # Tell Terraform to manage existing repository
# All other settings will be applied to the existing repository
github_repo_topics = ["managed", "terraform"]
github_has_issues = true
}
```
### Basic Repository
```hcl
module "basic_repo" {
source = "HappyPathway/repo/github"
name = "my-project"
repo_org = "MyOrganization"
}
```
### Repository with Protected Branches
```hcl
module "protected_repo" {
source = "HappyPathway/repo/github"
name = "protected-project"
repo_org = "MyOrganization"
branch_protections = {
main = {
required_status_checks = true
enforce_admins = true
required_reviews = 2
}
}
}
```
### Repository with Managed Files
```hcl
module "managed_repo" {
source = "HappyPathway/repo/github"
name = "managed-project"
repo_org = "MyOrganization"
managed_extra_files = {
"README.md" = {
content = file("${path.module}/templates/readme.md")
overwrite = true
}
"CONTRIBUTING.md" = {
content = file("${path.module}/templates/contributing.md")
overwrite = false
}
}
}
```
## Inputs
| Name | Description | Type | Required | Default |
|------|-------------|------|----------|---------|
| name | Repository name | string | Yes | - |
| repo_org | GitHub organization name | string | No | null |
| create_repo | Whether to create a new repository or manage existing | bool | No | true |
| force_name | Keep exact repository name (no date suffix) | bool | No | false |
| github_repo_description | Repository description | string | No | null |
| github_repo_topics | Repository topics | list(string) | No | [] |
| github_is_private | Make repository private | bool | No | true |
| // ...other inputs... |
## Outputs
| Name | Description |
|------|-------------|
| github_repo | All repository attributes (see details below) |
| ssh_clone_url | SSH clone URL |
| node_id | Repository node ID for GraphQL |
| full_name | Full repository name (org/repo) |
| repo_id | Repository ID |
| html_url | Repository web URL |
| http_clone_url | HTTPS clone URL |
| git_clone_url | Git protocol clone URL |
| visibility | Repository visibility (public/private) |
| default_branch | Default branch name |
| topics | Repository topics |
| template | Template repository info |
### Complete Repository Attributes
The `github_repo` output includes:
Basic Info:
- `name` - Repository name
- `full_name` - Full repository name (org/repo)
- `description` - Repository description
- `html_url` - GitHub web URL
- `ssh_clone_url` - SSH clone URL
- `http_clone_url` - HTTPS clone URL
- `git_clone_url` - Git protocol URL
- `visibility` - Public or private status
Settings:
- `topics` - Repository topics
- `has_issues` - Issue tracking enabled
- `has_projects` - Project boards enabled
- `has_wiki` - Wiki enabled
- `is_template` - Template repository status
- `allow_merge_commit` - Merge commit allowed
- `allow_squash_merge` - Squash merge allowed
- `allow_rebase_merge` - Rebase merge allowed
- `allow_auto_merge` - Auto-merge enabled
- `delete_branch_on_merge` - Branch deletion on merge
Additional Info:
- `default_branch` - Default branch name
- `archived` - Archive status
- `homepage_url` - Homepage URL if set
- `vulnerability_alerts` - Vulnerability alerts status
- `template` - Template repository details if used
- `gitignore_template` - .gitignore template if used
- `license_template` - License template if used
## Limitations and Important Notes
### Managing Existing Repositories
When managing existing repositories (`create_repo = false`):
- The repository must already exist in the specified organization
- You must have admin access to the repository
- Some settings may be read-only if they were set during repository creation
- Initial repository settings (like `auto_init`) are ignored
- Branch protection rules can only be added, not removed
### Error Cases
The module will fail if:
- When `create_repo = false` and the repository doesn't exist
- When `create_repo = false` and `repo_org` is not specified
- When trying to manage a repository you don't have admin access to
- When applying branch protection rules to a private repository without a GitHub Enterprise plan
### Best Practices
1. When managing existing repositories:
- Start with `create_repo = false` and minimal settings
- Gradually add configuration to avoid conflicts
- Use `terraform plan` to verify changes
- Consider using `lifecycle` blocks to ignore specific attributes
2. For new repositories:
- Use `create_repo = true` (default)
- Set `force_name = true` to maintain consistent naming
- Configure all settings during initial creation
## Testing
This module includes automated tests that verify:
- Repository creation
- Data source lookups for existing repositories
- All output attributes
Run the tests using:
```bash
terraform test
```
## Contributing
1. Fork the repository
2. Create a feature branch
3. Commit your changes
4. Push to the branch
5. Create a Pull Request
## License
MIT License - see [LICENSE](LICENSE) for details
[](https://github.com/HappyPathway/terraform-github-repo/actions/workflows/terraform.yaml)
[](https://github.com/HappyPathway/terraform-github-repo/actions/workflows/modtest-dev.yaml)
## Requirements
No requirements.
## Providers
| Name | Version |
|------|---------|
| [github](#provider\_github) | 6.5.0 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [github_actions_environment_secret.environment_secrets](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_secret) | resource |
| [github_actions_environment_variable.environment_variables](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_variable) | resource |
| [github_actions_secret.secret](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
| [github_actions_variable.variable](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource |
| [github_branch.branch](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource |
| [github_branch_default.default_main_branch](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource |
| [github_branch_protection.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_protection) | resource |
| [github_repository.repo](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource |
| [github_repository_collaborator.collaborators](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_collaborator) | resource |
| [github_repository_environment.environments](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_environment) | resource |
| [github_repository_file.codeowners](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) | resource |
| [github_repository_file.extra_files](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) | resource |
| [github_repository_file.managed_extra_files](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) | resource |
| [github_team_repository.admin](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository) | resource |
| [github_actions_public_key.repo_key](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/actions_public_key) | data source |
| [github_organization_teams.root_teams](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/organization_teams) | data source |
| [github_ref.ref](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/ref) | data source |
| [github_repository.existing](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/repository) | data source |
| [github_repository.template_repo](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/repository) | data source |
| [github_team.admin_teams](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/team) | data source |
| [github_user.collaborators](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source |
| [github_user.pull_request_bypassers](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [additional\_codeowners](#input\_additional\_codeowners) | Additional entries for CODEOWNERS file | `list(string)` | `[]` | no |
| [admin\_teams](#input\_admin\_teams) | Teams to grant admin access | `list(string)` | `[]` | no |
| [archive\_on\_destroy](#input\_archive\_on\_destroy) | Archive repository instead of deleting on destroy | `bool` | `true` | no |
| [archived](#input\_archived) | Archive this repository | `bool` | `false` | no |
| [collaborators](#input\_collaborators) | Map of collaborators and their permission levels | `map(string)` | `{}` | no |
| [create\_codeowners](#input\_create\_codeowners) | Create CODEOWNERS file | `bool` | `true` | no |
| [create\_repo](#input\_create\_repo) | Whether to create a new repository or manage an existing one | `bool` | `true` | no |
| [enforce\_prs](#input\_enforce\_prs) | Enforce pull request reviews | `bool` | `true` | no |
| [environments](#input\_environments) | List of GitHub environments to create for the repository |
list(object({
name = string
reviewers = optional(object({
teams = optional(list(string), [])
users = optional(list(string), [])
}), {})
deployment_branch_policy = optional(object({
protected_branches = optional(bool, true)
custom_branch_policies = optional(bool, false)
}), {})
secrets = optional(list(object({
name = string
value = string
})), [])
vars = optional(list(object({
name = string
value = string
})), [])
})) | `[]` | no |
| [extra\_files](#input\_extra\_files) | Additional files to create in the repository | list(object({
path = string
content = string
})) | `[]` | no |
| [force\_name](#input\_force\_name) | Keep exact repository name (no date suffix) | `bool` | `false` | no |
| [github\_allow\_auto\_merge](#input\_github\_allow\_auto\_merge) | Allow auto-merging pull requests | `bool` | `false` | no |
| [github\_allow\_merge\_commit](#input\_github\_allow\_merge\_commit) | Allow merge commits | `bool` | `false` | no |
| [github\_allow\_rebase\_merge](#input\_github\_allow\_rebase\_merge) | Allow rebase merging | `bool` | `false` | no |
| [github\_allow\_squash\_merge](#input\_github\_allow\_squash\_merge) | Allow squash merging | `bool` | `true` | no |
| [github\_auto\_init](#input\_github\_auto\_init) | Initialize repository with README | `bool` | `true` | no |
| [github\_codeowners\_team](#input\_github\_codeowners\_team) | n/a | `string` | `"terraform-reviewers"` | no |
| [github\_default\_branch](#input\_github\_default\_branch) | Default branch name | `string` | `"main"` | no |
| [github\_delete\_branch\_on\_merge](#input\_github\_delete\_branch\_on\_merge) | Delete head branch after merge | `bool` | `true` | no |
| [github\_dismiss\_stale\_reviews](#input\_github\_dismiss\_stale\_reviews) | Dismiss stale pull request approvals | `bool` | `true` | no |
| [github\_enforce\_admins\_branch\_protection](#input\_github\_enforce\_admins\_branch\_protection) | Enforce branch protection rules on administrators | `bool` | `true` | no |
| [github\_has\_issues](#input\_github\_has\_issues) | Enable issues feature | `bool` | `false` | no |
| [github\_has\_projects](#input\_github\_has\_projects) | Enable projects feature | `bool` | `true` | no |
| [github\_has\_wiki](#input\_github\_has\_wiki) | Enable wiki feature | `bool` | `true` | no |
| [github\_is\_private](#input\_github\_is\_private) | Make repository private | `bool` | `true` | no |
| [github\_org\_teams](#input\_github\_org\_teams) | Organization teams configuration | `list(any)` | `null` | no |
| [github\_push\_restrictions](#input\_github\_push\_restrictions) | List of team/user IDs with push access | `list(string)` | `[]` | no |
| [github\_repo\_description](#input\_github\_repo\_description) | Repository description | `string` | `null` | no |
| [github\_repo\_topics](#input\_github\_repo\_topics) | Repository topics | `list(string)` | `[]` | no |
| [github\_require\_code\_owner\_reviews](#input\_github\_require\_code\_owner\_reviews) | Require code owner review | `bool` | `true` | no |
| [github\_required\_approving\_review\_count](#input\_github\_required\_approving\_review\_count) | Number of approvals needed for pull requests | `number` | `1` | no |
| [gitignore\_template](#input\_gitignore\_template) | Gitignore template to use | `string` | `null` | no |
| [homepage\_url](#input\_homepage\_url) | Repository homepage URL | `string` | `null` | no |
| [is\_template](#input\_is\_template) | Make this repository a template | `bool` | `false` | no |
| [managed\_extra\_files](#input\_managed\_extra\_files) | Additional files to manage in the repository | list(object({
path = string
content = string
})) | `[]` | no |
| [name](#input\_name) | Name of the repository | `string` | n/a | yes |
| [prefix](#input\_prefix) | Prefix to add to repository name | `string` | `null` | no |
| [pull\_request\_bypassers](#input\_pull\_request\_bypassers) | Users/teams that can bypass pull request requirements | `list(string)` | `[]` | no |
| [repo\_org](#input\_repo\_org) | GitHub organization name | `string` | `null` | no |
| [required\_status\_checks](#input\_required\_status\_checks) | Required status checks for protected branches | object({
contexts = list(string)
strict = optional(bool, false)
}) | `null` | no |
| [secrets](#input\_secrets) | GitHub Actions secrets | list(object({
name = string
value = string
})) | `[]` | no |
| [security\_and\_analysis](#input\_security\_and\_analysis) | Security and analysis settings for the repository | object({
advanced_security = optional(object({
status = string
}), { status = "disabled" })
secret_scanning = optional(object({
status = string
}), { status = "disabled" })
secret_scanning_push_protection = optional(object({
status = string
}), { status = "disabled" })
}) | `null` | no |
| [template\_repo](#input\_template\_repo) | Template repository name | `string` | `null` | no |
| [template\_repo\_org](#input\_template\_repo\_org) | Template repository organization | `string` | `null` | no |
| [vars](#input\_vars) | GitHub Actions variables | list(object({
name = string
value = string
})) | `[]` | no |
| [vulnerability\_alerts](#input\_vulnerability\_alerts) | Enable Dependabot alerts | `bool` | `false` | no |
## Outputs
| Name | Description |
|------|-------------|
| [default\_branch](#output\_default\_branch) | Default branch of the repository |
| [full\_name](#output\_full\_name) | Full name of the repository in org/repo format |
| [git\_clone\_url](#output\_git\_clone\_url) | URL that can be provided to git clone to clone the repository anonymously via the git protocol |
| [github\_repo](#output\_github\_repo) | All attributes of the GitHub repository |
| [html\_url](#output\_html\_url) | URL to the repository on GitHub |
| [http\_clone\_url](#output\_http\_clone\_url) | URL that can be provided to git clone to clone the repository via HTTPS |
| [node\_id](#output\_node\_id) | Node ID of the repository, used for GraphQL API access |
| [repo\_id](#output\_repo\_id) | Repository ID |
| [ssh\_clone\_url](#output\_ssh\_clone\_url) | URL that can be provided to git clone to clone the repository via SSH |
| [template](#output\_template) | Template repository this repository was created from |
| [topics](#output\_topics) | List of topics applied to the repository |
| [visibility](#output\_visibility) | Whether the repository is private or public |