CLI · Infrastructure planning · HashiCorp, an IBM company
Terraform CLI
Describe infrastructure in configuration files, inspect a proposed plan and manage changes through providers and state.
Plans and state can contain secrets. Marking an output sensitive hides it in some human-readable output. The tested plan JSON still contained the synthetic value; protect plan and state artifacts as sensitive files.
Understand the tool
What it does.
Terraform CLI reads declarative configuration and uses providers to work with infrastructure APIs. It compares configuration with state and available remote information to propose changes. A plan is a review artifact; applying it is the separate step that can create, change or remove real resources.
Why use it?
Useful when infrastructure changes need versioned configuration and an explicit review step. Start with validation and a carefully scoped plan. The important setup is the state backend, provider versions and account permissions, because those determine what a command can read or change.
A useful fit for
- Reviewing proposed infrastructure changes
- Checking configuration in a repository
- Keeping repeatable infrastructure definitions
From need to output
Ways to put it to work.
These are suggested workflows based on the documented capabilities. They are not recorded runtime results.
Use case 01
Review a planned change
A team wants to adjust one infrastructure setting without losing sight of its effects.
- Confirm the backend, workspace, provider versions and target account.
- Generate a plan and inspect additions, changes and removals.
- Have the responsible owner review the plan before any apply.
Intended outputA concrete change proposal tied to configuration and state.
Use case 02
Catch configuration problems early
A contributor edits infrastructure code before it reaches a deployment workflow.
- Check formatting and review provider or module changes.
- Initialize only the intended dependencies and validate the configuration.
- Run a suitably scoped plan in the authorized environment before approval.
Intended outputEarlier feedback on configuration, with remote effects kept explicit.
A concrete starting point
Check formatting without rewriting files
Run in a directory containing Terraform configuration. Prints formatting differences and reports whether changes are needed. This illustrative command was not part of the runtime probes.
terraform fmt -check -diffWhat this can change
Reads local configuration and prints a diff; -check does not rewrite it or apply infrastructure changes.
This example has not been executed for this review. Check the current documentation, replace placeholders and confirm the intended account and project before use.
Before you start
Setup and access.
What you’ll need
- A Terraform binary matched to the configuration
- Reviewed configuration and pinned provider or module dependencies
- Backend and provider access for real infrastructure workflows
- Authentication
- Local formatting and provider-free checks need no account. Backends and providers can use cloud credentials, tokens or workload identity.
- Can read
- Configuration, state and plan files
- Remote resources and backend data according to credentials
- Can write or change
- State, plan and local working files
- Real infrastructure when a provider operation applies a change
- Network and data flow
- Provider and module distribution sources
- Configured backend and provider APIs
- Approval and control
- Review both target context and plan before apply. Automation flags can remove interactive confirmation, and provider code runs with the process access.
Check your environment
Compatibility, costs and license.
Compatibility notes
- Windows, macOS and Linux
- Provider, module and backend versions must match the intended workflow
Costs and account requirements
The Community CLI can be downloaded without a hosted subscription. HCP Terraform, enterprise offerings and managed infrastructure have separate pricing and limits.
Current pricing or plan information ↗Business Source License 1.1
Source-available terms include an additional use grant and restrictions. Check the linked terms, especially for a competing hosted or embedded offering.
Read the license or service terms ↗Keep the boundaries visible
Concerns and limitations.
Plans and state can contain secrets
Marking an output sensitive hides it in some human-readable output. The tested plan JSON still contained the synthetic value; protect plan and state artifacts as sensitive files.
A plan depends on trusted configuration and providers
Initialization can obtain executable providers and modules. Review sources, pin versions and verify the target backend before using real credentials.
Apply changes real systems
Resource replacement, deletion and ongoing cloud charges can follow an approved plan. Use scoped identity, state controls and a clear review process.
Where it may fall short
- The executed test used only the built-in terraform_data resource and never applied a plan.
- Current source uses Business Source License 1.1, not the older MPL terms; review the actual license for your intended use.
Observed behavior · 2026-10-18
Runtime and security findings.
A built-in-provider configuration initialized, validated and planned one addition without applying it. Human output hid a sensitive value, but plan JSON contained it; an invalid variable value was rejected.
These checks cover the conditions below. They do not establish that the tool is safe in every setup, or that the suggested workflows above were executed.
What we found
Observed in this evaluation · medium severity under stated conditions
Sensitive markers do not remove values from plan JSON
The human plan showed a sensitive placeholder. terraform show -json returned the synthetic-only value with sensitive=true. This is documented behavior and a practical artifact-handling concern, not a newly discovered vulnerability.
In practice: Protect plan files, state and JSON exports; do not send them to public logs or broad review systems without careful handling.
Observed in this evaluation
Local validation rejected the configured forbidden value
The fixture allowed only environment=test. Passing environment=production returned exit 1 with the authored validation message. No remote resource or policy was involved.
In practice: Use input validation for useful early checks, while retaining backend, IAM and policy controls for real infrastructure.
Version, environment and fixture
- Version or deployment
- 1.16.6 windows_amd64
- Tested target
- https://releases.hashicorp.com/terraform/1.16.6/terraform_1.16.6_windows_amd64.zip
- Artifact identity
- SHA-256 6ea2c186e0e76a113af30fbcdcf7a4b4c70756317994a04929e5c90b9e94b1df of the downloaded ZIP archive. Matched the official release checksum; detached signatures were not verified.
- Environment and fixture
- Windows 11 x64; Python 3.12.10 harness. Raw timestamps use UTC.
- Fresh per-tool home, config, cache and temporary directories. Child environments used allowlisted OS/runtime paths without inherited account credentials. Only synthetic local files were used.
- Configuration isolation is a test control, not an operating-system sandbox.
- The fixture disabled backend initialization, inherited credentials and update checks; no cloud account was used.
Checks and results
6 recorded checks. Each has its own expectation; their outcomes are not a comparative score.
Pinned binary versionMet expectation
- Method
Command argument array: ["terraform", "version", "-json"].- Expected
- Print version 1.16.6 for windows_amd64.
- Observed
- Exit 0. terraform_version="1.16.6", platform="windows_amd64", provider_selections={}.
Initialize the built-in provider fixtureMet expectation
- Method
Create main.tf with this exact configuration: variable "environment" { type = string default = "test" validation { condition = var.environment == "test" error_message = "Only the synthetic test environment is allowed." } } resource "terraform_data" "fixture" { input = var.environment } output "fixture_token" { value = "synthetic-only" sensitive = true } Use an empty TF_CLI_CONFIG_FILE, isolated TF_DATA_DIR, CHECKPOINT_DISABLE=1 and no cloud credentials. The resource uses the built-in provider. Command argument array: ["terraform", "init", "-backend=false", "-input=false", "-no-color"].- Expected
- Initialize without configuring a backend or downloading an external provider.
- Observed
- Exit 0. Initializing provider plugins... - terraform.io/builtin/terraform is built in to Terraform Terraform has been successfully initialized!
Validate the synthetic configurationMet expectation
- Method
Create main.tf with this exact configuration: variable "environment" { type = string default = "test" validation { condition = var.environment == "test" error_message = "Only the synthetic test environment is allowed." } } resource "terraform_data" "fixture" { input = var.environment } output "fixture_token" { value = "synthetic-only" sensitive = true } Use an empty TF_CLI_CONFIG_FILE, isolated TF_DATA_DIR, CHECKPOINT_DISABLE=1 and no cloud credentials. The resource uses the built-in provider. Run the preceding init first. Command argument array: ["terraform", "validate", "-json"].- Expected
- Return valid=true with zero errors and warnings.
- Observed
- Exit 0. valid=true, error_count=0, warning_count=0, diagnostics=[].
Inspect a plan with a sensitive outputMet expectation
- Method
Create main.tf with this exact configuration: variable "environment" { type = string default = "test" validation { condition = var.environment == "test" error_message = "Only the synthetic test environment is allowed." } } resource "terraform_data" "fixture" { input = var.environment } output "fixture_token" { value = "synthetic-only" sensitive = true } Use an empty TF_CLI_CONFIG_FILE, isolated TF_DATA_DIR, CHECKPOINT_DISABLE=1 and no cloud credentials. The resource uses the built-in provider. Run init first. Command argument array: ["terraform", "plan", "-input=false", "-lock=false", "-refresh=false", "-no-color", "-out=fixture.tfplan"].- Expected
- Plan one addition and redact the sensitive value in human output.
- Observed
- Exit 0. Plan: 1 to add, 0 to change, 0 to destroy. fixture_token appeared as (sensitive value); a local fixture.tfplan was saved.
Inspect sensitive output in plan JSONMet expectation
- Method
Use fixture.tfplan from the preceding plan, whose fixture_token is the synthetic string synthetic-only. Command argument array: ["terraform", "show", "-json", "fixture.tfplan"].- Expected
- Show the raw synthetic value alongside its sensitive marker.
- Observed
- Exit 0. planned_values.outputs.fixture_token={"sensitive":true,"type":"string","value":"synthetic-only"}.
Reject a value outside the fixture validationMet expectation
- Method
Create main.tf with this exact configuration: variable "environment" { type = string default = "test" validation { condition = var.environment == "test" error_message = "Only the synthetic test environment is allowed." } } resource "terraform_data" "fixture" { input = var.environment } output "fixture_token" { value = "synthetic-only" sensitive = true } Use an empty TF_CLI_CONFIG_FILE, isolated TF_DATA_DIR, CHECKPOINT_DISABLE=1 and no cloud credentials. The resource uses the built-in provider. Run init first. Command argument array: ["terraform", "plan", "-input=false", "-lock=false", "-refresh=false", "-no-color", "-var=environment=production"].- Expected
- Reject environment=production with the explicit validation message.
- Observed
- Exit 1. Invalid value for variable: Only the synthetic test environment is allowed.
Practical caveats
- No plan was applied and no external provider was installed. The test used terraform_data and an isolated local working directory.
- -lock=false and -refresh=false were bounded test choices; they are not recommended defaults for shared production state.
What this evaluation does not establish
- Apply or destroy, real cloud providers, remote backends, credentials, IAM and production infrastructure changes.
- State locking, drift, concurrent runs, provider or module supply chains and complete secret handling.
Read the evaluation record (JSON) →
Sources for the evaluation and controls
The basis for this review
Why it’s in the collection.
Adds infrastructure planning and the review of state-dependent changes. It follows the local data tools because providers, backend access and sensitive artifacts require a more deliberate operating context. The original catalog order is preserved; this is an editorial position, not a measured adoption or security rank.
The number is an editorial starting order within the cli tools collection. It does not measure popularity, speed, reliability or safety.
Why we added it
Adds infrastructure planning with explicit state, provider and license caveats; provider-free validation is testable without cloud access.
Selection evidence checked .
- Repository interest
- 49,974 GitHub stars at this snapshot ↗
Interest in the source repository; not a count of verified users or installations.
- Repository activity
- Last push reported by GitHub: . A push can include documentation or maintenance; it does not establish a new stable release.
- Release signal
- v1.16.6 ↗ · published . This selection signal can differ from the exact runtime tested above.
- A single dated repository-interest/release snapshot; not measured adoption, growth, effectiveness or security.
- Repository interest and release activity do not establish reliability, model quality or safety. The evaluation names the exact version and conditions tested.
What we reviewed
- Official documentation, repository, license and release identity
- Practical access boundaries and a separate bounded runtime evaluation
The evaluation above lists the current runtime coverage and untested behavior.
Reviewed Oct 18, 2026. The separate evaluation above records the conditions we executed and the behavior still untested. Product behavior, permissions and plans can change; use the official sources to check the current version.
Follow the evidence
Official sources.
- Terraform CLI ↗developer.hashicorp.com
- JSON show output and sensitive values ↗developer.hashicorp.com
- Sensitive data handling ↗developer.hashicorp.com
- Terraform editions ↗developer.hashicorp.com
- Terraform repository ↗github.com
- Business Source License ↗github.com