Skip to main content

The atmos terraform plan-diff command compares two Terraform plans and shows the differences between them.

atmos terraform plan-diff --help
 

terraform plan-diff

The atmos terraform plan-diff command compares two Terraform plans and shows the differences between them.

It takes an original plan file (--orig) and optionally a new plan file (--new). If the new plan file is not provided, it will generate one by running terraform plan with the current configuration.

The command shows differences in variables, resources, and outputs between the two plans.

info

Data sources are automatically skipped during comparison and will not appear in the diff.

Usage​

atmos terraform plan-diff <component> -s <stack> --orig=<original-plan-file> [--new=<new-plan-file>] [options]

Arguments​

component (required)
The name of the component to run the command against.

Flags​

-s / --stack (required)
The stack name to use.
--orig (required)
Path to the original Terraform plan file.
--new (optional)
Path to the new Terraform plan file.
--skip-init (optional)
Skip running terraform init before executing the command.

You can also pass any additional flags and arguments that are supported by the terraform plan command when generating a new plan.

Ignoring attribute changes​

Configure components.terraform.plan_diff.ignore_changes in atmos.yaml to exclude resource attributes that are expected to vary between plans. These exclusions apply to both atmos terraform plan-diff and plan verification during atmos terraform deploy.

For example, an RDS instance's computed latest_restorable_time can change between plans even when its configuration has not changed:

atmos.yaml
components:
terraform:
plan_diff:
ignore_changes:
- aws_db_instance.latest_restorable_time

Each entry must be an exact resource_type.attribute name. The rule applies to every instance of that resource type, including instances inside modules. Only top-level attributes are supported; bare attribute names, wildcards, resource addresses, and nested attribute paths are invalid. Malformed entries cause a configuration error before Terraform runs. When an entry is well formed but matches no attribute on the resources of that type present in the plans, which usually means a resource address or a typo was configured, Atmos prints a warning and leaves the comparison unchanged. Values that become known only after apply are shown as (known after apply) rather than as removed or added attributes.

No resource attributes are excluded from comparison by default.

Exclusions affect both the displayed diff and the comparison verdict. If the plans differ only in excluded attributes, plan-diff exits with code 0, and deployment plan verification passes. Other attribute changes, resource additions and removals, lifecycle action changes, and replacement metadata still count as differences. Variables and outputs are compared independently: exporting an ignored resource attribute as an output does not exclude that output from comparison.

note

This setting controls Atmos's comparison of two plans. It does not modify Terraform plans, state, or resource updates, and it does not configure Terraform's lifecycle.ignore_changes.

Edition compatibility​

Starting with the 2026-10-13 edition, Atmos displays differences in response_body_base64, content_base64sha256, content_base64sha512, content_md5, content_sha1, content_sha256, and content_sha512. Unpinned projects get this behavior too.

Earlier editions retain the historical display-only suppression of these seven attributes. Their differences still cause plan-diff to exit with code 2 and deployment verification to fail, just as before; a resource heading can appear without an attribute diff. Pin an earlier date, such as edition: "2026-10-12", to preserve that display behavior.

Explicit ignore_changes entries exclude attributes from both comparison and display under every edition. To tolerate a content hash change, add its qualified attribute explicitly, for example local_file.content_sha256. Computed attributes and content hashes can represent real changes and are not automatically safe to ignore.

Examples​

Compare an existing plan with a new plan generated with current configuration​

atmos terraform plan-diff myapp -s dev --orig=orig.plan

Compare two existing plan files​

atmos terraform plan-diff myapp -s dev --orig=orig.plan --new=new.plan

Example with data resources​

When your Terraform configuration includes data sources, they will be automatically filtered out of the diff:

# Your plan might include data sources like:
# data.aws_ami.example
# data.aws_vpc.main
# aws_instance.web_server
# aws_s3_bucket.storage

# The diff will only show managed resources:
atmos terraform plan-diff myapp -s dev --orig=orig.plan

Output:

Resources:
-----------
+ aws_instance.web_server
~ aws_s3_bucket.storage
~ versioning.enabled: false => true

Output Format​

When there are no differences between the two plan files:

The planfiles are identical

When there are differences between the two plan files:

Diff Output
=========

Variables:
----------
+ added_var: "new value"
- removed_var: "old value"
~ changed_var: "old value" => "new value"

Resources:
-----------
+ aws_s3_bucket.new_bucket
- aws_instance.removed_instance
~ aws_security_group.modified_group
~ ingress.cidr_blocks: ["10.0.0.0/16"] => ["10.0.0.0/8"]
+ egress.port: 443

Outputs:
--------
+ new_output: "value"
- removed_output: "value"
~ changed_output: "old" => "new"

Exit Codes​

Exit CodeDescription
0Success - no differences found
1Error occurred during execution
2Success - differences found between plans

Use Cases​

The plan-diff command is useful for:

  1. Validating changes: Compare a previously saved plan with the current state to see what has changed.
  2. Reviewing variable impacts: See how changing variables affects the infrastructure plan.
  3. CI/CD workflows: Use the exit code to determine if changes are expected or unexpected.
  4. Documentation: Generate human-readable diffs for change management and approvals.

How It Works​

The command:

  1. Runs terraform init in the component directory
  2. If --new is not specified, runs a plan and captures the output
  3. Runs terraform show -json for each plan to get the JSON representation
  4. Sorts the JSON for consistent comparison
  5. Creates a diff between the two plans
  6. Handles sensitive values properly by displaying (sensitive value)
  7. Returns appropriate exit code based on whether differences were found