Manage the control repo with Terraform
Optional: hand this page to your coding agentThe steps work by hand too.Show the whole prompt
Read https://intentius.io/terragucci/guides/manage-the-control-repo-with-terraform/.
Read the terragucci.yml of the control repo I name and write a Terraform configuration that holds the same defaults and projects with terragucci_defaults and terragucci_project, plus the import blocks that adopt each of them.
Run `tofu plan` (or `terraform plan`) with the provider built as the page shows, and show me the plan. It must show no change other than the imports.
Never apply, approve (a pull request review or `terragucci approve`), override a policy denial (`terragucci override`), use `--mode apply`, or merge; never touch `.chant/allowed_signers` or `chant/lifecycle`.Result
Section titled “Result”A Terraform or OpenTofu configuration that owns the control repo’s terragucci.yml, as described in Govern many repos from one place. The provider commits each change through the forge’s API, so a plan shows which setting of which project moves before anything is written. terragucci reconcile reads what it wrote the same way it reads a hand-written config.
| Resource | Owns in terragucci.yml |
|---|---|
terragucci_defaults |
defaults |
terragucci_project |
one entry of projects, by its key |
Keys that no resource owns stay as they are, comments included. A resource whose key is already there refuses to overwrite it and names the import that adopts it.
Before you start
Section titled “Before you start”| You need | Why |
|---|---|
| A control repo on GitHub, GitLab or Forgejo | the provider writes its terragucci.yml |
A token that can push to the control repo’s branch: TERRAGUCCI_TOKEN, or GITHUB_TOKEN, GITLAB_TOKEN or FORGEJO_TOKEN |
each change is one commit through the API |
| Go 1.25 or later | you build the provider from the terragucci repository |
| Terraform or OpenTofu | to plan and apply |
-
Build the provider.
Terminal window git clone https://github.com/intentius/terraguccicd terragucci/terraform-provider-terraguccigo build -o "$HOME/.terragucci/provider/terraform-provider-terragucci" . -
Point Terraform or OpenTofu at the build.
Put this in a CLI configuration file, such as
~/.terragucci/dev.tfrc:provider_installation {dev_overrides {"intentius/terragucci" = "/home/you/.terragucci/provider"}direct {}}Use the full path of the directory you built into, and export
TF_CLI_CONFIG_FILE=$HOME/.terragucci/dev.tfrc. Terraform and OpenTofu then load the provider from that directory withoutinit, and print a warning saying so. -
Describe the control repo.
terraform {required_providers {terragucci = {source = "intentius/terragucci"}}}provider "terragucci" {forge = "github"repository = "acme/control"}resource "terragucci_defaults" "this" {settings = {binary = "tofu"gate = "on-destructive"}}resource "terragucci_project" "infra" {key = "github.com/acme/infra"settings = {roots = ["envs/*/*"]drift = "17 4 * * *"}}settingstakes the same keys asterragucci.yml(keys), as an HCL object. The provider block also takesurlfor a forge that is not github.com, gitlab.com or codeberg.org,apiwhen the API is not at the usual path under it,branch(default: the repository’s default branch),path(default:terragucci.yml) andtoken. -
Apply the configuration.
Terminal window tofu applyThe control repo gets one commit per resource, such as
terraform: add terragucci_project github.com/acme/infra. Destroying a resource takes its key out again; once no key is left,terragucci.ymlis deleted. -
Change a setting and plan.
After you add
parallelism = 2to the project’ssettings,tofu planshows that one setting.~ resource "terragucci_project" "infra" {id = "github.com/acme/infra"~ settings = {+ parallelism = 2# (2 unchanged attributes hidden)}}Each plan reads
terragucci.ymlfrom the forge first. A key someone edited or dropped by hand shows up as a change, which the next apply undoes. -
Open the projects’ pull requests.
In a clone of the control repo, run
reconcile:Terminal window npx terragucci reconcile --config terragucci.yml --mode applyEach project whose pipeline changes gets a pull request.
Adopt an existing file
Section titled “Adopt an existing file”Import each entry terragucci.yml already holds, then plan:
import {
to = terragucci_defaults.this
id = "defaults"
}
import {
to = terragucci_project.infra
id = "github.com/acme/infra"
}When the plan shows only the imports, the configuration matches the control repo.
- Govern many repos from one place covers what
reconciledoes with each project.
These docs count page views and clicks with PostHog. They set no cookies, store nothing in your browser, and send nothing when your browser asks not to be tracked.