Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

breaking: create and set branch configuration using var.branches #61

Merged
merged 4 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/terraform-validation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
uses: actions/checkout@v4

- name: Run Checkov
uses: bridgecrewio/checkov-action@v12.2577.0
uses: bridgecrewio/checkov-action@v12
with:
container_user: 1000
directory: "/"
Expand All @@ -160,7 +160,7 @@ jobs:
quiet: true
skip_check: "CKV_GIT_5,CKV_GLB_1,CKV_TF_1"
soft_fail: false
skip_path: "examples/*"
skip_path: "examples/"

### SKIP REASON ###
# Check | Description | Reason
Expand Down
82 changes: 79 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,83 @@
# terraform-github-mcaf-repository

MCAF Terraform module to create and manage a GitHub repository.
Terraform module to create and manage a GitHub repository.

IMPORTANT: We do not pin modules to versions in our examples. We highly recommend that in your code you pin the version to the exact version you are using so that your infrastructure remains stable.
## Creating branches

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`:

```hcl
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:

```hcl
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"

name = "my-repo"

branches = {
"develop" = {
source_branch = "release"
}
}
}
```

See the [github_branch resource](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) for more details

## Configuring (additional) branches

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:

```hcl
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`:

```hcl
module "mcaf-repository" {
source = "schubergphilis/mcaf-repository/github"

name = "my-repo"

branches = {
"develop" = {
branch_protection = { use_branch_protection = false }
}
}
}
```

For more examples, see the [branches examples](https://github.com/schubergphilis/terraform-github-mcaf-repository/blob/master/examples/branches/main.tf).

<!-- BEGIN_TF_DOCS -->
## Requirements
Expand Down Expand Up @@ -56,8 +131,9 @@ No modules.
| <a name="input_allow_squash_merge"></a> [allow\_squash\_merge](#input\_allow\_squash\_merge) | To enable squash merges on the repository | `bool` | `false` | no |
| <a name="input_archived"></a> [archived](#input\_archived) | Specifies if the repository should be archived | `bool` | `false` | no |
| <a name="input_auto_init"></a> [auto\_init](#input\_auto\_init) | Disable to not produce an initial commit in the repository | `bool` | `true` | no |
| <a name="input_branch_protection"></a> [branch\_protection](#input\_branch\_protection) | The GitHub branches to protect from forced pushes and deletion | <pre>list(object({<br> branches = list(string)<br> enforce_admins = bool<br> restrict_pushes = optional(object({<br> blocks_creations = optional(bool)<br> push_allowances = optional(list(string))<br> }))<br> require_signed_commits = bool<br><br> required_checks = optional(object({<br> strict = bool<br> contexts = list(string)<br> }))<br><br> required_reviews = object({<br> dismiss_stale_reviews = bool<br> dismissal_restrictions = list(string)<br> required_approving_review_count = number<br> require_code_owner_reviews = bool<br> })<br> }))</pre> | `[]` | no |
| <a name="input_branches"></a> [branches](#input\_branches) | An optional map with GitHub branches to create | <pre>map(object({<br> source_branch = optional(string)<br> source_sha = optional(string)<br> use_branch_protection = optional(bool, true)<br><br> branch_protection = optional(object({<br> enforce_admins = optional(bool, false)<br> require_signed_commits = optional(bool, true)<br><br> required_checks = optional(object({<br> strict = optional(bool)<br> contexts = optional(list(string))<br> }))<br><br> restrict_pushes = optional(object({<br> blocks_creations = optional(bool)<br> push_allowances = optional(list(string))<br> }))<br><br> required_reviews = optional(object({<br> dismiss_stale_reviews = optional(bool, true)<br> dismissal_restrictions = optional(list(string))<br> required_approving_review_count = optional(number, 2)<br> require_code_owner_reviews = optional(bool, true)<br> }))<br> }), null)<br> }))</pre> | `{}` | no |
| <a name="input_default_branch"></a> [default\_branch](#input\_default\_branch) | Name of the default branch for the GitHub repository | `string` | `"main"` | no |
| <a name="input_default_branch_protection"></a> [default\_branch\_protection](#input\_default\_branch\_protection) | Default branch protection settings for managed branches | <pre>object({<br> enforce_admins = optional(bool, false)<br> require_signed_commits = optional(bool, true)<br><br> required_checks = optional(object({<br> strict = optional(bool)<br> contexts = optional(list(string))<br> }))<br><br> required_reviews = optional(object({<br> dismiss_stale_reviews = optional(bool, true)<br> dismissal_restrictions = optional(list(string))<br> required_approving_review_count = optional(number, 2)<br> require_code_owner_reviews = optional(bool, true)<br> }))<br><br> restrict_pushes = optional(object({<br> blocks_creations = optional(bool)<br> push_allowances = optional(list(string))<br> }))<br> })</pre> | <pre>{<br> "enforce_admins": false,<br> "require_signed_commits": true,<br> "required_reviews": {<br> "dismiss_stale_reviews": true,<br> "require_code_owner_reviews": true,<br> "required_approving_review_count": 2<br> }<br>}</pre> | no |
| <a name="input_delete_branch_on_merge"></a> [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | Automatically delete head branch after a pull request is merged | `bool` | `true` | no |
| <a name="input_description"></a> [description](#input\_description) | A description for the GitHub repository | `string` | `null` | no |
| <a name="input_environments"></a> [environments](#input\_environments) | An optional map with GitHub environments to configure | <pre>map(object({<br> secrets = optional(map(string), {})<br> wait_timer = optional(number, null)<br><br> deployment_branch_policy = optional(object(<br> {<br> custom_branch_policies = optional(bool, false)<br> protected_branches = optional(bool, true)<br> }),<br> {<br> custom_branch_policies = false<br> protected_branches = true<br> }<br> )<br><br> reviewers = optional(object({<br> teams = optional(list(string))<br> users = optional(list(string))<br> }), null)<br><br> }))</pre> | `{}` | no |
Expand Down
11 changes: 9 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ tasks:
test:
desc: Run Terraform tests
cmds:
- terraform init -test-directory=examples/basic
- terraform test -test-directory=examples/basic
- terraform init
- terraform test
silent: true

verbose-test:
desc: Run verbose Terraform tests
cmds:
- terraform init
- terraform test -verbose
silent: true
12 changes: 12 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Upgrading Notes

This document captures breaking changes.

## Upgrading to v1.0.0

First major release which also includes some breaking changes regarding how branches are configured:

- `var.branch_protection` has been removed, branch protection (and all other branch related settings) is now configured via `var.branches`. `var.default_branch_protection` has been added as a way to configure branch protection settings applied to all branches by default.
- `github_branch_protection` resource moves from a `count` to `for_each`. It should be safe to recreate these resources, if you want to avoid this please add relevant `moved` blocks.
- `require_signed_commits` setting defaults to true in the branch protection settings.
- The default branch is now also managed by `github_branch`; we saw some cases where changing the default branch resulted in the previous branch still existing and no longer managed by Terraform.
1 change: 1 addition & 0 deletions environments.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ locals {
}

resource "github_actions_environment_secret" "secrets" {
# checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - plaintext_value is a sensitive argument and there is no value in using a base64 encoded value here
for_each = {
for secret in local.environment_secrets : "${secret.environment}:${secret.name}" => secret
}
Expand Down
22 changes: 0 additions & 22 deletions examples/basic/main.tftest.hcl

This file was deleted.

86 changes: 86 additions & 0 deletions examples/branches/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
terraform {
required_version = ">= 1.3.0"

required_providers {
github = {
source = "integrations/github"
}
}
}

// This example to create and manage an additional branch called `develop`
module "basic" {
#checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - n/a for the example

source = "../.."

name = "basic"

branches = {
"develop" = {}
}
}

// This example should be the same as the above example.
module "with_default_branch" {
#checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - n/a for the example

source = "../.."

name = "basic"

branches = {
"develop" = {}
"main" = {}
}
}

// This example updates the default branch protection settings which should be applied to all branches
module "with_updated_default_branch_protection" {
#checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - n/a for the example

source = "../.."

name = "basic"

branches = {
"develop" = {}
}

default_branch_protection = {
enforce_admins = true
require_signed_commits = true
}
}

// This example creates a branch with custom branch protection settings
module "with_custom_branch_protection" {
#checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - n/a for the example

source = "../.."

name = "basic"

branches = {
"develop" = {
// if this is set, it takes precedence over the default branch protection settings
branch_protection = {
enforce_admins = true
require_signed_commits = true
}
}
}
}

// This example creates a branch without any branch protection
module "with_no_branch_protection" {
#checkov:skip=CKV_GIT_4:Ensure GitHub Actions secrets are encrypted - n/a for the example

source = "../.."

name = "basic"

branches = {
"develop" = { use_branch_protection = false }
}
}
Loading