Skip to content

How it works

Yaffle is an OpenTofu execution platform. It receives events from GitHub, runs OpenTofu in isolated containers, manages state, and reports results back.

GitHub event → Control plane → Runner container → Results to GitHub
State storage
ComponentWhat it does
Control planeAPI server that receives webhooks and orchestrates runs
RunnerExecutes OpenTofu in isolated containers
State storageManaged state with per-environment isolation
LockingPrevents concurrent modifications

Environments are named targets for your infrastructure. Each environment has its own state file and can have its own variables and secrets.

[[environments]]
name = "production"
[[environments]]
name = "staging"

You can name environments whatever you want and have as many or as few as your workflow requires.

Triggers connect Git events to environments:

# Push to main applies to production
[[triggers.github.push]]
branch = "main"
environment = "production"
# PRs create preview environments
[[triggers.github.pull_request]]
branch_pattern = "*"

When a trigger fires:

  1. Webhook received — GitHub notifies Yaffle
  2. Workspace identified — Which paths to run, which environment
  3. Container launched — Fresh isolated runner
  4. Backend configured — State path set for this environment
  5. Secrets injected — Credentials loaded securely, never logged
  6. OpenTofu executesinit, plan, then apply (if approved)
  7. Results posted — Status checks and outputs to GitHub

Every environment and preview gets isolated state:

environments/
├── production/
│ └── infra/terraform.tfstate
└── staging/
└── infra/terraform.tfstate
previews/
├── pr-42/
│ └── infra/terraform.tfstate
└── pr-99/
└── infra/terraform.tfstate

This means:

  • PRs can’t conflict with each other
  • Previews can’t affect production
  • Multiple workspaces stay isolated
  • Isolated execution — Each run gets a fresh container
  • No local credentials — Secrets managed by Yaffle
  • Encrypted state — State encrypted at rest and in transit
  • Locked state — Concurrent writes prevented
  • Audit trail — Every run logged with user, commit, and plan