Quick start
Create a GitHub App, run teriac server with Docker or Helm, and get your first plan on a pull request.
Four steps: create a GitHub App, run the server, point the webhook at it, open a pull request.
1. Create a GitHub App
In GitHub, go to Settings → Developer settings → GitHub Apps → New GitHub App (under your organisation's settings for an org-wide App).
| Setting | Value |
|---|---|
| Webhook URL | https://<host>/events/github |
| Webhook secret | A long random string. Keep it: the server needs it |
| Events | Pull request, Issue comment, Check run |
| Permissions | See the table below |
| Logo | Upload brand/teriac-avatar.png under Display information |
Without a logo, GitHub shows the App owner's picture on teriac's comments.
Permissions
Under Permissions and events:
| Permission | Access | What teriac uses it for |
|---|---|---|
| Repository → Checks | Read & write | A check run per plan, the Apply button, and notes on risky lines of code |
| Repository → Contents | Read | Cloning the PR, reading teriac.yaml and CODEOWNERS, comparing the branch with its base (out-of-date warnings, keeping approvals after a rebase) |
| Read & write | Only for drift fix PRs (fix_pr: true): pushing the fix branch |
|
| Repository → Issues | Read & write | Posting and editing comments, and the 👀 reaction on commands (PR comments use the Issues API) |
| Repository → Pull requests | Read & write | Changed files, reviews and approvals, mergeable state, and opening drift fix PRs |
| Repository → Metadata | Read | Required by GitHub for every App |
| Organization → Members | Read | team: rules: approvers, permissions, override lists and emergency-access grantors |
Nothing else is needed: no Administration, Workflows, Secrets or Actions access.
After changing an App's permissions, an org owner must accept them under the org's Settings → GitHub Apps → Installed GitHub Apps, or the App keeps the old ones.
Then:
- Note the App ID.
- Generate a private key and save the
.pemfile. - Install the App on the repos (or the whole organisation) teriac should work on.
Make a webhook secret with:
openssl rand -hex 322a. Run it with Docker
mkdir -p secrets
cp ~/Downloads/your-app.*.private-key.pem secrets/app.pem
echo "$WEBHOOK_SECRET" > secrets/webhook
docker run -p 8080:8080 -v teriac-data:/data \
-v "$PWD/secrets:/run/secrets:ro" \
-e TERIAC_GITHUB_APP_ID=123456 \
-e TERIAC_GITHUB_PRIVATE_KEY_FILE=/run/secrets/app.pem \
-e TERIAC_GITHUB_WEBHOOK_SECRET_FILE=/run/secrets/webhook \
-e TERIAC_REPO_ALLOWLIST='github.com/acme/*' \
-e TERIAC_PUBLIC_URL=https://teriac.acme.dev \
ghcr.io/marcdomain/teriac-server:0.2.1- The image is published at ghcr.io/marcdomain/teriac-server.
- The
_FILEvariables point at files inside the container, which is whysecrets/is mounted. TERIAC_REPO_ALLOWLISTis required: a server that would run code from any repo refuses to start.- Add your cloud credentials with more
-eflags or an--env-file.
Check it's up:
curl http://localhost:8080/healthz # {"ok":true}With Docker Compose
# compose.yaml
services:
teriac:
image: ghcr.io/marcdomain/teriac-server:0.2.1
ports: ["8080:8080"]
volumes:
- teriac-data:/data
- ./secrets:/run/secrets:ro
- ./repos.yaml:/data/repos.yaml:ro
environment:
TERIAC_GITHUB_APP_ID: "123456"
TERIAC_GITHUB_PRIVATE_KEY_FILE: /run/secrets/app.pem
TERIAC_GITHUB_WEBHOOK_SECRET_FILE: /run/secrets/webhook
TERIAC_PUBLIC_URL: https://teriac.acme.dev
TERIAC_SESSION_SECRET_FILE: /run/secrets/session
env_file: cloud.env # AWS_*, ARM_*, GOOGLE_* …
restart: unless-stopped
volumes:
teriac-data:With repos.yaml mounted, list your repos there instead of TERIAC_REPO_ALLOWLIST. See
Rules and permissions.
2b. Or install it on Kubernetes with Helm
kubectl create namespace teriac
kubectl -n teriac create secret generic teriac-github \
--from-file=private-key=app.pem --from-literal=webhook-secret="$WEBHOOK_SECRET"
helm install teriac oci://ghcr.io/marcdomain/charts/teriac-server --version 0.2.1 -n teriac -f values.yaml# values.yaml
github:
appId: "123456"
existingSecret: teriac-github
config:
repoAllowlist: [github.com/acme/*]
requireApplyProject: true # one project per apply: teriac apply -p <project>
httpRoute:
enabled: true
parentRefs: [{ name: public-gateway, namespace: gateway-system }]
hostnames: [teriac.acme.dev]
dashboard:
oidc:
enabled: true
issuer: https://acme.okta.com/oauth2/default
clientId: 0oa1b2c3d4
existingSecret: teriac-okta # key: client-secret
adminGroups: [platform-admins]Every value, with its default, is in charts/teriac-server/values.yaml. Routing, sign-in and the rest are on the Helm chart page.
Then:
- Register
https://teriac.acme.dev/auth/oidc/callbackas the redirect URI with Okta. - Check the install with
helm test teriac -n teriac.
3. Point the webhook at the server
Set the GitHub App's webhook URL to https://teriac.acme.dev/events/github. In the App's Advanced
tab, Recent deliveries should show 200 responses.
Trying it on your laptop? Expose port 8080 with a tunnel (for example cloudflared tunnel --url
http://localhost:8080) and use that URL.
4. Open a pull request
Change a Terraform, Terragrunt or OpenTofu project in a repo on the allowlist. Within moments:
- 👀 shows teriac picked it up;
- a comment lists each affected project, its plan, and the command to apply it;
- a check run
teriac: <project>appears per project, with an Apply button.
Comment teriac help on the PR to see every command, or read PR commands.
Next steps
- Decide who can apply what: Rules and permissions
- Add policy checks: Policy checks and safety
- Turn on dashboard sign-in: Dashboard and API
- Get drift alerts: Drift checks
- Production checklist: Security model
- Running on AWS? Follow the EKS guide