Skip to content

Govern many repos from one place

llms.txtlists every page for an agent
Optional: hand this page to your coding agentThe steps work by hand too.
Show the whole prompt
Read https://intentius.io/terragucci/guides/govern-many-repos/.
In this control repo, write terragucci.yml with the projects I name, run `npx terragucci config check`, then run the preview, `npx terragucci reconcile --config terragucci.yml`, and show me its output for each project.
Open a pull request in this control repo with the file. Print the `--mode apply` command for me to run; do not run it.
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`.

A control repo whose terragucci.yml lists every project. One command previews each project’s pipeline and another opens a pull request in each project that changes; the projects’ own pipelines apply.

You need Why
A repo to act as the control repo it holds only terragucci.yml
A token per forge that can push branches and open pull requests: GITHUB_TOKEN, GITLAB_TOKEN or FORGEJO_TOKEN, or the variable a project’s token_env names reconcile opens a pull request in each project
Projects on GitHub, GitLab or Forgejo they can be mixed in one file
  1. List the projects.

    A project is its address on the forge. defaults apply to every project, and a project’s own keys override them.

    defaults:
    binary: tofu
    gate: on-destructive
    projects:
    github.com/acme/infra:
    roots: ["envs/*/*"]
    gitlab.example.com/platform/network:
    binary: terraform
    drift: "17 4 * * *"
    codeberg.org/acme/edge: {}

    A repo you leave out is never touched. terragucci.yml keys lists what a project can set.

    To check every project against one policy repo, put policy.source under defaults:

    defaults:
    policy:
    source: git+https://github.com/acme/policy.git@v3

    Control repo lists what each project’s pull request carries and what the project keeps.

  2. Check the file.

    Terminal window
    npx terragucci config check
    terragucci.yml: ok
    approval: ledger (the default)
  3. Preview.

    Terminal window
    npx terragucci reconcile --config terragucci.yml

    This dry run says per project whether the pipeline would change, and prints the files and setup tips. --project github.com/acme/infra narrows it to one project; --json prints one object (JSON output).

  4. Open the pull requests.

    Terminal window
    npx terragucci reconcile --config terragucci.yml --mode apply

    Each project gets a pull request instead of a push to its main branch, and current projects are left alone; --mode apply runs no terraform apply. The exit code is 1 when any project failed.

    The description of the pull request reconcile opened in a Forgejo project with no pipeline: the control repo's config changed what the pipeline should be, so it adds .forgejo/workflows/terragucci.yml and terragucci.yml, for the project to review and mergeThe description of the pull request reconcile opened in a Forgejo project with no pipeline: the control repo's config changed what the pipeline should be, so it adds .forgejo/workflows/terragucci.yml and terragucci.yml, for the project to review and merge
    That pull request's files: the start of the generated .forgejo/workflows/terragucci.yml, its triggers and its check job pinned by digest, and the two-line terragucci.yml naming the tokenThat pull request's files: the start of the generated .forgejo/workflows/terragucci.yml, its triggers and its check job pinned by digest, and the two-line terragucci.yml naming the token
  5. Merge in each project.

    Each team reviews its pull request. A later reconcile, such as after editing defaults, opens one only where something changed.

terragucci

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.