Skip to main content

Configure Hooks

Hooks run an automated action at a specific point in a component's lifecycle — after a terraform plan, after an apply, and so on. Atmos ships built-in kinds for the jobs teams reach for most (security scanning, cost estimates, publishing outputs) plus a generic command kind for anything else.

By the end of this step, every plan will be security-scanned, and every apply will publish its component's outputs to a store.

How a hook works

A hook binds a kind (the action) to one or more events (when it runs):

hooks:
<name>:
events: [after-terraform-plan] # when to run
kind: trivy # what to run

Common events are after-terraform-plan and after-terraform-apply. The built-in kinds cover the usual cases — no wiring required:

checkov, trivy, kics
Security and policy scanners. The tool auto-installs through the toolchain, and findings render in your terminal (and on Atmos Pro).
infracost
Cost estimate of the planned change.
store
Publishes selected component outputs to a store so other components can read them by name.
command
Runs any binary — your escape hatch for anything the named kinds don't cover.

Scan every plan

The most common hook is a scanner that runs after each plan. Declare it once in your org defaults and it applies to every component:

terraform:
hooks:
security:
events:
- after-terraform-plan
kind: checkov # or: trivy, kics

Because checkov is declared in dependencies.tools, the toolchain installs it the first time the hook fires — you don't install or wire up anything.

Publish outputs on apply

Hooks also publish component coordinates for operators and downstream consumers: the store kind writes selected outputs after a component applies, so another component or tool can read them with !store without reaching into Terraform state.

First, add the store to your atmos.yaml. The config/ssm store uses AWS SSM Parameter Store (running in your sandbox via the local-aws identity) for non-secret service discovery:

stores:
config/ssm:
kind: aws/ssm
identity: local-aws
options:
region: us-east-1
prefix: /atmos/quickstart/config

Then add a store hook to a component. Here s3-bucket publishes its bucket_id after every apply:

components:
terraform:
s3-bucket:
hooks:
publish-coordinates:
events:
- after-terraform-apply # run automatically after every apply
kind: store
name: config/ssm # the store to write to
outputs:
bucket_id: .bucket_id # store key: Terraform output

Use the published value

A downstream component can read it by name with !store <store> <component> <key>. In this quick start, app-config uses stack-derived coordinates so the first terraform deploy --all can build the graph before any store values exist. In a larger stack, the same published coordinates can be consumed like this:

# stacks/catalog/app-config/defaults.yaml
vars:
bucket_id: !store config/ssm s3-bucket bucket_id
topic_arn: !store config/ssm sns-topic topic_arn
queue_url: !store config/ssm sqs-queue queue_url
Notice how nothing in your Terraform changed

Scanning, cost analysis, and output publishing are all attached at the stack level, on lifecycle events — your component code stays plain Terraform. Publishing via a store is just one kind; reach for !terraform.state when a consumer can read a producer's already-created state directly. See Hooks for the full list of kinds and events.


Next: stores hold secrets too — keep them off disk → Manage Secrets →