Terraform module to create and manage a GitHub repository.
Take care when configuring either var.license_template or var.gitignore_template as the values are case sensitive. See here for a list of supported licenses or here for a list of supported gitignore templates - to use either, provide the file name without the extension, e.g. mit or Terraform respectively.
Setting one of these templates can only be done during creation of the repository. If you want to add a LICENSE or .gitignore file after repository creation, you'll need to do it like any other file.
Additional branches can be created and configured using var.branches. Any branches created here are in addition to the default branch (var.default_branch).
You can create branches by either adding them to var.branches:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
branches = {
"develop" = {}
}
}Or by specifying the source branch or hash by setting source_branch or source_sha respectively:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
branches = {
"develop" = {
source_branch = "release"
}
}
}See the github_branch resource for more details
This module allows creating and managing files in a GitHub repository by using var.repository_files.
To create files:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
repository_files = {
".github/dependabot.yml" = {
content = file("${path.root}/files/dependabot.yml")
}
"README.md" = {
content = "Welcome to my project!"
managed = false
}
}
}The map key refers to the file path in the repository, and the content field contains the file content. By default, files created using this method are managed by Terraform, but this can be changed by setting the managed field to false, meaning any changes done outside of Terraform will be ignored.
The default behaviour is for any branch created by this branch to inherit the default branch protection settings (var.default_branch_protection), but this can be overridden by either settings the branch_protection key or disabling branch protection by setting the use_branch_protection field to false.
To override the default branch protection settings, specify the branch_protection key:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
branches = {
"develop" = {
branch_protection = {
enforce_admins = true
require_signed_commits = true
}
}
}
}In the event you want to create branches using Terraform but do not want any branch protection to be configured, you can set use_branch_protection to false:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
branches = {
"develop" = {
use_branch_protection = false
}
}
}For more examples, see the branches examples.
References to URLs, issues, pull requests, and commits are automatically shortened and converted into links. You can configure custom autolink references for a repository using the autolink_references variable.
You define custom autolinks by specifying a reference prefix and a target URL using var.autolink_references:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
autolink_references = {
"JIRA" = { url_template = "https://my-jira-instance.atlassian.net/browse/<num>" }
}
}In the above example, JIRA-123 is converted to https://jira.example.com/issue?query=123 when viewing comments or commit messages.
Important
Reference prefixes cannot have overlapping names. For example, a repository cannot have two custom autolinks with prefixes such as TICKET and TICK, since both prefixes would match the string TICKET123a.
Enviroments can be configured using the var.environments variable. This allows you to create environments with secrets, variables, and deployment policies.
You can also call the module directory, see its [README] for more details, or see the environments examples.
This module manages repository access by granting access to pre-existing teams. To grant a team access, populate the access map, using the team name as the key and the desired level as the value, for example:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
access = {
MyTeam = "maintain"
Everyone = "push"
}
}The module will use a data resource to look up the team ID and assign the team the desired permissions.
Important
If you're creating a GitHub team in the same run/workspace that assigns permissions to the repository, you must set an explicit dependency to ensure the team is created before repository:
resource "github_team" "myteam" {
name = "MyTeam"
}
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
access = {
MyTeam = "maintain"
Everyone = "push"
}
depends_on = [github_team.myteam]
}By default, the module will enable squash merges and disable merge commits and rebase merges. You can change this by setting the allow_merge_commit, allow_rebase_merge and allow_squash_merge variables to true or false.
To more easily select a single strategy, you can set the merge_strategy variable to one of the following values:
mergerebasesquash
Using merge_strategy will override the above variables.
It is possible to create (and manage) files within a GitHub repository using this module. We have a repository_files variable that takes a map of files to create; the key represents the name (and path) for the file, and the value is an object with the following attributes:
branch: optional value to specify the branch, defaults to the default branchcontent: content of the file, can be a string or string sourced from a file or template usingfile()ortemplatefile()respectively.managed: whether Terraform should manage this file, or if it is a one time commit and any changes done outside of Terraform, defaults totrueoverwrite_on_create: whether to overwrite the file if it already exists when creating it, defaults tofalse
Example:
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"
name = "my-repo"
repository_files = {
"README.md" = {
content = "# My repo"
managed = false
}
".github/workflows/ci.yml" = {
content = templatefile("${path.module}/ci.yml.tpl", { name = "My repo" })
}
"docs/index.md" = {
content = file("${path.module}/index.md")
}
}
}| Name | Version |
|---|---|
| terraform | >= 1.9.0 |
| github | ~> 6.11 |
| Name | Version |
|---|---|
| github | ~> 6.11 |
| Name | Source | Version |
|---|---|---|
| environment | ./modules/environment | n/a |
| Name | Type |
|---|---|
| github_actions_repository_access_level.actions_access_level | resource |
| github_actions_secret.secrets | resource |
| github_actions_variable.action_variables | resource |
| github_app_installation_repository.default | resource |
| github_branch.default | resource |
| github_branch_default.default | resource |
| github_branch_protection.default | resource |
| github_dependabot_secret.encrypted | resource |
| github_dependabot_secret.plaintext | resource |
| github_repository.default | resource |
| github_repository_autolink_reference.default | resource |
| github_repository_custom_property.default | resource |
| github_repository_dependabot_security_updates.default | resource |
| github_repository_file.managed | resource |
| github_repository_file.unmanaged | resource |
| github_repository_ruleset.default | resource |
| github_team_repository.default | resource |
| github_workflow_repository_permissions.default | resource |
| github_team.default | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| name | The name of the repository | string |
n/a | yes |
| access | An optional map with GitHub team names and their access level to the repository | map(string) |
{} |
no |
| actions_access_level | Control how this repository is used by GitHub Actions workflows in other repositories | string |
null |
no |
| actions_secrets | An optional map with GitHub action secrets | map(string) |
{} |
no |
| actions_variables | An optional map with GitHub Actions variables | map(string) |
{} |
no |
| allow_auto_merge | Enable allow auto-merging pull requests on the repository | bool |
true |
no |
| allow_merge_commit | Enable merge commits on the repository | bool |
true |
no |
| allow_rebase_merge | Enable rebase merges on the repository | bool |
true |
no |
| allow_squash_merge | Enable squash merges on the repository | bool |
true |
no |
| allow_update_branch | Enable to allow suggestions to update pull request branches | bool |
true |
no |
| app_installation_ids | Set of GitHub App installation IDs to associate with the repository | set(string) |
[] |
no |
| archive_on_destroy | Set to true to archive the repository instead of deleting on destroy | bool |
false |
no |
| archived | Specifies if the repository should be archived | bool |
false |
no |
| auto_init | Disable to not produce an initial commit in the repository | bool |
true |
no |
| autolink_references | Optional map with autolink reference key prefix and their corresponding URL templates | map(object({ |
{} |
no |
| branches | An optional map with GitHub branches to create | map(object({ |
{} |
no |
| custom_properties | An optional map of custom properties to set on the repository. The custom properties need to be defined on the org level beforehand to be used here. | map(object({ |
{} |
no |
| default_branch | Name of the default branch for the GitHub repository | string |
"main" |
no |
| default_branch_protection | Default branch protection settings for managed branches | object({ |
{ |
no |
| delete_branch_on_merge | Automatically delete head branch after a pull request is merged | bool |
true |
no |
| dependabot_enabled | Set to true to enable Dependabot alerts and security updates | bool |
false |
no |
| dependabot_encrypted_secrets | Map with encrypted Dependabot secrets | map(string) |
{} |
no |
| dependabot_plaintext_secrets | Map with plaintext Dependabot secrets | map(string) |
{} |
no |
| description | A description for the GitHub repository | string |
null |
no |
| environments | An optional map of GitHub environments to configure | map(object({ |
{} |
no |
| gitignore_template | The name of the template without the extension | string |
null |
no |
| has_discussions | To enable GitHub Discussions features on the repository | bool |
false |
no |
| has_issues | To enable GitHub Issues features on the repository | bool |
false |
no |
| has_projects | To enable GitHub Projects features on the repository | bool |
false |
no |
| has_wiki | To enable GitHub Wiki features on the repository | bool |
false |
no |
| homepage_url | URL of a page describing the project | string |
null |
no |
| is_template | To mark this repository as a template repository | bool |
false |
no |
| license_template | The name of the (case sensitive) license template to use | string |
null |
no |
| merge_commit_message | The default commit message for merge commits | string |
"PR_BODY" |
no |
| merge_commit_title | The default commit title for merge commits | string |
"PR_TITLE" |
no |
| merge_strategy | The merge strategy to use for pull requests | string |
null |
no |
| pages | The repository's GitHub Pages configuration. | object({ |
null |
no |
| repository_files | A map of GitHub repository files that should be created | map(object({ |
{} |
no |
| source_repo | The source repository to create this repository from in format owner/repo | string |
null |
no |
| squash_merge_commit_message | The default commit message for squash merges | string |
"COMMIT_MESSAGES" |
no |
| squash_merge_commit_title | The default commit title for squash merges | string |
"PR_TITLE" |
no |
| tag_protection | The repository tag protection pattern | string |
null |
no |
| template_repository | The settings of the template repostitory to use on creation | object({ |
null |
no |
| topics | A list of topics to set on the repository | list(string) |
[] |
no |
| visibility | Set the GitHub repository as public, private or internal | string |
"private" |
no |
| vulnerability_alerts | Set to true to enable security alerts for vulnerable dependencies | bool |
true |
no |
| workflow_permissions | An optional object to configure GitHub Actions workflow permissions for the repository | object({ |
null |
no |
| Name | Description |
|---|---|
| full_name | The full 'organization/repository' name of the repository |
| name | The name of the repository |
| repo_id | The id of the repository |
100% Open Source and licensed under the Apache License Version 2.0. See LICENSE for full details.