-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Summary
Refactor the current project into a standalone, reusable Terraform module that any consuming repo can call with a single module block. The consuming repo should only need to maintain YAML config files and a minimal main.tf.
Motivation
Currently, using this project for a new GitHub org requires forking or copying the entire repo. Extracting it into a reusable module lets multiple orgs adopt the YAML-driven config pattern without duplicating Terraform logic.
Design
Module interface
The module accepts a config_path variable pointing to the consumer's YAML config directory and handles all parsing, merging, and resource creation internally.
variable "config_path" {
description = "Path to the root config directory containing config.yml and subdirectories"
type = string
}
variable "webhook_secrets" {
type = map(string)
default = {}
sensitive = true
}
variable "github_read_delay_ms" {
type = number
default = 0
}
variable "github_write_delay_ms" {
type = number
default = 100
}Module structure (published module)
terraform-github-org/
├── main.tf # Org-level resources + module.repositories call
├── yaml-config.tf # All YAML parsing/merging logic
├── variables.tf # Module inputs (config_path, webhook_secrets, etc.)
├── outputs.tf # Module outputs
├── modules/
│ └── repository/ # Existing submodule (unchanged)
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── README.md
Consumer repo structure
my-org-github/
├── config/
│ ├── config.yml
│ ├── group/
│ │ └── *.yml
│ ├── repository/
│ │ └── *.yml
│ ├── ruleset/
│ │ └── *.yml
│ └── webhook/
│ └── *.yml
├── main.tf # ~15 lines: provider + module call
├── outputs.tf
├── backend.tf
└── Makefile # Optional
Consumer main.tf example
terraform {
required_version = ">= 1.6"
required_providers {
github = {
source = "integrations/github"
version = "~> 6.0"
}
}
}
provider "github" {
owner = "my-org"
}
module "github_org" {
source = "git::https://github.com/gjed/terraform-github-org.git?ref=v1.0.0"
config_path = "${path.root}/config"
}Implementation tasks
- Remove the
provider "github"block from the module — consumers must configure their own provider - Add
config_pathvariable and replace all hardcodedconfig/paths inyaml-config.tfwithvar.config_path-relative paths - Verify
file()/fileset()calls work correctly with consumer-relative paths (must usepath.root-based resolution) - Update module outputs to expose
organizationso consumers can reference it - Update
onboard-repos.shandoffboard-repos.shto support nested module state paths (e.g.module.github_org.module.repositories["repo"]) - Ship
validate-config.pyand.pre-commit-config.yamlas a consumer template/scaffold (not inside the TF module) - Create a consumer template repo or example directory showing the minimal setup
- Add documentation (README) for the published module
- Tag initial release
Notes
- The
ownerfield can no longer be read from YAML by the module to configure the provider (providers are configured before modules run). Consumers setownerdirectly in their provider block. - Terraform's
file()requires paths known at plan time —config_pathmust be a static string (e.g."${path.root}/config"), not a computed value. - The YAML-config-inside-module approach is intentional. Forcing consumers to pre-process YAML would just push complexity around for no benefit.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels