https://github.com/xebis/github-organization-as-code
Manage your GitHub organization's repositories using GitOps principles with a YAML-based configuration, GitHub Actions with reusable workflows, AWS S3 for storage, and GitHub App integration.
https://github.com/xebis/github-organization-as-code
github github-app github-management github-organization github-repositories github-workflows gitops iac terraform terraform-backend-s3 terraform-github terraform-github-provider yaml-configuration
Last synced: 4 months ago
JSON representation
Manage your GitHub organization's repositories using GitOps principles with a YAML-based configuration, GitHub Actions with reusable workflows, AWS S3 for storage, and GitHub App integration.
- Host: GitHub
- URL: https://github.com/xebis/github-organization-as-code
- Owner: xebis
- License: mit
- Created: 2025-02-25T21:15:46.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-07-01T21:38:14.000Z (6 months ago)
- Last Synced: 2025-07-01T22:28:44.014Z (6 months ago)
- Topics: github, github-app, github-management, github-organization, github-repositories, github-workflows, gitops, iac, terraform, terraform-backend-s3, terraform-github, terraform-github-provider, yaml-configuration
- Language: HCL
- Homepage:
- Size: 19.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# GitHub Organization as Code
Manage your GitHub organization's repositories using GitOps principles with a YAML-based configuration, GitHub Actions with reusable workflows, AWS S3 for storage, and GitHub App integration.
## Features
- **Automated Repository Management** - Define repositories, and repository properties using simple YAML file.
- **GitOps Workflow** - Manage configurations via pull requests and automate updates using GitHub Actions.
- **Terraform** - Uses Terraform under the hood to apply changes efficiently.
- **Terraform State Management** - Stores Terraform state securely in AWS S3.
- **GitHub App Integration** - Uses a GitHub App for authentication and API interactions.
### Fun Fact
This repository was automatically created and is continuously managed using the very code inside it!
## Installation and Configuration
- Configure an AWS S3 bucket to store Terraform state files.
- Set up a GitHub App and its installation to handle authentication and authorization for your GitHub Organization.
- Implement GitOps by setting up a GitHub repository with:
- YAML-based configuration
- GitHub workflows
- Repository variables and secrets
> [!caution]
> The GitHub App PEM file, S3 API credentials, Terraform state, GitHub repository secrets, and configuration code are key security elements.
### Set Up AWS S3 Bucket
Set up an AWS S3 bucket or a compatible storage service.
> [!important]
> Ensure you have the following details ready:
>
> - Bucket Name
> - Access Key ID
> - Secret Access Key
> - Region
> - S3 Endpoint URL (only required for non-AWS S3-compatible services)
### Set Up GitHub Organizations
Create a GitHub App:
- GitHub / *Organization* / Settings / Developer Settings / GitHub Apps / **New GitHub App**
- Register new GitHub App
- GitHub App name: *Your GitHub App name*
- Description: *Your GitHub App description*
- HomepageURL: *Your GitHub App URL*
- Webhook
- Active: unchecked
- Permissions
- Repository permissions
- Administration: Read and write
- Organization permissions
- Administration: Read and write
- Where can this GitHub App be installed?:
Only on this account *(for installations only in the current organization)*
Any account *(for installations in any organization)*
Install the GitHub App:
- GitHub / *Organization* / Settings / Developer Settings / GitHub Apps / *Your GitHub App name* / Install App
- **For each** *owner*
- **Install**
- for these repositories: All repositories
- **Install**
Get the GitHub App credentials:
- GitHub / *Organization* / Settings / Developer Settings / GitHub Apps / *Your GitHub App name* / General / Private keys / **Generate a private key**
> [!important]
> Ensure you have the following details ready:
>
> - GitHub Owner
> - GitHub App ID
> - GitHub App Installation ID
> - GitHub App PEM File
### Set Up GitHub Repository for GitHub Organization Management
Create GitHub organization YAML configuration file. See [GitHub Organization YAML](#github-organization-yaml) below.
For example:
```yaml
---
repositories:
- name: .github
description: The organization profile.
topics:
- github-organization-profile
- github-profile
- github-profile-readme
```
Create GitHub workflow planning and applying configuration changes to the GitHub Organization:
```yaml
---
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
call-terraform:
uses: xebis/github-organization-as-code/.github/workflows/terraform.yaml@v0
with:
aws_region: ${{ vars.AWS_REGION }}
aws_endpoint_url_s3: ${{ vars.AWS_ENDPOINT_URL_S3 }}
gh_owner: ${{ vars.GH_OWNER }}
gh_app_id: ${{ vars.GH_APP_ID }}
gh_app_installation_id: ${{ vars.GH_APP_INSTALLATION_ID }}
path: xebis.yaml
secrets:
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
gh_app_pem_file: ${{ secrets.GH_APP_PEM_FILE }}
```
Set up GitHub actions, variables and secrets:
- GitHub / *Repository* / Settings
- Actions / General
- Workflow permissions: Read and write permissions
- Secrets and variables / Actions / Actions secrets and variables
- Secrets
- **New repository secret**
- `GH_APP_PEM_FILE` (`GITHUB_APP_PEM_FILE` contents)
- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- Variables
- **New repository variable**
- `GH_APP_ID` (`GITHUB_APP_ID`)
- `GH_APP_INSTALLATION_ID` (`GITHUB_APP_INSTALLATION_ID`)
- `AWS_ENDPOINT_URL_S3`
- `AWS_REGION`
- `GH_OWNER` (`GITHUB_OWNER`)
## Usage
The GitHub organization YAML configuration post a Terraform plan as a pull request comment whenever a pull request to the main branch is created or whenever a new commit to the pull request is pushed. Once the pull request is merged into `main`, the plan is applied automatically.
> [!note]
> The state is stored as JSON object `github//terraform.tfstate` in the bucket.
### GitHub Organization YAML
The example below demonstrates the full range of capabilities available in the organization YAML configuration.
```yaml
---
organization:
all-repositories: # OPTIONAL
# All-repository default properties
visibility: public # OPTIONAL, DEFAULT public
# All-repository default features
has_issues: true # OPTIONAL, DEFAULT false
has_discussions: true # OPTIONAL, DEFAULT false
has_projects: true # OPTIONAL, DEFAULT false
has_wiki: true # OPTIONAL, DEFAULT false
# All-repository default settings
allow_merge_commit: false # OPTIONAL, DEFAULT true
allow_squash_merge: true # OPTIONAL, DEFAULT true
allow_rebase_merge: true # OPTIONAL, DEFAULT true
allow_auto_merge: true # OPTIONAL, DEFAULT false
delete_branch_on_merge: true # OPTIONAL, DEFAULT false
# All-repository default rulesets
rulesets:
- name: "Main Branch"
target: branch # REQUIRED, VALUES branch or tag
enforcement: active # REQUIRED, VALUES disabled or active
bypass_actors: # OPTIONAL, DEFAULT empty
# Xebis GitHub Semantic Release https://github.com/apps/xebis-github-semantic-release
- actor_id: 1527160 # REQUIRED, VALUE The ID of the actor
actor_type: Integration # REQUIRED, VALUES RepositoryRole, Team, Integration, OR OrganizationAdmin
bypass_mode: always # REQUIRED, VALUES always or pull_request
conditions: # OPTIONAL, DEFAULT empty
ref_name:
include: # OPTIONAL, DEFAULT empty, VALUE array of ref names or patterns to include, SPECIAL VALUES ~ALL and ~DEFAULT_BRANCH also accepted
- ~DEFAULT_BRANCH
exclude: # OPTIONAL, DEFAULT empty
rules:
creation: true # OPTIONAL, DEFAULT false
update: true # OPTIONAL, DEFAULT false
update_allows_fetch_and_merge: false # OPTIONAL, DEFAULT false
deletion: true # OPTIONAL, DEFAULT false
required_linear_history: true # OPTIONAL, DEFAULT false
required_signatures: true # OPTIONAL, DEFAULT false
pull_request: # OPTIONAL, DEFAULT empty MEANING does not require a pull request before merging
required_approving_review_count: 0 # OPTIONAL, DEFAULT 0
repositories:
- name: repo-slug
# Repository metadata
description: Repository description. # OPTIONAL, DEFAULT none
homepage_url: http://repo.domain/ # OPTIONAL, DEFAULT none
topics: # OPTIONAL, DEFAULT none
- github-topic-1
# Repository properties
visibility: public # OPTIONAL, DEFAULT public
is_template: true # OPTIONAL, DEFAULT false
# Repository features
has_issues: true # OPTIONAL, DEFAULT false
has_discussions: true # OPTIONAL, DEFAULT false
has_projects: true # OPTIONAL, DEFAULT false
has_wiki: true # OPTIONAL, DEFAULT false
# Repository settings
allow_merge_commit: false # OPTIONAL, DEFAULT true
allow_squash_merge: true # OPTIONAL, DEFAULT true
allow_rebase_merge: true # OPTIONAL, DEFAULT true
allow_auto_merge: true # OPTIONAL, DEFAULT false
delete_branch_on_merge: true # OPTIONAL, DEFAULT false
```
Defaults are usually the same as in the Terraform provider `github` resource `github_repository`, see [Terraform Registry / Providers / integrations / github / resources / github_repository](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository#argument-reference).
### Local Usage
Apply the configuration using Terraform:
```shell
# Environment variables
export AWS_REGION=
export AWS_ENDPOINT_URL_S3= # Only for non-AWS S3 compatible APIs
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export GITHUB_OWNER=
export GITHUB_APP_ID=
export GITHUB_APP_INSTALLATION_ID=
export GITHUB_APP_PEM_FILE=$(cat )
export TF_WORKSPACE="$GITHUB_OWNER"
export TF_VAR_path="../test.yaml"
# Terraform
terraform -chdir=terraform init
terraform -chdir=terraform plan
terraform -chdir=terraform apply
```
## Testing
This repository is tested using [`test.yaml`](test.yaml) as the configuration file for the [Xebis Test GitHub Organization](https://github.com/xebis-test) settings and repositories.
The workflow is designed to post a Terraform plan as a pull request comment whenever a pull request to the main branch is created or whenever a new commit to the pull request is pushed. Once the pull request is merged into `main`, the plan is applied automatically.
## Credits and Acknowledgments
- Martin Bružina - Author
## Copyright and Licensing
- MIT License
Copyright © 2025 Martin Bružina