The atmos terraform plan-diff command compares two Terraform plans and shows the differences between them.
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.
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 initbefore 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:
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.
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 Code | Description |
|---|---|
| 0 | Success - no differences found |
| 1 | Error occurred during execution |
| 2 | Success - differences found between plans |
Use Cases
The plan-diff command is useful for:
- Validating changes: Compare a previously saved plan with the current state to see what has changed.
- Reviewing variable impacts: See how changing variables affects the infrastructure plan.
- CI/CD workflows: Use the exit code to determine if changes are expected or unexpected.
- Documentation: Generate human-readable diffs for change management and approvals.
How It Works
The command:
- Runs
terraform initin the component directory - If
--newis not specified, runs a plan and captures the output - Runs
terraform show -jsonfor each plan to get the JSON representation - Sorts the JSON for consistent comparison
- Creates a diff between the two plans
- Handles sensitive values properly by displaying
(sensitive value) - Returns appropriate exit code based on whether differences were found