An Action pairs a graph operation (create / update / transition an entity or relationship) with a trigger that does the real work against an external substrate. This page is the lookup reference for what each trigger does when an Action fires — the dispatch behavior, the flow, and the terminal states. For the full YAML field tables, see the Action schema.
Terrantula never runs terraform apply itself. Every substrate trigger
either opens a pull request against your repo or asks a runner you control to
plan/apply. The graph is a read-only projection of the resulting TF-derived
state. Terrantula triggers and observes; your CI applies.
When an Action is triggered (from the UI, the API, the CLI, or a cascade), the worker:
parameters, recommendations, and any
{{ secrets.* }} references in the trigger config.entity, parameters, recommendations, run — see
Interpolation).trigger.type.metadata field.running and the entity/relationship to its
onTrigger state.The ActionRun reaches a terminal state (succeeded / failed) when the
substrate reports completion — by GitHub/Atlantis webhook, by polling, or by a
callback. If nothing reports back, the reaper times the run out after the
Action's timeout (default 60 minutes) and marks it failed.
| Type | Substrate | What it does |
|---|---|---|
pull-request | GitHub | Opens a PR via the Git Data API; auto-completes on merge/close. |
terraform-cloud | TFC / HCP Terraform | Fires a run against a pre-existing workspace; polls to a terminal state. |
atmos-workflow | Atmos | POSTs to a customer-deployed runner that runs atmos workflow. |
atlantis | Atlantis | Opens a PR (default) or calls Atlantis's API directly. |
webhook | Generic HTTP | Calls any URL with an interpolated payload; completion by callback. |
noop | none | Transitions the run to succeeded immediately (cascade-only / in-Terrantula effects). |
Substrate order follows the product commitment: Terraform first, Atmos as a peer substrate, OpenTofu second. All four substrate triggers are tier-1.
Purpose. Open a GitHub pull request with file changes and wait for a human to merge or close it. The PR-based approval pattern is the core of the cross-team flow: a requesting team triggers the Action, the owning team gets a PR in their own repo and review queue, their existing pipeline applies, and Terrantula tracks the outcome.
Config. See the Action schema → pull-request for the full field table.
Flow. The worker creates head from base via the Git Data API, commits
all files, opens the PR, and stores { prNumber, prUrl, repo } in the
ActionRun's metadata. On PR close:
succeeded; entity/relationship transitions to onSuccess.failed; transitions to onFailure.Notes.
webhookSecret set — see
Webhooks → PR-trigger webhook.
Without it, the PR still opens but the run won't auto-complete.auth.token and Terrantula mints an installation token.
A static auth.token is the Sam-cohort escape hatch for GHE-Server / no-App
setups.Purpose. Fire a Terraform Cloud / HCP Terraform run against a pre-existing workspace. Terrantula never executes Terraform — TFC runs the plan/apply, Terrantula triggers and observes.
Config. See the Action schema → terraform-cloud for the full field table.
Flow. The worker resolves workspaceName to an ID, POSTs /api/v2/runs,
stores { runId, runUrl, workspaceId, workspaceName, organization, status } in
metadata, then polls GET /api/v2/runs/:id until a terminal status:
applied, planned_and_finished, planned_and_saved,
planned, policy_checked.errored, discarded, canceled, force_canceled,
policy_soft_failed.Notes.
autoApply: false is plan-only. With the default, the entity transitions
to onSuccess when the run reaches planned — the plan finished but the
infrastructure has not yet been provisioned. Set autoApply: true if the
entity should only transition once TFC reaches applied.sensitive: false).
Never pass API keys/passwords here — configure those as workspace-level
sensitive variables in TFC. Run-scoped variables are for routing data (tenant
IDs, regions, plan tiers).apply. TFC
pulls config from the workspace's VCS settings; configSource is
informational.Purpose. Invoke a named Atmos workflow on a runner you deploy. Atmos workflows mirror Terrantula Actions architecturally — both are named, parameterized invocations against a deployment target.
Config. See the Action schema → atmos-workflow for the full field table.
Flow. The trigger HTTP-POSTs a structured payload to runner.endpoint. The
runner clones your Atmos repo, runs atmos workflow <name> -s <stack>, and POSTs
back to the run's callback URL to signal completion.
Notes.
terrantula-atmos-runner container, or a GitHub Actions / GitLab CI workflow
template, and point the trigger at it. Terrantula never hosts the runner —
this keeps the Atmos path runnable with zero SaaS dependencies.runner.endpoint is validated against the same internal-address
blocklist as the Atlantis trigger.Purpose. Drive a customer-hosted Atlantis instance. Two modes.
Config. See the Action schema → atlantis for the full field table.
Pull-request mode (default). Terrantula opens a GitHub PR with the file
changes; Atlantis picks it up via its own webhook subscription and runs
plan/apply. Behaves like the pull-request trigger but is
explicitly labeled for Atlantis; produces
{ mode: 'pull-request', prNumber, prUrl, repo } metadata. On merge,
Terrantula's webhook transitions the run.
API-dispatch mode. Terrantula calls Atlantis's /api/plan or /api/apply
endpoint directly (synchronous, no PR cycle), parses the project results, stores
{ mode: 'api-dispatch', command, projectResults, planOutput }, and POSTs the
callback.
Notes.
atlantis.yaml — that stays in your repo (or is patched via the PR-trigger's
file-patch operation). Even in api-dispatch mode, Atlantis runs the apply on
its own infrastructure.X-Atlantis-Token header, set via Atlantis's --api-secret.endpoint requires https:// and is validated against the
shared internal-address blocklist (loopback, link-local, RFC 1918, CGNAT,
IPv6 ULA/multicast, IPv4-mapped IPv6).A single Action can override trigger fields per environment via envOverrides
(different TFC workspaces / webhook URLs / repos in dev vs prod). Override fields
are shallow-merged onto the base trigger at dispatch; the type must match the
base trigger's type. See the
Action schema → per-env overrides.
{{ secrets.* }} resolves