Skip to main content

atmos terraform plan

Use this command to generate a Terraform execution plan for an Atmos component in a stack, showing what changes would be made to your infrastructure.

atmos terraform plan
 
00:00.0 / 00:00.0
atmos terraform plan --help
 

Usage​

Execute the terraform plan command like this:

atmos terraform plan <component> -s <stack> [options]

This command generates an execution plan that shows:

  • Resources that will be created, modified, or destroyed
  • Changes to resource attributes
  • Data source reads that will be performed

By default, Atmos saves the plan to a file using a standardized naming convention: <context>-<component>.planfile. This planfile can later be used with atmos terraform apply --from-plan to ensure that only the reviewed changes are applied.

tip

Run atmos terraform plan --help=all to see shared selector and dependency flags.

Examples​

Basic Planning​

Generate a plan for the vpc component in the dev stack:

atmos terraform plan vpc -s dev

Custom Planfile Output​

Save the plan to a specific file using the -out flag (native Terraform flag):

atmos terraform plan vpc -s dev -out=my-custom.planfile

Skip Planfile Generation​

When using Terraform Cloud (which doesn't support the -out flag), skip planfile generation:

atmos terraform plan vpc -s dev --skip-planfile

Planning with Variable Overrides​

Pass additional variables to the plan:

atmos terraform plan vpc -s dev -var="instance_type=t3.large"

Targeted Planning​

Plan changes only for specific resources:

atmos terraform plan vpc -s dev -target=aws_subnet.private

Destroy Planning​

Generate a plan to destroy infrastructure:

atmos terraform plan vpc -s dev -destroy

Graph-backed Multi-component Planning​

Run plans for multiple components through the Terraform dependency graph:

# Plan every Terraform component in dependency order
atmos terraform plan --all -s dev

# Plan a named subset, preserving dependency edges between selected components
atmos terraform plan --components vpc,eks/cluster,eks/apps -s dev

# Plan components selected by query
atmos terraform plan --query '.settings.tier == "network"' -s dev

The graph is built from dependencies.components first, with settings.depends_on as a fallback. Components that are independent at the same point in the graph can run concurrently when --max-concurrency is greater than 1.

atmos terraform plan --all -s dev --max-concurrency 4

Concurrent plan output is isolated per component. Use --log-order grouped to print each component's logs together after it finishes, or keep the default stream mode to see logs as they arrive. To reduce noise from unchanged components, use --hide=no-changes.

atmos terraform plan --all -s dev \
--max-concurrency 4 \
--failure-mode keep-going \
--log-order grouped \
--hide=no-changes \
--execution-summary-file /tmp/atmos-plan-summary.json

GitHub Actions CI Output​

When CI mode is enabled with --ci, ci.enabled: true, or GitHub Actions auto-detection, graph-backed multi-component plan runs write a single aggregate CI result after the scheduler finishes. This applies to --all, --components, and --query plan runs. Single-component plan, apply, and deploy keep their existing per-command CI output.

In GitHub Actions, the aggregate result writes once to $GITHUB_STEP_SUMMARY and $GITHUB_OUTPUT. The job summary includes component counts, total resource counts, failed/changed/no-change/skipped groups, a per-component table, and details for failed or changed components. Output variables include has_changes, has_errors, exit_code, resource totals, component totals, summary, command, stack, and component.

Aggregate exit codes follow Terraform plan semantics across the whole graph:

Exit CodeMeaning
1At least one component failed
2No failures, but at least one component has changes
0No failures and no changes

Planfile Management​

Default Behavior​

When you run atmos terraform plan, Atmos automatically:

  1. Generates a planfile with the naming pattern:

    • Without folder prefix: <context>-<component>.planfile
    • With folder prefix: <context>-<folder_prefix>-<component>.planfile
  2. Saves the planfile in the component's working directory

  3. The planfile can be used later with:

    atmos terraform apply <component> -s <stack> --from-plan

Custom Planfile Locations​

You can specify a custom planfile location using the standard Terraform -out flag:

# Absolute path
atmos terraform plan vpc -s dev -out=/tmp/my-plan.tfplan

# Relative path (relative to component directory)
atmos terraform plan vpc -s dev -out=plans/vpc.tfplan

Skipping Planfile Generation​

To run a plan without generating a planfile (useful for quick checks or when using Terraform Cloud):

atmos terraform plan vpc -s dev --skip-planfile

You can also configure this globally in atmos.yaml:

components:
terraform:
plan:
skip_planfile: true

Arguments​

component (required)

Atmos component name to plan.

Flags​

--use-mocks (optional)
Resolve Terraform YAML lookups from the producer’s literal component mocks instead of its remote state. Default: false. Requires YAML function processing to remain enabled.
--stack / -s (required)

Atmos stack name where the component is defined.

--skip-planfile (optional)

Skip writing the plan to a file. When set, Atmos will not pass the -out flag to Terraform.

This is useful when:

  • Using Terraform Cloud (which doesn't support -out)
  • Running quick plan checks without saving the output
  • Running in CI/CD environments where planfiles aren't needed
atmos terraform plan vpc -s dev --skip-planfile
--affected (optional)

Plan only affected components based on changes in the repository. This is a global operation that identifies and plans all components affected by recent changes across all stacks.

# Plan only affected components across all stacks
atmos terraform plan --affected
--all (optional)

Plan all components in all stacks (use with caution).

atmos terraform plan --all
--dry-run (optional)

Show what would be executed without actually running the plan.

atmos terraform plan vpc -s dev --dry-run
--skip-init (optional)

Skip running terraform init before planning.

atmos terraform plan vpc -s dev --skip-init
--init-mode (optional)

Override init.mode for this invocation: auto (default, skip init when nothing relevant changed), always, or never (disables the ordinary implicit init, but unlike --skip-init does not suppress the forced reconfigure init that atmos terraform workspace select/new needs).

atmos terraform plan vpc -s dev --init-mode=always
--init-reconfigure (optional)

Override init.reconfigure for this invocation: auto (default), always, or never.

atmos terraform plan vpc -s dev --init-reconfigure=always
--init-upgrade (optional)

Override init.upgrade for this invocation: auto (default), always, or never.

atmos terraform plan vpc -s dev --init-upgrade=always
--process-templates (optional)

Enable/disable Go template processing in Atmos stack manifests.

Default: true

atmos terraform plan vpc -s dev --process-templates=false
--ui (optional)

Enable streaming UI mode for real-time resource status display. Shows a Docker-build-style progress view with spinners, progress bar, and resource states.

The UI automatically disables when output is piped, in CI environments, or when running unsupported commands.

--ui errors when combined with --max-concurrency greater than 1, since concurrently-scheduled components can't share one terminal for their full-screen UI sessions. Use --max-concurrency 1 (the default) with --ui, or drop --ui to run concurrently.

atmos terraform plan vpc -s dev --ui

Use --ui=false to explicitly disable when enabled by config.

--ci (optional)

Enable CI mode for automated pipelines. When enabled, Atmos writes job summaries, CI output variables, and status checks based on the ci configuration in atmos.yaml.

CI mode is auto-detected when CI=true or GITHUB_ACTIONS=true environment variables are set. Use this flag to explicitly enable CI mode in environments where auto-detection is not available.

Environment variables: ATMOS_CI, CI

atmos terraform plan vpc -s dev --ci

Native Terraform Flags​

The atmos terraform plan command supports all native terraform plan flags. To pass native Terraform flags, you have two options:

  1. Direct flags - Pass Terraform flags directly if they don't conflict with Atmos flags
  2. Double-dash separator - Use -- to explicitly separate Atmos flags from Terraform flags
Using the Double-Dash Separator

The -- separator is a common Unix convention that indicates "end of options". Everything after -- is passed directly to Terraform without interpretation by Atmos. This is useful when:

  • You want to ensure a flag is passed to Terraform, not Atmos
  • You're using flags that might conflict with Atmos flags
  • You want to be explicit about which tool receives which flags

Example:

atmos terraform plan vpc -s dev -- -refresh=false -out=my-custom.tfplan

Some commonly used native flags include:

-out=FILE

Write the plan to a file at the specified path. This is the standard Terraform flag for specifying a custom planfile location.

atmos terraform plan vpc -s dev -out=my-plan.tfplan
-destroy

Create a plan to destroy all resources.

atmos terraform plan vpc -s dev -destroy
-target=RESOURCE

Plan only specific resources. Can be specified multiple times.

atmos terraform plan vpc -s dev -target=aws_subnet.private -target=aws_route_table.private
-var 'NAME=VALUE'

Set a variable value. Can be specified multiple times.

atmos terraform plan vpc -s dev -var="instance_count=3" -var="environment=staging"
-refresh-only

Create a plan to update the state to match remote systems.

atmos terraform plan vpc -s dev -refresh-only

Default Locking and Concurrency Flags​

Instead of retyping flags like -lock-timeout on every invocation, declare a default in components.terraform.flags — globally in atmos.yaml, per stack, or per component. plan supports all five flags (lock_timeout, lock, parallelism, refresh, compact_warnings); a native flag typed directly on the command line (as shown above) always wins over a declared default.

Multi-Component Operations​

Execute terraform plan across multiple components using filtering flags. All flags can be combined with --dry-run to preview what would be executed.

Plan All Components​

# Plan all components in all stacks
atmos terraform plan --all

# Plan all components in a specific stack
atmos terraform plan --all --stack prod
atmos terraform plan --stack prod

Plan Affected Components​

Plan only components affected by changes in the current branch (requires git):

# Plan affected components in all stacks
atmos terraform plan --affected

# Plan affected components in a specific stack
atmos terraform plan --affected --stack prod

# Include dependent components (components that depend on affected components)
atmos terraform plan --affected --include-dependents

# Clone the target reference instead of checking it out
atmos terraform plan --affected --clone-target-ref=true

Plan Specific Components​

# Plan specific components in all stacks
atmos terraform plan --components vpc,eks

# Plan specific components in a specific stack
atmos terraform plan --components vpc,eks --stack prod

Plan Components by Query​

Filter components using YQ expressions against component configuration:

# Plan components where team tag equals "eks"
atmos terraform plan --query '.vars.tags.team == "eks"'

# Plan components in a specific account
atmos terraform plan --query '.settings.context.account_id == 12345'

# Combine with stack filter
atmos terraform plan --query '.vars.tags.team == "eks"' --stack prod

Plan Components by Tags and Labels​

Filter components by metadata.tags/metadata.labels. These flags compose with --all/--affected/--components/--query to narrow the selected set further, rather than being mutually exclusive with them:

# Plan components tagged production or tier-1 (matches any)
atmos terraform plan --tags production,tier-1

# Plan components labeled cost-center=platform (matches all given labels)
atmos terraform plan --labels cost-center=platform

# Narrow an --affected run to only production-tagged components
atmos terraform plan --affected --tags production

Include Dependencies and Dependents​

Selector flags choose the seed set; --include-dependencies and --include-dependents expand it through the dependency graph. Expanded components are planned even when they do not match the selectors — they are prerequisites (or dependents) of what was selected. Prerequisites can live in other stacks, so --include-dependencies with -s dev legitimately plans prerequisite components outside the dev stack:

# Plan dev-labeled components plus everything they depend on
atmos terraform plan --labels=env=dev --include-dependencies

# Bound the expansion to direct dependencies only
atmos terraform plan --labels=env=dev --include-dependencies=1

# Plan a stack plus everything that depends on it, up to two levels out
atmos terraform plan -s dev --include-dependents=2

Pass the depth with = (for example, --include-dependencies=2); a space-separated value is not bound to the flag. The bare flag expands without a depth limit, and true/false values are accepted for backward compatibility.

Multi-Component Flags​

--all
Plan all components in all stacks (or specified stack with --stack).
--affected
Plan components affected by git changes in dependency order. Supports all flags from atmos describe affected.
--components
Plan specific components by name (comma-separated or repeated flag).
--query
Plan components matching a YQ expression. All Atmos sections are available: vars, settings, env, metadata, etc.
--tags
Filter by tags (comma-separated, matches any): --tags=production,tier-1. Composes with --all/--affected/--components/--query to narrow the selected set further; cannot be combined with a single component argument.
--labels
Filter by labels (comma-separated key=value or key:value pairs, matches all): --labels=cost-center=platform,compliance=sox. Composes with --all/--affected/--components/--query/--tags; cannot be combined with a single component argument.
--include-dependencies
Also plan everything the selected components depend on (their prerequisites), in dependency order — even when the prerequisites live in other stacks or do not match the selectors. Accepts an optional depth: the bare flag expands the full dependency chain, while --include-dependencies=1 bounds it to direct dependencies. Requires a multi-component selection.
Environment variable: ATMOS_INCLUDE_DEPENDENCIES
--include-dependents
Also plan everything that depends on the selected components, in dependency order. Works with any multi-component selection (--all, --components, --query, --stack, --tags, --labels, --affected). Accepts an optional depth: the bare flag expands the full dependent chain, while --include-dependents=2 bounds it to two levels.
Environment variable: ATMOS_INCLUDE_DEPENDENTS
--ref
Git reference to compare against (branch or tag). Default: refs/remotes/origin/HEAD.
--sha
Git commit SHA to compare against.
--clone-target-ref
Clone the target reference instead of checking it out locally.

CI Integration​

Experimental

When running in CI mode (--ci flag or auto-detected), Atmos produces rich CI artifacts:

  • Job summaries with resource badges, collapsible diffs, and warnings written to $GITHUB_STEP_SUMMARY
  • Output variables (has_changes, has_errors, exit_code, etc.) written to $GITHUB_OUTPUT
  • Status checks showing plan progress and results (requires ci.checks.enabled: true)
  • PR plan-summary comments when ci.comments.enabled: true, the run is for a pull request, and the workflow grants pull-requests: write; comments reuse the job-summary template and are updated by default on later runs for the same command, component, and stack
# In GitHub Actions (auto-detected)
atmos terraform plan vpc -s dev

# Explicit CI mode
atmos terraform plan vpc -s dev --ci
info

See CI Configuration for full configuration options including custom templates, status checks, and output variables. See CI Pull Request Comments to opt into plan-summary comments.

Configuration​

Configure default behavior for terraform plan in your atmos.yaml:

components:
terraform:
plan:
# Skip generating planfiles by default (useful for Terraform Cloud)
skip_planfile: false

This can also be set using the environment variable:

export ATMOS_COMPONENTS_TERRAFORM_PLAN_SKIP_PLANFILE=true
info

See Terraform Planfiles for a comprehensive guide on working with planfiles in Atmos.