Architecture
npx terragucci init writes a pipeline file for your forge; its CI runs everything in terragucci’s image. It needs no server or hosted service and keeps state in your backend. The package is Apache-2.0.
A change, start to finish
Section titled “A change, start to finish”Each step names its stage and the identity it runs with. All of them run on GitHub, GitLab and Forgejo.
-
The pull request:
tf-checkandtf-plan, with the read-only plan identity.tf-checkformats and validates every root on the branch push (on a pull request only from a fork).tf-planplans only the roots the change reaches, one layer at a time. -
The plan note:
tf-planposts one grouped comment naming every destroy and replacement, and setsterragucci/plan./terragucci planre-plans from a comment; on GitLab it needs thecommentsschedule. -
The merge: any push to the default branch runs
tf-applywith the apply identity, one push at a time. Under the defaulton-destructivegate only a wave that destroys or replaces waits. Withapply.when: pull-request, a writer’s/terragucci applycomment applies the open head instead (on GitLab, with thecommentsschedule). The guide lists what it refuses. -
The waves:
tf-applyruns one job per wave,waves.canaryroots first, then dependency order. Withwaves.jobs, a large wave gets a job that decides it and share jobs that apply it. Each wave plans after the previous one applied. -
The approval: no stage runs. A waiting job exits 3 and prints the approve command for its set digest. A person runs
terragucci approveto record an approval onchant/lifecycle, using their push access to that branch; underapproval: pr-reviewa review of the head also counts. Withapproval: sealedthe approval also carries a seal that must verify against.chant/allowed_signersfrom the commit before the applied one. -
The apply:
tf-apply, with the apply identity.terragucci approveor a rerun of the job restarts the waiting wave. So does a push or a/terragucci applycomment (on GitLab, with thecommentsschedule). The wave re-plans and refuses on a changed digest, and never applies a root twice. A comment that fails a check runs nothing. -
Drift: with
drift:set to a schedule,tf-driftplans every root with-refresh-onlyunder the plan identity and keeps one issue updated, closing it when drift is gone. It never applies.
Components
Section titled “Components”| Where | What |
|---|---|
| your machine | npx terragucci init, once and after a config change; terragucci approve, to approve a wave |
| your forge’s CI | every stage: check and plan on pull requests, apply on the default branch or the pull request, drift on schedule, comment jobs |
| your repository | the pipeline file, an optional terragucci.yml, the chant/lifecycle branch, and under approval: sealed chant.workspace.json and the signers file |
| your cloud | your state (with choudoufu, a tag on each resource in its place), and the plan and apply identities the jobs assume over OIDC |
| your bucket, if you set one | the reports and their index, the resource inventory and change history, and with terragucci estate and terragucci audit the delivery metrics and the audit trail (the layout) |
The plan identity is read-only because pull request code runs with it. Applying before merge gives the apply identity to unmerged code, so it is opt-in.
- Get your first plan note sets it up on a repository.
- The tutorial runs each step on a 15-root example on your laptop.
- Waves and approvals explains the waves and the gate.
- The approvals runbook has the commands for signers, pending waves and refusals.
- The glossary defines terragucci’s words and lists the ones that mean something else in Terraform.
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.