-
Notifications
You must be signed in to change notification settings - Fork 0
Using as a Module
Instead of forking this repository, you can reference terraform/ as a reusable
Terraform module. This separates the shared infrastructure logic from your
per-org YAML configuration, so you only maintain config files and a short
main.tf.
terraform {
required_version = ">= 1.0"
required_providers {
github = {
source = "integrations/github"
version = "~> 6.0"
}
}
}
provider "github" {
owner = "your-org-name"
}
module "github_org" {
source = "github.com/gjed/github-configs-template//terraform?ref=v1.0.0"
config_path = "${path.root}/config"
}Pin ref to a release tag for reproducible builds.
your-org-configs/
├── main.tf
├── outputs.tf # optional — pass-through of module outputs
├── backend.tf # optional — remote state (see below)
└── config/
├── config.yml
├── group/
│ └── base.yml
├── repository/
│ └── *.yml
├── ruleset/
│ └── *.yml # optional
└── webhook/
└── *.yml # optional
A ready-to-copy starting point is in examples/consumer/.
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
config_path |
string |
yes | — | Path to the config/ directory. |
webhook_secrets |
map(string) |
no | {} |
Webhook secrets for env:VAR_NAME patterns. |
Important:
config_pathmust be a static string — e.g."${path.root}/config". Computed values (data sources, locals with unknown values) are not supported becausefile()andfileset()are evaluated at plan time.
| Output | Description |
|---|---|
organization |
GitHub org name read from config.yml
|
repository_count |
Number of managed repositories |
repositories |
Map of { name, url, ssh_url, visibility } per repo |
subscription_tier |
Subscription tier from config.yml
|
subscription_warnings |
Non-null when rulesets are skipped on free tier |
duplicate_key_warnings |
Non-null when duplicate keys appear across config files |
Reference outputs in your root module:
output "repositories" {
value = module.github_org.repositories
}The module does not configure the GitHub provider. You must declare it in your
consumer root with owner set to your organization name:
provider "github" {
owner = "your-org-name"
# Optional: rate limiting for large organizations (100+ repos)
# read_delay_ms = 0
# write_delay_ms = 100
}The provider is configured before Terraform evaluates the module, so the org name
from config.yml is not available at that stage — set it explicitly here.
Store state remotely for team use. Copy
examples/consumer/backend.tf.example
to backend.tf and uncomment the relevant block:
# S3 (AWS)
terraform {
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "github-org/terraform.tfstate"
region = "us-east-1"
encrypt = true
}
}The scripts/onboard-repos.sh and scripts/offboard-repos.sh scripts work with
both the direct layout (this repo used as a root) and the wrapped layout.
When using the module from a consumer root, pass --module-path so the scripts
target the correct Terraform state paths:
# Import a repo into state
./scripts/onboard-repos.sh \
--module-path "module.github_org." \
--import my-repo
# Remove a repo from state
./scripts/offboard-repos.sh \
--module-path "module.github_org." \
my-repo
# List repos in state
./scripts/offboard-repos.sh \
--module-path "module.github_org." \
--listIf you currently use this repo directly as a Terraform root, follow these steps:
-
Create a consumer directory with the minimal
main.tfshown above. -
Generate the
terraform state mvcommands with the migration helper:# Preview (safe — no changes) ./scripts/migrate-state.sh # Execute ./scripts/migrate-state.sh --execute
-
Add a
provider "github"block to your newmain.tf. -
Run
terraform initandterraform planto verify the state migration.
Getting Started
Reference
Advanced