Skip to main content

Manage Lifecycle Events with Hooks

Atmos hooks run automated actions at specific points in a component's lifecycle — before/after terraform plan, apply, deploy, or init. Built-in kinds cover the common cases (cost analysis, security scanning, storing outputs) and the generic command kind plugs in any binary you need. Tools auto-install through the Atmos toolchain and their output renders identically in your terminal and on Atmos Pro.

Hooks Schema

Each hook has a kind that selects an engine and a set of defaults. The generic command kind runs any binary; named kinds like infracost and trivy ship sane defaults so you don't need to write any wiring.

components:
terraform:
vpc:
hooks:
# Cost diff after every plan — zero config.
cost:
events: [after.terraform.plan]
kind: infracost

# Security scan after every plan.
security:
events: [after.terraform.plan]
kind: trivy

# Store outputs after apply (the original hook use case).
outputs:
events: [after.terraform.apply]
kind: store
name: prod/ssm
outputs:
vpc_id: .id

Hooks can be declared at the global level, the terraform section, an individual component, or in the overrides section. Partial config at each level merges into the final result so you can keep configuration DRY.

Supported Lifecycle Events

EventWhen it fires
before.terraform.initBefore atmos terraform init runs
after.terraform.initAfter atmos terraform init finishes
before.terraform.planBefore atmos terraform plan runs (after init has completed)
after.terraform.planAfter atmos terraform plan finishes
before.terraform.applyBefore atmos terraform apply runs
after.terraform.applyAfter atmos terraform apply finishes
before.terraform.deployAlias of before.terraform.apply (deploy is apply with -auto-approve)
after.terraform.deployAlias of after.terraform.apply

Hooks with no events list fire on every supported event for backward compatibility with configs written before event filtering existed. You should use the dotted form (after.terraform.plan) in new configs. The legacy hyphenated form (after-terraform-plan) is still accepted and equivalent for backward compatibility.

The before.terraform.init and after.terraform.init events fire around the explicit atmos terraform init command. They do not fire for the implicit init that plan, apply, and deploy run automatically — use before.terraform.plan / before.terraform.apply for those.

Built-in Kinds

Each named kind below ships defaults for command, args, env, and on_failure so the minimal config (just events and kind) does the right thing. Every default is overridable — set the field on your hook and your value wins. See Overriding Kind Defaults for the override rules (notably: args and env are full replacement, not merge).

kind: infracost

Runs Infracost to compute monthly cloud cost estimates from your Terraform plan. Renders a cost diff card with the top resources by monthly cost.

hooks:
cost:
events: [after.terraform.plan]
kind: infracost

Requires INFRACOST_API_KEY to be set in the shell or on the hook (free at infracost.io).

kind: trivy

Trivy is an open-source security and misconfiguration scanner from Aqua Security. The trivy kind runs Trivy in config mode against the component's Terraform sources and feeds the SARIF output through Atmos's shared scanner result handler.

hooks:
security:
events: [after.terraform.plan]
kind: trivy
command (default)
trivy.
args (default)
config --format sarif --output $ATMOS_OUTPUT_FILE --quiet $ATMOS_COMPONENT_PATH.
Output
Single SARIF file written directly to $ATMOS_OUTPUT_FILE.
on_failure (default)
warn — a scanner finding does not block your plan unless you override this.
Runtime requirements
The trivy binary on PATH. Declare it in dependencies.tools to have Atmos auto-install through the toolchain.
Authentication
None required for config scans.

kind: checkov

Checkov is an open-source policy-as-code scanner maintained by Bridgecrew / Prisma Cloud (Palo Alto Networks). The checkov kind runs Checkov over the component's Terraform sources and feeds the SARIF output through Atmos's shared scanner result handler.

hooks:
policy:
events: [after.terraform.plan]
kind: checkov
command (default)
checkov.
args (default)
-d $ATMOS_COMPONENT_PATH -o sarif --output-file-path $ATMOS_OUTPUT_DIR --quiet --soft-fail. Note: Checkov's --output-file-path takes a directory and writes results_sarif.sarif inside it.
Output
SARIF file written to $ATMOS_OUTPUT_DIR/results_sarif.sarif; the kind's result handler reads from that nested path.
on_failure (default)
warn.
Runtime requirements
The checkov binary on PATH. Declare it in dependencies.tools to have Atmos auto-install through the toolchain.
Default env additions
Atmos sets SSL_CERT_FILE from the host CA bundle when one is detected. The PyInstaller-packaged Checkov release ships a frozen certifi bundle that often cannot validate the TLS chain serving api0.prismacloud.io (the API Checkov hits at startup to fetch guideline mappings); pointing SSL_CERT_FILE at the host bundle is the official PyInstaller workaround. On hosts where Atmos cannot detect a CA bundle, the kind makes no env change and Checkov falls back to its bundled certifi.

kind: kics

KICS (Keeping Infrastructure as Code Secure) is an open-source IaC scanner from Checkmarx. The kics kind runs KICS over the component's Terraform sources and feeds the SARIF output through Atmos's shared scanner result handler.

hooks:
iac-scan:
events: [after.terraform.plan]
kind: kics
command (default)
kics.
args (default)
scan -p $ATMOS_COMPONENT_PATH -o $ATMOS_OUTPUT_DIR --report-formats sarif --no-progress.
Output
SARIF file written to $ATMOS_OUTPUT_DIR/results.sarif.
on_failure (default)
warn.
Runtime requirements
The kics binary on PATH. Declare it in dependencies.tools to have Atmos auto-install through the toolchain — Atmos ships a curated registry override so kics: "<version>" resolves correctly even though the upstream Aqua entry uses an unsupported go_build type.
KICS_QUERIES_PATH
Required at runtime. The KICS release tarball does not include the query library. Homebrew install: export KICS_QUERIES_PATH=$(brew --prefix kics)/share/kics/assets/queries. For toolchain installs, point at the unpacked assets/queries directory shipped alongside the release archive.

All three scanner kinds emit SARIF and share a result handler that renders findings as a compact markdown table — severity, rule ID (linked to the upstream remediation guide when available), short description, and file:line location. The same markdown body flows to your terminal, the Atmos Pro run page, and PR comments.

kind: store

Reads Terraform outputs and writes them to an external store such as kind: aws/ssm, kind: aws/asm, Azure Key Vault, or Google Secret Manager. Use this to share state between components without backend wiring — paired with the !store function for reading.

hooks:
outputs:
events: [after.terraform.apply]
kind: store
name: prod/ssm
outputs:
vpc_id: .id
private_subnet_ids: .private_subnet_ids

See Store function reference below for configuration details.

kind: git

Publishes component artifacts to a Git repository on lifecycle events — commit (and optionally push) generated files through the shared Atmos Git service, with its safety rules (no force push, path-scoped commits, bounded push retry) and authentication built in.

By default the hook targets the current repository — the repo the component already lives in — matching the common case of committing generated files back to the working repo after terraform apply:

components:
terraform:
app:
hooks:
publish-artifacts:
events:
- after.terraform.apply
kind: git
# repository omitted -> the current repository
commit:
message: "Update generated artifacts for {{ .component }} in {{ .stack }}"
paths:
- generated/{{ .stack }}/{{ .component }}
push: true

Setting repository: <name> targets a managed repository configured under the top-level git.repositories section instead — Atmos clones/reconciles its workdir, commits, and pushes with the repository's configured identity, signing, and retry settings:

components:
terraform:
app:
hooks:
publish-artifacts:
events:
- after.terraform.apply
kind: git
repository: generated-terraform
commit:
message: "Update generated artifacts for {{ .component }} in {{ .stack }}"
push: true

Behavior notes:

  • Clean no-op: when there are no changes to commit, the hook succeeds without creating a commit — no empty commits.
  • Push only on commit: push: true pushes only when a commit was actually created.
  • Provenance trailers: published commits carry Atmos-Stack, Atmos-Component, and Atmos-Source-SHA trailers, making deployment-repo commits traceable back to exactly what produced them.
  • Failure mode: unlike the advisory tool kinds, kind: git defaults to on_failure: fail — a silently dropped commit or push loses artifacts. Override with on_failure: warn or ignore if publishing is best-effort.
  • Templating: commit.message and commit.paths support the standard hook template context ({{ .component }}, {{ .stack }}, {{ .vars.* }}).

kind: git hooks are separate from local Git hooks (pre-commit, commit-msg, ...) — those are configured under git.hooks and managed by atmos git hooks.

kind: command (generic engine)

The escape hatch — runs any toolchain-resolved binary with Atmos's standard ATMOS_* env-var contract. Use when no built-in kind fits your tool.

hooks:
custom-scan:
events: [after.terraform.plan]
kind: command
command: my-internal-scanner
args:
- "--component"
- "{{ .atmos_component }}"
- "--source"
- "$ATMOS_COMPONENT_PATH"
- "--out"
- "$ATMOS_OUTPUT_FILE"
format: markdown # optional; tells Atmos to render the output file as markdown
on_failure: warn # warn | fail | ignore

The subprocess receives these environment variables:

ATMOS_COMPONENT_PATH
On-disk path to the component's Terraform module (honors workdir resolution).
ATMOS_PLANFILE
Planfile path on after-plan events (when threaded — currently a stub).
ATMOS_OUTPUT_DIR
A fresh temp directory created by Atmos before the subprocess starts (via os.MkdirTemp("", "atmos-hook-*")). Unique per hook invocation — two hooks firing on the same event get separate directories and do not share state through these env vars. The directory and everything inside it is deleted automatically when the hook returns. Use this for tools that write to a directory rather than a single file (e.g., KICS, Checkov).
ATMOS_OUTPUT_FILE
$ATMOS_OUTPUT_DIR/output. Write structured output here for the kind's result handler to read. Same lifetime as ATMOS_OUTPUT_DIR.
ATMOS_STACK
The stack name.
ATMOS_COMPONENT
The component name.

Atmos creates a fresh temp directory per hook invocation, points ATMOS_OUTPUT_DIR and ATMOS_OUTPUT_FILE at it, and deletes the entire directory after the hook returns. Custom commands can write any additional files they need into $ATMOS_OUTPUT_DIR — sibling hooks won't collide, and cleanup is automatic.

Tool stdout/stderr stream through Atmos's I/O layer so you see them in real time — same UX as Terraform plan output.

kind: step (run a step type)

Runs any registered workflow / custom-command step typecontainer, toast, log, markdown, http, and the rest — on a lifecycle event. Instead of growing the hook-kind list one tool at a time, kind: step makes the whole step library available as hooks, so a step you already use in a workflow runs identically as a hook.

hooks:
notify-slack:
kind: step
type: http # any registered step type
events: [after.terraform.apply]
on_failure: warn # envelope policy: warn | fail | ignore
retry: # envelope policy: same schema as a workflow step's retry
max_attempts: 3
with: # the step's own parameters
url: https://hooks.slack.com/services/XXX
method: POST
body: '{"text": "Deployed {{ .atmos_component }} to {{ .stack }}"}'
The http step ships separately

The Slack example above needs the http step type. If your Atmos build doesn't have it yet, use a step type that is registered (e.g. container, toast, log, markdown) — the bridge itself works with every registered step type.

The split between the envelope and with: is deliberate:

  • The envelope (kind, type, events, on_failure, retry, env) is what the hook runner interprets.
  • with: is what the step interprets — it is the step's own parameter block, exactly as you'd write it in a workflow.

on_failure and retry sit at the envelope because Atmos applies them around the step (retry the whole step, then decide warn/fail/ignore) — the step never sees them.

# Build and push an image after apply, retried, non-blocking.
hooks:
publish-image:
kind: step
type: container
events: [after.terraform.apply]
on_failure: warn
with:
action: build
image: example:latest
build:
context: .
tags: [example:latest]
type
The step type to run — any registered workflow/custom-command step type. A typo fails the preflight check before Terraform runs.
with
The step's parameters. These are rendered with the standard hook template context and YAML functions (so {{ .atmos_component }} and !store ... work inside with:), then handed to the step. The step's own validation is the gate — the schema keeps with: open.
when (default success)
Declarative condition controlling whether this hook runs. See Reacting to success or failure.
retry
Optional. Wraps the step execution in Atmos's retry policy — same schema as a workflow step's retry. Applied by the hook runner, not the step.
env
Extra environment variables layered on top of the standard ATMOS_* variables (ATMOS_STACK, ATMOS_COMPONENT, ATMOS_COMPONENT_PATH, …) the step receives.
on_failure (default warn)
warn | fail | ignore, applied to the step's own outcome (not the terraform operation's). Use when: to react to the operation outcome.

All step types are available, including interactive ones — Atmos does not restrict them. Whether an interactive step makes sense on a (usually headless / CI) lifecycle event is the step's responsibility, not the hook's.

Reacting to success or failure

By default an after-* hook runs only when the operation succeeds — a store hook must not write outputs after a failed apply. Set when: to change that. Hooks support the same declarative predicates as workflow and custom command steps, plus the hook-specific lifecycle status predicates:

when: success (default)
Run only when the operation succeeded.
when: failure
Run only when the operation failed.
when: always
Run on both outcomes.
when: ci
Run in CI after a successful operation. Hooks apply success implicitly when the condition does not mention success, failure, or always.
when: [ci, always]
Run in CI after both successful and failed operations.

Built-in predicates are ci, local, always, never, success, and failure. Compose them with list shorthand, all, any, and not:

hooks:
ci-summary:
kind: command
events: [after.terraform.plan]
command: ./scripts/write-ci-summary.sh
when: [ci, always]

local-cleanup:
kind: command
events: [after.terraform.apply]
command: ./scripts/cleanup.sh
when:
all:
- local
- failure

skip-in-ci:
kind: command
events: [after.terraform.plan]
command: ./scripts/local-report.sh
when:
not: ci

Condition filtering also applies during hook preflight. For example, when: ci hooks are skipped outside CI before Atmos validates or installs the hook's tools.

The outcome is available to the step both as template context and as environment variables, alongside the component and stack — so a hook can announce exactly what happened:

hooks:
announce:
kind: step
type: say
events: [after.terraform.apply]
when: always
with:
print: always
content: >-
The {{ .atmos_component }} component in the {{ .stack }} stack
{{ if eq .status "failure" }}was not successful{{ else }}was successful{{ end }}
{{ .status }}
success or failure. Also ATMOS_HOOK_STATUS.
{{ .exit_code }}
The operation's exit code (0 on success). Also ATMOS_HOOK_EXIT_CODE.
{{ .error }}
The error message on failure, empty on success. Also ATMOS_HOOK_ERROR.
{{ .atmos_component }} / {{ .stack }}
The component and stack (already part of the hook template context). Also ATMOS_COMPONENT / ATMOS_STACK.

Steps that read the environment instead of templates (e.g. a shell or say step) get the same values via ATMOS_HOOK_STATUS, ATMOS_HOOK_EXIT_CODE, ATMOS_HOOK_ERROR, ATMOS_COMPONENT, and ATMOS_STACK.

Outcome reaches all hook kinds

when: and the ATMOS_HOOK_* variables apply to every hook kind, not just kind: step — e.g. a kind: command cleanup hook with when: failure. The outcome is only meaningful on after-* events; before-* events always run as success.

Overriding Kind Defaults

Every named kind (infracost, trivy, checkov, kics, store) ships defaults for command, args, env, and on_failure. Any field you set on the hook overrides the kind's default for that field.

Override is replace, not merge

args and env are full replacement — if you set args on the hook, the kind's default arg list is discarded entirely (you must restate every arg you want). Same for env. If you only need to tweak one flag, use kind: command directly and pass the full command line.

A common case is bumping a scanner's severity threshold or adding a config file. Because override replaces the entire arg list, copy the default args from the kind's reference section above and add your overrides:

hooks:
security:
events: [after.terraform.plan]
kind: trivy
args:
- config
- --format
- sarif
- --output
- $ATMOS_OUTPUT_FILE
- --severity
- HIGH,CRITICAL # added
- --quiet
- $ATMOS_COMPONENT_PATH

You can also override just on_failure (independent of args/env) to make a scanner finding block the run:

hooks:
security:
events: [after.terraform.plan]
kind: trivy
on_failure: fail # default is warn

Or override env to inject a tool-specific config path:

hooks:
policy:
events: [after.terraform.plan]
kind: checkov
env:
CHECKOV_CONFIG_FILE: $ATMOS_COMPONENT_PATH/.checkov.yaml

Setting env on the hook replaces the kind's DefaultEnv map entirely. For kind: checkov specifically, that means losing the default SSL_CERT_FILE workaround (see kind: checkov) — restate it if you still need it.

Tool Auto-Install via dependencies.tools

Declare which tools a hook needs and Atmos installs them automatically through the toolchain before the hook fires. Same syntax used by component dependencies:

components:
terraform:
vpc:
dependencies:
tools:
infracost: "0.10.44"
checkov: "3.2.529"
hooks:
cost: { events: [after.terraform.plan], kind: infracost }
security: { events: [after.terraform.plan], kind: checkov }

A pre-flight check runs once per command invocation:

  1. Resolve every tool the component declares.
  2. Install any that aren't already present.
  3. Build a PATH augmentation that points at the installed pinned versions.
  4. Verify each hook's binary is resolvable.

If any binary is missing, the run aborts before Terraform with a clear error including a hint to declare it in dependencies.tools. You won't lose a 90-second plan to find out a hook is misconfigured.

Pin a concrete version ("3.2.529") or use a SemVer constraint ("~> 3.2"). "latest" is accepted but the resulting PATH may not match what the toolchain installed — pin a version for reliable behavior.

Curated Atmos Registry

Atmos ships a small curated registry baked into the binary that overrides upstream Aqua registry entries for tools that don't model cleanly with Aqua's defaults. Today this covers KICS (the upstream entry uses type: go_build which the Atmos installer doesn't support yet). The override is invisible to users — you just write kics: "2.1.20" in dependencies.tools and it works.

You can override even the built-in overrides with your own registry entry at higher priority — see Toolchain Configuration for the registry syntax.

Skipping Hooks at Runtime

Set --skip-hooks (or the ATMOS_SKIP_HOOKS environment variable) to bypass hooks for a single invocation without editing stack config. Useful for emergency operations, local iteration, or when a scanner is producing noisy false positives you want to ignore for one run.

atmos terraform plan vpc -s prod --skip-hooks                  # skip all
atmos terraform plan vpc -s prod --skip-hooks=cost,security # skip specific hooks by name
ATMOS_SKIP_HOOKS=true atmos terraform apply vpc -s prod # via env var

Skipped hooks are logged at INFO level so it stays visible in CI output. The flag is per-invocation only — it doesn't propagate to nested commands or workflows. Because hooks only run on terraform operations, --skip-hooks is a flag of the atmos terraform command and all its subcommands (plan, apply, deploy, …).

Hooks with --all

atmos terraform plan --all / atmos terraform apply --all walks every terraform component in the selected stack(s) in dependency order and runs the command for each. Hooks fire just like a single-component invocation, with these specifics:

  • Hooks fire per component, in dependency order. destroy --all reverses the order so dependents tear down before their dependencies.
  • Tool auto-install runs per component. Each component's dependencies.tools is resolved on its own, so different components in the same --all run can pin different versions of the same tool — the toolchain PATH is rebuilt per component.
  • --skip-hooks propagates across the whole run. The flag is set on the shared invocation state and applies uniformly to every component --all visits.
  • on_failure: fail aborts the remaining traversal. A failing hook on component K stops --all before it visits any downstream node. Components already processed stay processed — there is no rollback.

Failure Modes

Every hook can declare an on_failure mode:

warn (default)
Log a warning if the hook fails, continue. Built-in scanner kinds default to warn so a security or cost issue doesn't block your plan unless you explicitly want it to.
fail
Propagate the subprocess error — the terraform command aborts. Use when a hook finding should block the operation (e.g., critical security violations).
ignore
Silently swallow failures. Useful for opportunistic notifications you don't want to ever break a run.
on_failure vs when

These answer different questions. on_failure controls what happens when the hook itself fails. when (success | failure | always) controls whether the hook runs based on the terraform operation's outcome — see Reacting to success or failure.

Format Symmetry

When a hook's kind produces a markdown summary (every built-in kind does), Atmos renders the same bytes in:

  • Your terminal (via ui.MarkdownMessage)
  • The GitHub Actions job step summary
  • The Atmos Pro run page (when Pro is connected)

No separate "terminal-friendly" vs "Pro-friendly" variants — write markdown once, get it everywhere.

CI Reporting

When running in CI (GitHub Actions), Atmos can surface scanner-hook findings in the pipeline itself instead of leaving them buried in the terraform plan log. Three independent outputs are available, all under ci: and all gated by the ci.enabled master switch:

ci:
enabled: true # required for any CI reporting to fire
summary: true # markdown report in the job step summary (default: on)
annotations: true # inline ::error/::warning on the PR diff (default: on)
results: true # upload SARIF to GitHub Code Scanning (default: off)
ci.summary
Appends each hook's markdown summary to the GitHub Actions job step summary. Default on.
ci.annotations
Renders each finding as an inline GitHub annotation (::error/::warning) anchored at its file and line on the pull request diff. This is the non-Code-Scanning path — it needs no GitHub Advanced Security. Default on.
ci.results
Uploads the raw SARIF to GitHub Code Scanning (the Security tab) as tracked alerts. Code Scanning is free on public repositories; on private/internal repositories it requires GitHub Advanced Security — a paid add-on that GitHub licenses per active committer. Default off (opt-in). The analysis category is derived automatically from the scan target (atmos/&lt;component&gt; for shared component source, atmos/&lt;stack&gt;/&lt;component&gt; for a per-stack workdir) so per-component uploads don't overwrite each other.

All three are best-effort: a reporting failure logs at debug and never fails the hook or the terraform command. Outside CI they no-op. Findings derive from the tool's SARIF, so the three built-in SARIF scanners — checkov, trivy, kics — all participate; infracost (cost, not findings) does not.

ci.annotations and ci.results can both place line-level feedback on a pull request. Enable both when you intentionally want the lightweight Actions annotation and the tracked Code Scanning alert; otherwise enable only one of them to avoid duplicate comments on the same lines.

Required GitHub Actions permissions

permissions:
contents: read
security-events: write # ONLY required for ci.results (SARIF upload)

ci.summary and ci.annotations need no special permissions and no paid add-on — the step summary is a file write and annotations are log output, so they work on any repository. ci.results uploads to Code Scanning, which requires the security-events: write permission and — on private/internal repositoriesGitHub Advanced Security, which GitHub licenses as a paid add-on per active committer (Code Scanning is free on public repositories). Note: pull requests from forks do not receive security-events: write on the default token, so ci.results is skipped there.

Custom hooks

A custom kind: command hook gets the same reporting as the built-in scanners by declaring format: sarif — any SARIF-emitting tool (tfsec, semgrep, gitleaks, snyk, …) then flows to the summary, annotations, and Code Scanning with no extra code:

hooks:
tfsec:
events: [after.terraform.plan]
kind: command
command: tfsec
args: ["--format", "sarif", "--out", "$ATMOS_OUTPUT_FILE", "$ATMOS_COMPONENT_PATH"]
format: sarif # parse output as SARIF
# results: results.sarif # optional: read SARIF from this file in $ATMOS_OUTPUT_DIR

The report is labeled by the SARIF's own tool name (e.g. "tfsec").

Backwards Compatibility

The pre-rename command: YAML key is still accepted as an alias for kind:. Existing stack manifests like:

hooks:
vpc-id:
events: [after.terraform.apply]
command: store # legacy form — still works
name: vpc/id
outputs:
id: .vpc_id

…parse identically post-upgrade. No migration required.

Hyphenated lifecycle events such as after-terraform-apply are also still accepted. New documentation and examples use the canonical dotted form (after.terraform.apply).

Store Function Reference

For complete details on the store kind (configuring stores, supported backends, output mapping, etc.), see Sharing State with Stores.

hooks.<name>
Map key is the hook's name (unique per component).
hooks.<name>.events
List of lifecycle events that trigger this hook.
hooks.<name>.kind
Which engine runs the hook. One of store, command, git, step, infracost, checkov, trivy, kics. Aliased from legacy command: field.
hooks.<name>.type
For kind: step: the step type to run (e.g. container, http, toast, log).
hooks.<name>.with
For kind: step: the step's own parameters. Rendered with the hook template context and YAML functions, then validated by the step at run time.
hooks.<name>.retry
For kind: step: retry policy wrapping the step execution. Same schema as a workflow step's retry.
hooks.<name>.command
For kind: command: the binary to execute (resolved via the toolchain or PATH). Named kinds default this.
hooks.<name>.args
For kind: command: arguments passed to the binary. Supports Go template syntax ({{ .atmos_component }}) for stack metadata and $ATMOS_* env-var substitution at exec time.
hooks.<name>.env
Additional env vars exported to the subprocess. Supports the same templating as args.
hooks.<name>.format
Optional rendering hint. v1 supports markdown — tells Atmos to render the tool's output file as markdown in the terminal.
hooks.<name>.on_failure
warn (default), fail, or ignore. Applies to the hook's own outcome, not the terraform operation's.
hooks.<name>.when
Declarative condition controlling whether the hook runs. Omitted means success; if the condition does not mention success, failure, or always, Atmos applies success implicitly. See Reacting to success or failure.
hooks.<name>.name / hooks.<name>.outputs
Store-kind specific. See store function reference.
hooks.<name>.repository
For kind: git: the name of a managed repository under the top-level git.repositories config. Omit to target the current repository.
hooks.<name>.commit.message
For kind: git: the commit message. Supports the standard hook template context. Empty selects the engine default (Update artifacts for <component> in <stack>).
hooks.<name>.commit.paths
For kind: git: repo-relative paths staged for the commit. Paths must resolve inside the repository worktree.
hooks.<name>.push
For kind: git: push the created commit to the remote when true (only when a commit was actually created).

Examples

Five working examples live in the Examples gallery:

Each uses dummy AWS provider config so tofu plan succeeds offline.