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

first POC with GH settings and CODEOWNERS #14

Merged
merged 6 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
60 changes: 60 additions & 0 deletions .github/workflows/terraform-apply.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Apply new changes to SolEng repositories

on:
workflow_dispatch:
pull_request:
branches:
- main
paths:
- terraform-plans/**
push:
branches:
- main
paths:
- terraform-plans/**

jobs:
terraform:
name: Run Terraform
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
repository:
- soleng-tf-test-repo
chanchiwai-ray marked this conversation as resolved.
Show resolved Hide resolved
steps:
- name: Checkout branch
uses: actions/checkout@v4
- name: Install Terraform
run: sudo snap install terraform --classic
- name: Terraform init
working-directory: ./terraform-plans
run: terraform init
- name: Terraform validate
working-directory: ./terraform-plans
env:
GITHUB_APP_ID: ${{ secrets.SOLENG_APP_ID }}
GITHUB_APP_INSTALLATION_ID: ${{ secrets.SOLENG_APP_INSTALLATION_ID }}
GITHUB_APP_PEM_FILE: ${{ secrets.SOLENG_APP_PEM_FILE }}
run: terraform validate -no-color
- name: Terraform plan
working-directory: ./terraform-plans
env:
GITHUB_APP_ID: ${{ secrets.SOLENG_APP_ID }}
GITHUB_APP_INSTALLATION_ID: ${{ secrets.SOLENG_APP_INSTALLATION_ID }}
GITHUB_APP_PEM_FILE: ${{ secrets.SOLENG_APP_PEM_FILE }}
run: |
terraform plan -no-color \
-var-file=configs/github.tfvars \
-var-file=configs/${{ matrix.repository }}.tfvars
- name: Terraform Apply only on merge to main
if: ${{ github.event_name == 'push' }}
working-directory: ./terraform-plans
env:
GITHUB_APP_ID: ${{ secrets.SOLENG_APP_ID }}
GITHUB_APP_INSTALLATION_ID: ${{ secrets.SOLENG_APP_INSTALLATION_ID }}
GITHUB_APP_PEM_FILE: ${{ secrets.SOLENG_APP_PEM_FILE }}
run: |
terraform apply -no-color -auto-approve \
-var-file=configs/github.tfvars \
-var-file=configs/${{ matrix.repository }}.tfvars
48 changes: 48 additions & 0 deletions terraform-plans/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Terraform plans for Solution Engineering

Currently these plans are only for setting GitHub repos and to add workflow files.

## How to start
jneo8 marked this conversation as resolved.
Show resolved Hide resolved

1. Initialize Terraform.

```bash
terraform init
```

1. [Optional] If it's used locally for multiple repos. Create a workspace for each repo, otherwise terraform will try to overwrite the existing resource, e.g. repo.

```bash
terraform workspace new <repo-name>
```

1. Set GitHub authenetication for GitHub application.
```bash
export GITHUB_APP_ID="1234"
export GITHUB_APP_INSTALLATION_ID="56789"
export GITHUB_APP_PEM_FILE=$(cat ./my-app.private-key.pem)
```

1. [Optional] Create custom configuration or use one of defined in config directory.

```tfvars
owner = "<owner/org name>"
repository = "<repo name>"
branch = "main"
workflow_files = {
jira_sync_config = {
source = "./files/workflows/jira_sync_config.yaml"
destination = ".github/workflows/jira_sync_config.yaml"
}
codeowners = {
source = "./files/workflows/CODEOWNERS"
destination = ".github/CODEOWNERS"
}
}
```

1. Generate Terraform plan to validate it.

```bash
terraform plan -var-file=configs/github.tfvars -var-file=configs/soleng-tf-test-repo.tfvars
```
1 change: 1 addition & 0 deletions terraform-plans/configs/github.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
owner = "canonical"
8 changes: 8 additions & 0 deletions terraform-plans/configs/soleng-tf-test-repo.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
repository = "soleng-tf-test-repo"
branch = "main"
workflow_files = {
codeowners = {
source = "./files/github/CODEOWNERS"
destination = ".github/CODEOWNERS"
}
}
4 changes: 4 additions & 0 deletions terraform-plans/files/github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These owners will be the default owners for everything in the repo. Unless a
# later match takes precedence, @canonical/soleng-reviewers will be requested for
# review when someone opens a pull request.
@canonical/soleng-reviewers
9 changes: 9 additions & 0 deletions terraform-plans/imports.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {
to = module.github_settings.github_repository.repo
id = var.repository
}

import {
to = module.github_settings.github_branch_protection.branch_protection
id = "${var.repository}:${var.branch}"
}
17 changes: 17 additions & 0 deletions terraform-plans/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module "github_settings" {
source = "./modules/GitHub/settings"
owner = var.owner
repository = var.repository
branch = var.branch
force_push_bypassers = ["${var.owner}/soleng-admin"]
dismissal_restrictions = ["${var.owner}/soleng-admin", "${var.owner}/soleng-reviewers"]
pull_request_bypassers = ["${var.owner}/soleng-admin"]
}

module "github_workflow_files" {
source = "./modules/GitHub/workflows"
owner = var.owner
repository = var.repository
branch = var.branch
workflow_files = var.workflow_files
}
87 changes: 87 additions & 0 deletions terraform-plans/modules/GitHub/settings/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
terraform {
required_providers {
github = {
source = "integrations/github"
version = "~> 6.0"
}
}
}

provider "github" {
owner = var.owner
app_auth {} # using environmet variables for auth
}

chanchiwai-ray marked this conversation as resolved.
Show resolved Hide resolved
resource "github_repository" "repo" {
name = var.repository

has_issues = true
has_projects = false
has_wiki = false
has_discussions = false

allow_merge_commit = false
allow_squash_merge = true
allow_rebase_merge = false
allow_auto_merge = false

allow_update_branch = true
delete_branch_on_merge = true
Pjack marked this conversation as resolved.
Show resolved Hide resolved

}

data "github_team" "admins" {
slug = "soleng-admin"
}

data "github_team" "reviewers" {
slug = "soleng-reviewers"
}

data "github_team" "engineering" {
slug = "solutions-engineering"
}

resource "github_repository_collaborators" "repo_collaborators" {
repository = var.repository

team {
permission = "admin"
team_id = data.github_team.admins.id
}

team {
permission = "maintain"
team_id = data.github_team.reviewers.id
}

team {
permission = "push"
team_id = data.github_team.engineering.id
}
}

resource "github_branch_protection" "branch_protection" {
repository_id = github_repository.repo.node_id
pattern = var.branch
enforce_admins = true
Pjack marked this conversation as resolved.
Show resolved Hide resolved
require_signed_commits = true
required_linear_history = true
require_conversation_resolution = true
allows_deletions = false

allows_force_pushes = false
force_push_bypassers = var.force_push_bypassers

required_status_checks {
strict = true
}

required_pull_request_reviews {
dismiss_stale_reviews = true
dismissal_restrictions = var.dismissal_restrictions
pull_request_bypassers = var.pull_request_bypassers
require_code_owner_reviews = true
required_approving_review_count = 2
}
}
30 changes: 30 additions & 0 deletions terraform-plans/modules/GitHub/settings/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
variable "owner" {
type = string
description = "GitHub repository owner"
}

variable "repository" {
type = string
description = "GitHub repository name"
}

variable "branch" {
type = string
description = "Branch name"
default = "main"
}

variable "force_push_bypassers" {
type = list(any)
description = "List of user / groups that are allowed to bypass force push restrictions."
}

variable "dismissal_restrictions" {
type = list(any)
description = "List of user / groups with dismissal access."
}

variable "pull_request_bypassers" {
type = list(any)
description = "List of user / groups that are allowed to bypass pull request requirements."
}
49 changes: 49 additions & 0 deletions terraform-plans/modules/GitHub/workflows/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
terraform {
required_providers {
github = {
source = "integrations/github"
version = "~> 6.0"
}
}
}

provider "github" {
owner = var.owner
app_auth {} # using environmet variables for auth
}


resource "random_string" "update_uid" {
length = 8
numeric = true
special = false
}

resource "github_branch" "workflows_branch" {
repository = var.repository
branch = "${var.pr_branch}-${random_string.update_uid.id}"
source_branch = var.branch
}

resource "github_repository_file" "workflows_files" {
for_each = var.workflow_files
repository = var.repository
branch = github_branch.workflows_branch.branch
file = each.value.destination
content = file(each.value.source)
commit_message = "update ${each.value.destination}"
overwrite_on_create = true
}

resource "github_repository_pull_request" "workflows_update_pr" {
base_repository = var.repository
base_ref = var.branch
head_ref = github_branch.workflows_branch.branch
title = var.pr_title
body = var.pr_body

depends_on = [
github_branch.workflows_branch,
github_repository_file.workflows_files
]
}
41 changes: 41 additions & 0 deletions terraform-plans/modules/GitHub/workflows/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
variable "owner" {
type = string
description = "GitHub repository owner"
}

variable "repository" {
type = string
description = "GitHub repository name."
}

variable "branch" {
type = string
description = "Default branch name."
default = "main"
}

variable "pr_branch" {
type = string
description = "Pull request branch name."
default = "chore/update-workflows"
}

variable "pr_title" {
type = string
description = "Pull request title."
default = "Updating workflows files"
}

variable "pr_body" {
type = string
description = "Pull request body message."
default = "Updates workflows files by SolEng bot."
}

variable "workflow_files" {
type = map(object({
source = string
destination = string
}))
description = "GitHub workflow files"
}
23 changes: 23 additions & 0 deletions terraform-plans/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
variable "owner" {
type = string
description = "GitHub repository owner"
}

variable "repository" {
type = string
description = "GitHub repository name"
}

variable "branch" {
type = string
description = "git branch name"
default = "main"
}

variable "workflow_files" {
type = map(object({
source = string
destination = string
}))
description = "GitHub workflow files"
}