Skip to main content

Component Output Mocks

Declare literal outputs on a component and opt into using them for !terraform.state and !terraform.output lookups during local plans or configuration inspection. By default, mocks are fallbacks: a real value wins when it exists, and the mock fills in only when it doesn't.

Usage​

Declare mocks on the component that produces the outputs:

stacks/dev.yaml
components:
terraform:
vpc:
mocks:
vpc_id: vpc-local
private_subnet_ids: [subnet-a, subnet-b]
app:
vars:
vpc_id: !terraform.state vpc vpc_id
first_subnet: !terraform.output vpc '.private_subnet_ids[0]'

Enable mock lookups explicitly:

atmos describe component app -s dev --use-mocks
atmos terraform plan app -s dev --use-mocks

When vpc has not been provisioned, the lookups return vpc-local and subnet-a. After atmos terraform apply vpc -s dev, the same commands return the real vpc_id and subnet from state. To always use the mocks, even when state exists, pass --use-mocks=always.

Attach the mode with an equals sign

A bare --use-mocks takes no value, so --use-mocks always leaves always behind as a positional argument and does not select the mode. When the mode word follows the component, Atmos reports this with an error and a hint. Write --use-mocks=always.

Running the app's plan can still require its own provider credentials and infrastructure access.

Resolution modes​

The components.terraform.mocks.mode setting decides how --use-mocks treats real state. Configure it once in atmos.yaml:

atmos.yaml
components:
terraform:
mocks:
mode: fallback # fallback (default) | always

Fallback mode​

In fallback mode Atmos runs the real lookup first, including authentication and the backend read. It uses the component's mocks only when the lookup misses in a recoverable way: the referenced component's state is not provisioned, or the requested output is missing.

With the vpc example above:

SituationResult for !terraform.state vpc vpc_id
vpc applied, output vpc_id is vpc-0abcvpc-0abc (the mock is ignored)
vpc never appliedvpc-local (from mocks)
vpc applied, but it has no vpc_id outputvpc-local (from mocks)
vpc never applied, vpc declares no matching mockThe normal not-provisioned error for !terraform.state; null for !terraform.output, the same as without mocks
vpc applied, no vpc_id output, and no vpc_id mocknull, the same as without mocks
Backend returns an access-denied or network errorThe error. Mocks never hide it

When the real lookup for a component that declares mocks fails with an error that is not recoverable (credentials, network, backend, Terraform initialization, or a missing Terraform binary), the error includes a hint to use --use-mocks=always or components.terraform.mocks.mode: always for mocks-only resolution. Use always for lookups on machines that have no credentials or no Terraform installed, such as CI jobs that only inspect configuration with atmos describe component.

The precedence is: real value, then mock, then a YQ // default, then the original error. A // default in the expression is therefore the last resort, not a replacement for the mock:

vars:
vpc_id: !terraform.state vpc '.vpc_id // "vpc-default"'

Here the value is the real vpc_id when it exists, vpc-local when only the mock exists, and vpc-default when neither exists.

Map outputs are merged​

Mocks are deep-merged under the real outputs. Every value present in real state wins, and a mock fills only the keys that are missing from a real map output. Suppose the real config output is { a = 1 } and the mock is:

components:
terraform:
vpc:
mocks:
config: {a: 0, b: 2}

Then .config.a is the real 1, .config.b is 2 from the mock, and .config resolves to {a: 1, b: 2}.

Lists and scalars are never merged element by element. A real list replaces the mock list wholesale, and a real scalar replaces the mock scalar.

Outputs that are null in state

Terraform does not record outputs whose value is null in state. In fallback mode an output that is null in a provisioned component is therefore indistinguishable from a missing output, and it resolves to the mock. Don't declare a mock for an output that can legitimately be null, or use --use-mocks=always when that matters.

Always mode​

In always mode lookups resolve from mocks and nothing else. Atmos does not initialize Terraform, authenticate, read a backend, or use the state caches for those lookups, so the result is the same on every machine regardless of what has been deployed.

atmos describe component app -s dev --use-mocks=always

Use always when lookups must be hermetic, for example atmos describe component in CI jobs with no cloud credentials or without Terraform installed. A plan with --use-mocks=always still initializes and plans the component itself, so it needs Terraform and that component's own backend and provider access; only the lookups it makes are hermetic. In this mode a missing mocks map or an undeclared output is an error, because there is no real value to fall back to. A YQ // default still applies:

vars:
vpc_id: !terraform.state vpc '.vpc_id // "vpc-default"'

Edition default​

The default mode depends on the project's config edition. Unpinned projects, and projects pinned to an edition on or after 2026-10-01, use fallback. Projects pinned to an earlier edition use always, which is how bare --use-mocks behaved before the setting existed. Set components.terraform.mocks.mode explicitly to choose either mode regardless of the pin.

Configuration Reference​

mocks
A map of output names to literal values on the producer component. Templates and YAML functions inside the map are not evaluated. The map follows component inheritance and deep merging. Explicit null values are valid.
--use-mocks

Turns on mock lookups for atmos terraform plan and atmos describe component. Every other atmos terraform subcommand (for example apply, deploy, and destroy) rejects the flag. atmos terraform plan --all and --affected pass it through to each component. YAML function processing must remain enabled. Accepted values (matching is case-insensitive):

  • Absent, empty, or a false boolean (false, 0, f): mocks are off and lookups use real state and outputs.
  • Bare --use-mocks or a true boolean (true, 1, t): mocks are on, using the resolved components.terraform.mocks.mode.
  • fallback or always: mocks are on, overriding components.terraform.mocks.mode for this run.

Any other value is an error. Attach the value with =, as in --use-mocks=always; a bare --use-mocks takes no value, so --use-mocks always leaves always as a positional argument and Atmos reports it as an error with a hint.

Default: off

ATMOS_USE_MOCKS

Environment equivalent of --use-mocks, with the same accepted values. Only atmos terraform plan reads it; atmos describe component ignores it, so pass --use-mocks there. If ATMOS_USE_MOCKS is exported in a shell or CI environment, every atmos terraform subcommand other than plan (for example apply, deploy, and destroy) fails with an error that names the variable. Unset it before running those commands.

components.terraform.mocks.mode

Either fallback or always, as described in Resolution modes. The value in atmos.yaml is case-insensitive (Always works). An invalid value, whether in atmos.yaml or in ATMOS_COMPONENTS_TERRAFORM_MOCKS_MODE, fails at configuration load for every command, not only when a --use-mocks lookup runs. The default is fallback for unpinned projects and projects pinned to a config edition on or after 2026-10-01, and always for projects pinned to an earlier edition. The effective value resolves in this order (highest wins): the --use-mocks=<mode> flag, the ATMOS_COMPONENTS_TERRAFORM_MOCKS_MODE environment variable, atmos.yaml, then the edition-aware default. See the Terraform configuration reference for the full field entry.

Limits​

Without --use-mocks, lookups use their normal state and output source. This feature does not simulate providers or provision resources. See the component mocks example for a producer and consumer configuration.