From bcf78f8d5cb2650510f56cfd71d8ad163d9f5af5 Mon Sep 17 00:00:00 2001 From: Luke Fritz Date: Mon, 2 Jan 2023 09:43:25 -0600 Subject: [PATCH] Add branch protection module (feat) --- main.tf | 21 ++++++++ modules/branch-protection/main.tf | 38 ++++++++++++++ modules/branch-protection/variables.tf | 71 ++++++++++++++++++++++++++ variables.tf | 54 ++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 modules/branch-protection/main.tf create mode 100644 modules/branch-protection/variables.tf diff --git a/main.tf b/main.tf index 4acd07b..9d5498b 100644 --- a/main.tf +++ b/main.tf @@ -100,6 +100,27 @@ resource "github_branch_default" "default" { branch = var.default_branch } +# --------------------------------------------------------------------------------------------------------------------- +# CONFIGURE PROTECTION FOR THE DEFAULT BRANCH +# --------------------------------------------------------------------------------------------------------------------- + +module "default_branch_protection" { + source = "./modules/branch-protection" + + repository_id = github_repository.repo.id + pattern = var.default_branch + + enforce_admins = var.branch_protection_enforce_admins + required_status_checks = var.branch_protection_required_status_checks + strict = var.branch_protection_strict + dismiss_stale_reviews = var.dismiss_stale_reviews + require_code_owner_reviews = var.require_code_owner_reviews + require_signed_commits = var.require_signed_commits + push_restrictions = var.push_restrictions + review_dismissal_restrictions = var.review_dismissal_restrictions + required_approving_review_count = var.required_approving_review_count +} + # --------------------------------------------------------------------------------------------------------------------- # GRANT READ (PULL) ACCESS TO TEAMS # --------------------------------------------------------------------------------------------------------------------- diff --git a/modules/branch-protection/main.tf b/modules/branch-protection/main.tf new file mode 100644 index 0000000..5cd7041 --- /dev/null +++ b/modules/branch-protection/main.tf @@ -0,0 +1,38 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# DEPLOY A GITHUB REPOSITORY WITH DEFAULT SETTINGS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +terraform { + required_version = ">= 0.12.26" + + required_providers { + github = { + source = "integrations/github" + version = ">= 5.12.0" + } + } +} + +# --------------------------------------------------------------------------------------------------------------------- +# CREATE THE BRANCH PROTECTION RULE +# --------------------------------------------------------------------------------------------------------------------- + +resource "github_branch_protection" "branch_protection_rule" { + repository_id = var.repository_id + pattern = var.pattern + enforce_admins = var.enforce_admins + require_signed_commits = var.require_signed_commits + push_restrictions = var.push_restrictions + + required_status_checks { + strict = var.strict + contexts = var.required_status_checks + } + + required_pull_request_reviews { + dismiss_stale_reviews = var.dismiss_stale_reviews + require_code_owner_reviews = var.require_code_owner_reviews + dismissal_restrictions = var.review_dismissal_restrictions + required_approving_review_count = var.required_approving_review_count + } +} diff --git a/modules/branch-protection/variables.tf b/modules/branch-protection/variables.tf new file mode 100644 index 0000000..fe62692 --- /dev/null +++ b/modules/branch-protection/variables.tf @@ -0,0 +1,71 @@ +# --------------------------------------------------------------------------------------------------------------------- +# REQUIRED VARIABLES +# --------------------------------------------------------------------------------------------------------------------- + +variable "repository_id" { + description = "The ID of the repository in which this branch protection rule will be created." + type = string +} + +variable "pattern" { + description = "The pattern identifying branches to which this protection rule will apply." + type = string +} + +# --------------------------------------------------------------------------------------------------------------------- +# OPTIONAL VARIABLES +# --------------------------------------------------------------------------------------------------------------------- + +variable "enforce_admins" { + description = "Setting this to true enforces status checks for repository administrators. In general this should be false to allow admins and service accounts to reconcile branches after a release without creating trailing merge commits -- branches would never be current with one another." + type = bool + default = true +} + +variable "required_status_checks" { + description = "A list of status checks (contexts) that must pass before a branch can be merged into the protected branch." + type = set(string) + default = [] +} + +variable "strict" { + description = "Setting this to true enforces that a branch be current with the base branch before merging." + type = bool + default = true +} + +variable "dismiss_stale_reviews" { + description = "Dismiss approved reviews automatically when a new commit is pushed." + type = bool + default = true +} + +variable "require_code_owner_reviews" { + description = "Whether or not an approval is required from code owners to merge a pull request." + type = bool + default = true +} + +variable "require_signed_commits" { + description = "Requires all commits in the branch to be signed with GPG." + type = bool + default = true +} + +variable "push_restrictions" { + description = "A list of actor IDs that are explicitly permitted to push to the branch. Admins have this capability if `enforce_admins` is false." + type = set(string) + default = [] +} + +variable "review_dismissal_restrictions" { + description = "The list of actor IDs with dismissal access." + type = set(string) + default = [] +} + +variable "required_approving_review_count" { + description = "The number of approvals required to satisfy branch protection requirements. This must be a number between 1 and 6." + type = number + default = 1 +} diff --git a/variables.tf b/variables.tf index 4f146c8..31404c8 100644 --- a/variables.tf +++ b/variables.tf @@ -239,6 +239,60 @@ variable "default_branch" { default = "main" } +variable "branch_protection_enforce_admins" { + description = "Setting this to true enforces status checks for repository administrators. In general this should be false to allow admins and service accounts to reconcile branches after a release without creating trailing merge commits -- branches would never be current with one another." + type = bool + default = true +} + +variable "branch_protection_required_status_checks" { + description = "A set of status checks (contexts) that must pass before a branch can be merged into the protected branch." + type = set(string) + default = [] +} + +variable "branch_protection_strict" { + description = "Setting this to true enforces that a branch be current with the base branch before merging." + type = bool + default = true +} + +variable "dismiss_stale_reviews" { + description = "Dismiss approved reviews automatically when a new commit is pushed." + type = bool + default = true +} + +variable "require_code_owner_reviews" { + description = "Whether or not an approval is required from code owners to merge a pull request." + type = bool + default = true +} + +variable "require_signed_commits" { + description = "Requires all commits in the branch to be signed with GPG." + type = bool + default = true +} + +variable "push_restrictions" { + description = "A list of actor IDs that are explicitly permitted to push to the branch. Admins have this capability if `enforce_admins` is false." + type = set(string) + default = [] +} + +variable "review_dismissal_restrictions" { + description = "The list of actor IDs with permission to dismiss reviews." + type = set(string) + default = [] +} + +variable "required_approving_review_count" { + description = "The number of approvals required to satisfy branch protection requirements. This must be a number between 1 and 6." + type = number + default = 1 +} + variable "labels" { description = "A set of labels to configure for the repository." type = set(object({