Skip to main content

NTC Github Administration

Release Notes Implementation Blueprint 🔒   Source Code

Description

NTC GitHub Administration simplifies the management of GitHub organizations through infrastructure-as-code. This building block automates the configuration of organization settings, teams, members, repositories, and security policies, ensuring consistent and secure GitHub environments. With support for branch protection rulesets, secrets management, and repository templates, NTC GitHub Administration provides a comprehensive solution for scaling GitHub operations across teams and projects.

Whether you are managing organization-wide security policies, standardizing repository configurations, or automating team and member provisioning, NTC GitHub Administration ensures reliable and consistent GitHub management aligned with best practices.

Usage

Latest Release1.0.0
# ---------------------------------------------------------------------------------------------------------------------
# ¦ PROVIDER
# ---------------------------------------------------------------------------------------------------------------------
provider "github" {
# github org which should be managed
owner = "my-company"

# it is recommended to use a GitHub App installation instead of a token to authenticate with github
# https://registry.terraform.io/providers/integrations/github/latest/docs#github-app-installation
app_auth {
id = var.app_id # or `GITHUB_APP_ID` environment variable
installation_id = var.app_installation_id # or `GITHUB_APP_INSTALLATION_ID` environment variable
pem_file = var.app_pem_file # or `GITHUB_APP_PEM_FILE` environment variable
}
}

# ---------------------------------------------------------------------------------------------------------------------
# ¦ NTC GITHUB ADMINISTRATION
# ---------------------------------------------------------------------------------------------------------------------
module "ntc_github_administration" {
source = "https://github.com/nuvibit-terraform-collection/terraform-github-ntc-administration?ref=X.X.X"

organization_settings = {
# set 'update_settings' to false to omit this block
update_settings = true
display_name = "My Company"
description = "Github Organization of My Company"
company = "My Company"
location = "Switzerland"
blog = "https://mycompany.com"
email = "info@mycompany.com"
billing_email = "billing@mycompany.com"
has_organization_projects = false
has_repository_projects = false
default_repository_permission = "write"
web_commit_signoff_required = false
advanced_security_enabled_for_new_repositories = false
dependabot_alerts_enabled_for_new_repositories = false
dependabot_security_updates_enabled_for_new_repositories = false
dependency_graph_enabled_for_new_repositories = false
secret_scanning_enabled_for_new_repositories = false
secret_scanning_push_protection_enabled_for_new_repositories = false
members_can_create_pages = false
members_can_create_public_pages = false
members_can_create_private_pages = false
members_can_fork_private_repositories = false
members_can_create_public_repositories = true
members_can_create_private_repositories = true
members_can_create_internal_repositories = true
members_can_create_repositories = true
}

# organization ruleset for branch protection (requires a GitHub Team or GitHub Enterprise plan)
organization_rulesets = [
{
name = "branch-protection"
target = "branch"
enforcement = "active"
include_refs = ["~DEFAULT_BRANCH"]
exclude_refs = []
include_repos = ["~ALL"]
exclude_repos = ["legacy-repo"]
bypass_actors = [
{
# NOTE: 'actor_name' must match an existing actor in the current organization or an actor created in the same module
actor_name = "admins"
actor_type = "Team"
bypass_mode = "always"
},
{
actor_name = "my-app"
actor_type = "Integration"
bypass_mode = "always"
},
{
actor_name = "OrganizationAdmin"
actor_type = "OrganizationAdmin"
bypass_mode = "always"
},
{
actor_name = "admin"
actor_type = "RepositoryRole"
bypass_mode = "always"
}
]
required_checks = ["ci", "security-scan"]
required_workflows = []
required_code_scanning = []
restrict_creations = true
restrict_updates = true
restrict_deletions = true
restrict_force_pushes = true
required_linear_history = true
required_signatures = true
pull_request = {
required = true
dismiss_stale_reviews_on_push = true
require_code_owner_review = true
require_last_push_approval = true
required_approving_review_count = 1
required_review_thread_resolution = true
}
}
]

# organization secrets for github actions
organization_secrets = [
{
name = "MY_SECRET"
# WARNING: do not add secrets in clear text
# secrets should be referenced as sensitive values (e.g. referenced from secrets vault or sensitive input via environment variable)
value = "supersecretvalue"
visibility = "all"
type = "github_actions"
}
]

# organization variables for github actions
organization_variables = [
{
name = "MY_VARIABLE"
value = "variablevalue"
visibility = "all"
type = "github_actions"
}
]

# add members to current organization
organization_members = [
{
username = "hans-muster"
role = "admin"
}
]

# create teams in current organization
organization_teams = [
{
name = "admins"
description = "Organization administrators"
privacy = "closed"
members = [
{
username = "hans-muster"
role = "maintainer"
}
]
}
]

# list of repositories created in the current organization (based on github provider)
organization_repositories = [
{
name = "test-repo"
description = "this repo was created during automated testing"
visibility = "private"
topics = ["test"]
# NOTE: use an existing template repository or create new template repository in separate module call
template = {
template_repository = module.ntc_github_template_repos.organization_repositories["test-template"].name
repository_owner = module.ntc_github_template_repos.organization_repositories["test-template"].owner
include_all_branches = true
}
settings = {
create_readme = false
has_issues = false
has_discussions = false
has_projects = false
has_wiki = false
allow_merge_commit = false
allow_squash_merge = true
allow_rebase_merge = false
allow_auto_merge = false
delete_branch_on_merge = true
web_commit_signoff_required = false
allow_update_branch = false
archive_on_destroy = false
vulnerability_alerts = true
ignore_vulnerability_alerts_during_read = false
# (optional) chose gitignore file from available templates
# https://github.com/github/gitignore
gitignore_template = null
# (optional) chose license file from available templates
# https://github.com/github/choosealicense.com/tree/gh-pages/_licenses
license_template = null
}
# (optional) create or overwrite files in github repository - most use cases can be solved with 'template_repository' instead
# WARNING: bypass permission required when branch protection is enabled
managed_files = [
{
file = "main.tf"
content = file("${path.module}/files/main.tf")
overwrite_on_create = true
# enabling this will only create the file initially and it will not be updated
# this can be usefull to avoid bypassing branch protection (file will be initially created before branch protection rule)
# WARNING: updating 'ignore_lifecycle' after initial deployment will cause the file to be recreated
ignore_lifecycle = true
}
]
# (optional) invite collaborators to github repository
collaborators = [
{
username = "builder-bob"
permission = "pull"
}
]
# (optional) assign teams directly to github repository
teams = [
{
# NOTE: 'team_name' must match an existing team in the current organization or a team in 'organization_teams'
team_name = "admins"
permission = "push"
}
]
}
]
}

# create template repositories separately to avoid a circular dependency
module "ntc_github_template_repos" {
source = "https://github.com/nuvibit-terraform-collection/terraform-github-ntc-administration?ref=X.X.X"

organization_repositories = [
{
name = "test-template"
description = "this repo was created during automated testing"
visibility = "private"
topics = ["test"]
settings = {
# NOTE: set 'is_template' to true to create a template repository which can be used as a base for new repositories
is_template = true
create_readme = false
has_issues = false
has_discussions = false
has_projects = false
has_wiki = false
allow_merge_commit = false
allow_squash_merge = true
allow_rebase_merge = false
allow_auto_merge = false
delete_branch_on_merge = true
web_commit_signoff_required = false
allow_update_branch = false
archive_on_destroy = false
vulnerability_alerts = true
ignore_vulnerability_alerts_during_read = false
}
managed_files = [
{
file = ".gitignore"
content = file("${path.module}/files/.gitignore")
overwrite_on_create = true
ignore_lifecycle = false
}
]
},
]
}

Requirements

The following requirements are needed by this module:

  • terraform (>= 1.3.0)

  • github (>= 6.0, != 6.6.0, != 6.5.0)

Providers

The following providers are used by this module:

  • github (>= 6.0, != 6.6.0, != 6.5.0)

Modules

The following Modules are called:

ntc_github_repositories

Source: ./modules/repository

Version:

Resources

The following resources are used by this module:

Required Inputs

No required inputs.

Optional Inputs

The following input variables are optional (have default values):

organization_members

Description: List of organization members to manage.

Type:

list(object({
username = string
role = optional(string, "member")
}))

Default: []

organization_repositories

Description: A list of github repositories to create in current organization.

Type:

list(object({
name = string
description = optional(string, "")
visibility = optional(string, "private")
topics = optional(list(string), [])
template = optional(object({
template_repository = optional(string, "")
repository_owner = optional(string, "")
include_all_branches = optional(bool, true)
}), {})
settings = optional(object({
create_readme = optional(bool, true)
is_template = optional(bool, false)
has_issues = optional(bool, true)
has_discussions = optional(bool, true)
has_projects = optional(bool, true)
has_wiki = optional(bool, true)
allow_merge_commit = optional(bool, true)
allow_squash_merge = optional(bool, true)
allow_rebase_merge = optional(bool, true)
allow_auto_merge = optional(bool, false)
delete_branch_on_merge = optional(bool, false)
web_commit_signoff_required = optional(bool, false)
allow_update_branch = optional(bool, false)
archive_on_destroy = optional(bool, false)
vulnerability_alerts = optional(bool, false)
ignore_vulnerability_alerts_during_read = optional(bool, false)
gitignore_template = optional(string, null)
license_template = optional(string, null)
}), {})
branch_protection_rules = optional(list(object({
pattern = optional(string, "main")
enforce_admins = optional(bool, false)
allows_deletions = optional(bool, false)
require_conversation_resolution = optional(bool, false)
require_signed_commits = optional(bool, false)
required_linear_history = optional(bool, false)
allows_force_pushes = optional(bool, false)
required_status_checks = optional(object({
strict = optional(bool, true)
contexts = optional(list(string), [])
}), {})
restrict_pushes = optional(object({
blocks_creations = optional(bool, true)
push_allowances = optional(list(string), [])
}), {})
required_pull_request_reviews = optional(object({
dismiss_stale_reviews = optional(bool, false)
restrict_dismissals = optional(bool, false)
dismissal_restrictions = optional(list(string), [])
require_code_owner_reviews = optional(bool, false)
required_approving_review_count = optional(number, 0)
}), {})
force_push_bypassers = optional(list(string), [])
lock_branch = optional(bool, false)
})), [])
managed_files = optional(list(object({
file = string
content = string
overwrite_on_create = optional(bool, true)
ignore_lifecycle = optional(bool, false)
branch = optional(string, null)
commit_message = optional(string, null)
commit_author = optional(string, null)
commit_email = optional(string, null)
})), [])
collaborators = optional(list(object({
username = string
permission = optional(string, "pull")
})), [])
teams = optional(list(object({
team_name = string
permission = optional(string, "pull")
})), [])
}))

Default: []

organization_rulesets

Description: List of organization rulesets to create for branch protection and other repository rules.

Type:

list(object({
name = string
target = optional(string, "branch")
enforcement = optional(string, "active")
include_refs = optional(list(string), ["~DEFAULT_BRANCH"])
exclude_refs = optional(list(string), [])
include_repos = optional(list(string), ["~ALL"])
exclude_repos = optional(list(string), [])
bypass_actors = optional(list(object({
actor_name = string
actor_type = string
bypass_mode = optional(string, "always")
})), [])
required_checks = optional(list(string), [])
required_workflows = optional(list(string), [])
required_code_scanning = optional(list(string), [])
restrict_creations = optional(bool, false)
restrict_updates = optional(bool, false)
restrict_deletions = optional(bool, false)
restrict_force_pushes = optional(bool, true)
required_linear_history = optional(bool, false)
required_signatures = optional(bool, false)
pull_request = optional(object({
required = optional(bool, false)
dismiss_stale_reviews_on_push = optional(bool, false)
require_code_owner_review = optional(bool, false)
require_last_push_approval = optional(bool, false)
required_approving_review_count = optional(number, 1)
required_review_thread_resolution = optional(bool, false)
}))

}))

Default: []

organization_secrets

Description: List of organization-level secrets to create.

Type:

list(object({
name = string
value = string
visibility = optional(string, "all")
type = optional(string, "github_actions")
}))

Default: []

organization_settings

Description: Configuration settings for the GitHub organization.

Type:

object({
update_settings = optional(bool, false)
display_name = optional(string, "")
description = optional(string, "")
company = optional(string, "")
location = optional(string, "")
blog = optional(string, "")
email = optional(string, "")
billing_email = optional(string, "")
has_organization_projects = optional(bool, true)
has_repository_projects = optional(bool, true)
default_repository_permission = optional(string, "read")
web_commit_signoff_required = optional(bool, false)
advanced_security_enabled_for_new_repositories = optional(bool, false)
dependabot_alerts_enabled_for_new_repositories = optional(bool, false)
dependabot_security_updates_enabled_for_new_repositories = optional(bool, false)
dependency_graph_enabled_for_new_repositories = optional(bool, false)
secret_scanning_enabled_for_new_repositories = optional(bool, false)
secret_scanning_push_protection_enabled_for_new_repositories = optional(bool, false)
members_can_create_pages = optional(bool, true)
members_can_create_public_pages = optional(bool, true)
members_can_create_private_pages = optional(bool, true)
members_can_fork_private_repositories = optional(bool, true)
members_can_create_public_repositories = optional(bool, true)
members_can_create_private_repositories = optional(bool, true)
members_can_create_internal_repositories = optional(bool, true)
members_can_create_repositories = optional(bool, true)
})

Default: {}

organization_teams

Description: List of organization teams to create and manage.

Type:

list(object({
name = string
description = optional(string, "")
privacy = optional(string, "closed")
members = optional(list(object({
username = string
role = optional(string, "member")
})), [])
}))

Default: []

organization_variables

Description: List of organization-level variables to create.

Type:

list(object({
name = string
value = string
visibility = optional(string, "all")
type = optional(string, "github_actions")
}))

Default: []

Outputs

The following outputs are exported:

organization_repositories

Description: All created GitHub repositories with their complete attributes.