Terraform CLI Commands and Quick Notes
11/15/2024
Terraform CLI Commands and Quick Notes
This article organizes Terraform commands by workflow. Commands that are self-explanatory are grouped under a single short description. Deprecated or malformed commands from the original notes are retained and clearly marked with the recommended alternative.
Important: Commands that modify infrastructure or state should be reviewed carefully before use, especially
-auto-approve,-lock=false,terraform state push,terraform state rm,terraform force-unlock, and targeted operations.
1. Help, Version, and CLI Convenience
Use these commands to view help, check the installed Terraform version, enable shell completion, run Terraform from another directory, or open the interactive console.
terraform -help
terraform fmt -help
terraform version
terraform -install-autocomplete
terraform -chdir="../dev" apply
terraform console
terraform -help— Get a list of available commands with descriptions. It can also be used with a subcommand for more information.terraform fmt -help— Display help options for thefmtcommand.terraform version— Show the installed Terraform version and notify you when a newer version is available.terraform -install-autocomplete— Install shell autocomplete support.terraform -chdir="../dev" apply— Change to the specified directory before running the command.terraform console— Open an interactive console for evaluating Terraform expressions.
2. Format Terraform Code
Run formatting early after creating or editing configuration files. These commands apply the standard HCL formatting rules and help keep code consistent for collaboration and CI/CD.
terraform fmt
terraform fmt -recursive
terraform fmt -diff
terraform fmt -check
terraform fmt— Format Terraform configuration files.terraform fmt -recursive— Also format Terraform files in subdirectories.terraform fmt -diff— Display the differences between the original and formatted content.terraform fmt -check— Check formatting without changing files. It returns a non-zero exit status when formatting is required.
Question: Does terraform fmt have a recursive option?
Yes. Use terraform fmt -recursive to format Terraform files in the current directory and its subdirectories.
3. Initialize a Working Directory
terraform init prepares a working directory, downloads required providers and modules, and initializes the backend. Run it for a new configuration and again after changing providers, modules, or backend settings.
terraform init
terraform init -backend=false
terraform init -lock=false
terraform init -input=false
terraform init -migrate-state
terraform init -upgrade
terraform init -get-plugins=false
terraform init -verify-plugins=false
terraform init -backend=false— Skip backend initialization.terraform init -lock=false— Do not hold a state lock during backend migration. Use with caution.terraform init -input=false— Disable interactive prompts.terraform init -migrate-state— Reconfigure the backend and attempt to migrate existing state.terraform init -upgrade— Select newer provider and module versions allowed by the configured version constraints.terraform init -get-plugins=false— Deprecated. Initialize without downloading plugins.terraform init -verify-plugins=false— Deprecated. Skip provider signature verification.
Initialize & Validate
The corrected syntax is:
terraform init -backend=false && terraform validate
Note: Validate but skip backend validation.
Question: What is a backend?
A backend defines where Terraform stores state and, depending on the backend, how operations such as state locking are performed.
4. Download and Update Modules
These commands download modules required by the configuration. This is usually handled automatically by terraform init.
terraform get
terraform get -update
terraform get— Download and install required modules.terraform get -update— Check installed modules and download newer versions that satisfy the configuration.
5. Validate Terraform Configuration
Validation checks configuration syntax and internal consistency. Initialize the directory first so required providers and modules are available.
terraform validate
terraform validate -json
terraform validate— Validate the configuration without accessing remote state or remote services.terraform validate -json— Return validation results in machine-readable JSON.
6. Test Terraform Configuration
Terraform test files normally use the .tftest.hcl extension. These commands discover and execute tests for root configurations and modules.
terraform test
terraform test -test-directory=tests
terraform test -filter=tests/my_test.tftest.hcl
terraform test -verbose
terraform test -test-directory=tests— Search for test files in a custom directory.terraform test -filter=tests/my_test.tftest.hcl— Run only the specified test file.terraform test -verbose— Show the plan or state for each test run.
7. Create and Save Execution Plans
Use terraform plan before applying changes to review what Terraform intends to create, update, replace, or destroy.
terraform plan
terraform plan -out=<path>
terraform plan -out="test.tfplan"
terraform plan -destroy
terraform plan -refresh-only
terraform plan -out=<path>— Save the generated plan to a file for a laterterraform apply.terraform plan -destroy— Create a plan that destroys all managed objects.terraform plan -refresh-only— Review state updates needed to match real infrastructure without planning normal configuration changes.
Refresh-only notes
Note 1: Used to make changes to state without making changes to the infrastructure — please refer again.
Note 2: The
terraform plan -refresh-onlycommand is used in Terraform to update the state of your infrastructure in memory without making any actual changes to the infrastructure.
Note 3: It is important to note that while the
terraform plan -refresh-onlycommand updates Terraform’s internal state, it does not modify the Terraform state file on disk. The Terraform state file is only updated when Terraform actually makes changes to the infrastructure.
Clarification: terraform plan -refresh-only only previews the proposed state changes. Use terraform apply -refresh-only to save those refreshed values to state.
8. Apply Infrastructure Changes
Use terraform apply after reviewing the proposed changes. A saved plan can be applied directly without another approval prompt.
terraform apply
terraform apply -auto-approve
terraform apply <planfilename>
terraform apply test.tfplan
terraform apply -lock=false
terraform apply -parallelism=<n>
terraform apply -parallelism=2
terraform apply -var="environment=dev"
terraform apply -var-file="varfile.tfvars"
terraform apply -target=aws_instance.example
terraform apply -refresh-only
terraform apply -refresh=false
terraform apply -replace="aws_instance.example[0]"
terraform apply -destroy
terraform apply -auto-approve— Apply without requiring an interactiveyes. Useful in controlled automation.terraform apply <planfilename>— Apply a previously saved plan without another confirmation prompt.terraform apply -lock=false— Do not lock state during the operation. Use with caution when concurrent runs are possible.terraform apply -parallelism=<n>— Limit the number of concurrent operations.terraform apply -var="environment=dev"— Set one input variable.terraform apply -var-file="varfile.tfvars"— Load variable values from a file.terraform apply -target=aws_instance.example— Apply only to the targeted resource and its dependencies. Use sparingly.terraform apply -refresh-only— Update the state to match real infrastructure without making normal create, update, or destroy changes.terraform apply -refresh=false— Skip the normal state refresh before applying. This can save time in very large environments but may produce a plan based on stale information.terraform apply -replace="aws_instance.example[0]"— Plan and apply replacement of a specific resource instance.terraform apply -destroy— Destroy Terraform-managed infrastructure.terraform destroyis a convenience alias for this operation.
Note: Do not reconcile for state, to save time in large data centers. The corrected syntax is:
terraform apply -refresh=false
Important Note: Make the state file match the real infrastructure, but do not match it to the configuration when there is resource drift.
Apply a saved plan without typing yes
Linux/macOS shell
terraform plan -out="test.tfplan" && terraform apply test.tfplan
Windows PowerShell
terraform plan -out="test.tfplan"; terraform apply test.tfplan
Avoid Prompting
TO : run without using
yesas approval, the operators are"and"and";".
terraform plan -out="test.tfplan" and terraform apply test.tfplan # linux
terraform plan -out="test.tfplan" ; terraform apply test.tfplan # windows
Clarification: The normal Linux/macOS shell operator is &&, not the word and. A semicolon runs the next command even if the first command fails, while && runs it only after success.
9. Destroy Infrastructure
These commands destroy all managed infrastructure or only a selected target.
terraform destroy
terraform destroy -target=aws_instance.example
terraform destroy -auto-approve
terraform destroy -target="module.appgw.resource[\"key\"]"
terraform plan -destroy
terraform apply -destroy
terraform destroy— Destroy all infrastructure managed by the current configuration.terraform destroy -target=aws_instance.example— Destroy only the targeted resource.terraform destroy -auto-approve— Destroy without requiring an interactiveyes.terraform destroy -target="module.appgw.resource[\"key\"]"— Destroy one resource instance created withfor_each.
Note: Use
-targetsparingly. For large environments, prefer smaller, separately managed configurations instead of routinely relying on targeted operations.
10. Replace, Taint, and Untaint Resources
Replacement recreates a resource even when its configuration has not changed. The -replace option is preferred because the replacement decision remains visible in the normal plan-and-apply workflow.
terraform apply -replace="aws_instance.example[0]"
terraform taint vm1.name
terraform taint instancetype.name
terraform untaint vm1.name
terraform taint vm1.name— Deprecated. Mark a resource for replacement in state.terraform taint instancetype.name— Deprecated. Another retained taint example.terraform untaint vm1.name— Remove the tainted status from a resource.
Question: Is there a terraform replace command?
No. There is no standalone terraform replace command; use terraform plan -replace=ADDRESS or terraform apply -replace=ADDRESS.
Question: What is the difference between replace and taint?
-replace records the replacement in the plan you review. taint immediately changes state and is deprecated, so -replace is safer and preferred.
11. Refresh Terraform State
Refresh-only mode reconciles Terraform state with real infrastructure without performing normal configuration-driven changes.
terraform refresh
terraform plan -refresh-only
terraform apply -refresh-only
terraform refresh— Deprecated. Previously updated state to match real infrastructure.terraform plan -refresh-only— Preview changes that would update state.terraform apply -refresh-only— Review and save refreshed values to the state.
Use refresh-only mode after an emergency manual change or another out-of-band infrastructure change that Terraform needs to record.
12. View Plans, State, and Resources
Use terraform show for a complete state or plan file. Use terraform state show for one resource.
terraform show
terraform show <path to statefile>
terraform show -json
terraform state show <resourcename>
terraform state show docker_image.nginx
terraform show— Display the latest state snapshot in human-readable form.terraform show <path to statefile>— Display a specific state or plan file.terraform show -json— Display state or plan data in machine-readable JSON.terraform state show <resourcename>— Display detailed state data for one resource.
Question: What is the difference between terraform show and terraform state?
terraform show displays an entire state or plan file. terraform state contains subcommands for listing, inspecting, moving, removing, pulling, pushing, or changing individual state entries.
13. Manage Terraform State
State commands support both local and remote state. Commands that modify state create backup files, but should still be used carefully.
terraform state
terraform state list
terraform state mv
terraform state mv vm1.oldname vm1.newname
terraform state pull
terraform state pull > state.tfstate
terraform state push
terraform state rm
terraform state replace-provider
terraform state replace-provider hashicorp/azurerm customproviderregistry/azurerm
terraform state show <resourcename>
terraform state show docker_image.nginx
terraform state list— List resources tracked in the current state.terraform state mv— Move or rename an address in state, for example when a resource is renamed.terraform state pull— Download the current state and write it to standard output.terraform state pull > state.tfstate— Save the pulled state to a local file.terraform state push— Upload a local state file. Use with extreme caution.terraform state rm— Remove a resource from state without destroying the real object. A later plan may propose creating it again unless the configuration is also changed.terraform state replace-provider— Change provider source addresses recorded in state.terraform state show— Display one resource from state.
14. Import Existing Infrastructure
Import associates an existing real-world object with a Terraform resource address in state.
terraform import <resource_address> <resource_id>
Example:
terraform import aws_instance.example i-0123456789abcdef0
After import, ensure the Terraform configuration matches the imported object so the next plan does not propose unexpected changes.
15. Output Values
These commands display root-module output values stored in Terraform state.
terraform output
terraform output -state=<path to state file>
terraform output -json
terraform output -raw <output_name>
terraform output vm1_public_ip
terraform output— Display all root-module outputs in the current state.terraform output -state=<path to state file>— Display outputs from a specified local state file. This legacy option is ignored for remote state.terraform output -json— Return outputs in machine-readable JSON.terraform output -raw <output_name>— Print a simple string, number, or boolean without extra formatting.terraform output vm1_public_ip— Display one named output.
In CI/CD pipelines, prefer
terraform output -jsonandterraform show -jsonso downstream tools can parse the results.
Question: Is there a command like terraform output?
Yes. The command is exactly terraform output; it reads output values declared in the root module from the current state.
16. Workspaces
CLI workspaces provide separate state instances for the same configuration. They can help with temporary variations, but separate directories or configurations are often clearer for strongly isolated development, UAT, and production environments.
terraform workspace
terraform workspace new prod
terraform workspace new <workspace name>
terraform workspace list
terraform workspace show
terraform workspace select <workspace name>
terraform workspace select
terraform workspace delete <workspace name>
terraform workspace delete
terraform workspace show— Show the current workspace.terraform workspace list— List available workspaces.terraform workspace select <workspace name>— Switch to an existing workspace.terraform workspace new <workspace name>— Create and select a workspace.terraform workspace delete <workspace name>— Delete a workspace that is not currently selected.
The incomplete select and delete commands above; both require a workspace name or additional applicable options.
17. Provider Information and Dependency Management
These commands inspect provider requirements, create mirrors, print schemas, and update provider selections in the dependency lock file.
terraform providers
terraform providers mirror <target-dir>
terraform providers schema -json
terraform providers lock
terraform -plugin-dir=path
terraform providers— Display the provider requirements of the configuration.terraform providers mirror <target-dir>— Download required provider packages into a local filesystem mirror.terraform providers schema -json— Print provider, resource, and data-source schemas as JSON.terraform providers lock— Update provider selections and checksums in.terraform.lock.hcl.terraform -plugin-dir=path— Global option example for loading provider plugins from a specified directory.
More commands
terraform providers mirror
terraform providers schema
Both normally need more information: mirror requires a target directory, and schema requires -json.
18. Dependency Lock File and State Locking
Question: When does Terraform lock the state file?
Terraform automatically locks state for operations that can write state, provided the selected backend supports state locking.
Question: Does .terraform.lock.hcl lock the state file?
No. .terraform.lock.hcl records provider versions and checksums; state locking is a separate backend operation that prevents concurrent state writes.
Understanding versioning
Use version constraints to define compatible Terraform, provider, and module versions. The dependency lock file then records the exact selected provider versions for repeatable runs.
terraform {
required_version = "~> 1.14"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
required_versionconstrains the Terraform CLI version.- A provider
versionconstraint defines acceptable provider versions. .terraform.lock.hclrecords the selected provider version and checksums.- Remote module selections are not currently recorded in
.terraform.lock.hcl; use a precise module version constraint when repeatability is required.
19. Force-Unlock State
Use force-unlock only when Terraform failed to release a lock from your own interrupted operation. Unlocking a state actively used by another process can cause concurrent writes and state corruption.
terraform force-unlock <lock_id>
Terraform reports the lock ID when lock acquisition or release fails.
20. Log In and Log Out
These commands manage local API credentials for HCP Terraform or a Terraform Enterprise hostname.
terraform login
terraform login <hostname>
terraform login hostname
terraform logout
terraform logout <hostname>
terraform logout hostname
terraform login— Obtain and store a token for the default HCP Terraform hostname.terraform login <hostname>— Authenticate to a specified HCP Terraform or Terraform Enterprise host.terraform logout— Remove stored credentials for the default host.terraform logout <hostname>— Remove stored credentials for the specified host.
The literal hostname are examples; replace hostname with the real host name.
21. Generate a Dependency Graph
Use the graph command to produce a Graphviz DOT representation of Terraform dependencies.
terraform graph
terraform graph | dot -Tsvg > graph.svg
The first command prints DOT data. The second converts it to an SVG when Graphviz is installed.
22. Terraform Environment Variables
Terraform CLI environment variables control logging, input handling, variables, default arguments, working data, automation behavior, and plugin caching.
TF_LOG
TF_LOG_PATH
TF_INPUT
TF_MODULE_DEPTH
TF_VAR_name
TF_CLI_ARGS
TF_CLI_ARGS_name
TF_DATA_DIR
TF_SKIP_REMOTE_TESTS
TF_LOG— Set Terraform log verbosity, such asTRACE,DEBUG,INFO,WARN, orERROR.TF_LOG_PATH— Write logs to a file.TF_LOGmust also be enabled.TF_INPUT— Set tofalseor0to disable interactive input.TF_VAR_name— Set the value of an input variable namedname.TF_CLI_ARGS— Add default arguments to all Terraform commands.TF_CLI_ARGS_name— Add default arguments to one command, such asTF_CLI_ARGS_plan.TF_DATA_DIR— Change the location where Terraform stores per-working-directory data that normally lives in.terraform.TF_MODULE_DEPTH— This is an old/legacy variable and is not part of the current standard CLI environment-variable reference.TF_SKIP_REMOTE_TESTS— This is not a common current Terraform CLI environment variable and may relate to an older or specialized test workflow.
23. Provider Alias Example
Provider aliases allow multiple configurations of the same provider, such as two AWS regions or accounts.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "ap-southeast-2"
}
provider "aws" {
alias = "us_east"
region = "us-east-1"
}
resource "aws_s3_bucket" "secondary" {
provider = aws.us_east
bucket = "example-secondary-bucket"
}
24. Null Resource and Provisioners
Question: What is the difference between a null resource and a provisioner?
A provisioner runs a local or remote action. A null_resource was commonly used only as a container for provisioners; for new code, prefer the built-in terraform_data resource when no real infrastructure resource is suitable.
Example using terraform_data:
resource "terraform_data" "example" {
triggers_replace = [
var.deployment_version
]
provisioner "local-exec" {
command = "echo Deployment version changed"
}
}
Provisioners should be a last resort because Terraform cannot model their behavior as reliably as normal provider-managed resources.
25. Terraform Editions: OSS, HCP Terraform, and Enterprise
Question: What is the difference between Terraform OSS, HCP Terraform, and Terraform Enterprise?
- Terraform CLI/OSS: Runs locally or in your own automation and uses configured backends for state.
- HCP Terraform: HashiCorp-hosted service for remote runs, state, collaboration, policies, and a private registry.
- Terraform Enterprise: Self-hosted distribution of the HCP Terraform application for organizations that need to run it in their own environment.
26. Private Registry
A private registry lets an organization publish, version, discover, and reuse approved private modules and providers. HCP Terraform and Terraform Enterprise provide organization-scoped private registries.
27. Quick Review Questions
Show vs state
terraform show reads a whole plan or state snapshot. terraform state provides focused subcommands to inspect or modify addresses inside state.
Understanding versioning
Set compatible versions in required_version, provider version constraints, and module version arguments. Commit .terraform.lock.hcl so provider selections remain consistent.
When will the state file get locked?
Before an operation that may write state, if the backend supports locking. Read-only operations generally do not need a write lock.
Null resource vs provisioner
A provisioner is an action block. A null-style resource is only a container that gives the action lifecycle; prefer terraform_data for new configurations.
Is there any command like terraform output?
Yes: terraform output, terraform output -json, terraform output -raw NAME, and terraform output NAME.
Will the dependency lock file lock the state file?
No. .terraform.lock.hcl pins provider packages; a backend state lock controls concurrent state writes.
Terraform replace
Use terraform plan -replace=ADDRESS or terraform apply -replace=ADDRESS; there is no standalone replace command.
Enterprise vs cloud vs OSS
CLI/OSS is the local engine, HCP Terraform is HashiCorp-hosted, and Terraform Enterprise is the self-hosted platform.
Private registry
It is an organization-controlled catalog for sharing approved modules and providers with versioning and access control.
Replace vs taint
-replace is reviewed in a plan and is recommended. terraform taint writes a tainted status into state immediately and is deprecated.
Provider alias
Use alias in an additional provider block and reference it as <provider>.<alias>, such as aws.us_east.
28. Study and Review the above Notes, also refer the following pages & videos
Review every plan before applying it, commit .terraform.lock.hcl, and avoid disabling locking or refresh unless you understand the risk.
Introduction to Terraform :
Terraform in 10 commands :
Terraform in 10 minutes :
Recommended Article 1 :
Recommended Article 2 :
Recommended Article 3 :
29. Suggested Terraform Command Workflow
A common safe sequence is:
terraform version
terraform fmt -recursive
terraform init
terraform validate
terraform test
terraform plan -out="test.tfplan"
terraform show test.tfplan
terraform apply test.tfplan
terraform output
For cleanup:
terraform plan -destroy
terraform destroy