Terraform State¶
Terraform state represents the current condition of infrastructure resources at a specific point in time — essentially, what Terraform expects to exist in your cloud account.
When Terraform provisions resources, it creates a terraform.tfstate file. This JSON file maps resource instances to their remote counterparts.
Terraform State Commands¶
Terraform provides multiple subcommands to inspect and manipulate state:
terraform state list— List resources in the stateterraform state show— Display detailed info about a resourceterraform state rm— Remove resources from the stateterraform state pull— Downloads the remote state over the local state and outputs itterraform state push— Update remote state from local fileterraform state replace-provider— Replace a provider in the stateterraform state mv— Move a resource within the state (e.g., move into a module or rename) without recreation (e.g.,terraform state mv aws_instance.worker module.worker.aws_instance.worker)
State Backups¶
Terraform automatically creates a backup whenever a state-changing command is run. Backup file: terraform.tfstate.backup Cannot be disabled — ensures recovery best practices
Resource Drift¶
Drift occurs when the real infrastructure differs from the expected state.
A resource address identifies zero or more resource instances:
[module_path][resource_spec]
module_path → module hierarchy: module.<module_name>[<module_index>]
- module - the namespace for modules
- module_name - user-defined name of the module
- module_index - when multiple, specify an index
resource_spec → specific resource instance:
<resource_type>.<resource_name>[<instance_index>]
- resource_type - type of the resource being addressed
- resource_name - user-defined name of the resource
- instance_index - when multiple, specify an index
Drift Resolutions¶
Replacing Resources¶
When a resource has become damaged or degraded that cannot be detected by
Terraform we can use the -replace flag to actually recreate it.
Terraform deprecated terraform taint in 0.15.2 (used to mark a resource for
replacement the next time apply was triggered).
- Usage:
terraform apply -replace="aws_instance.my_web_app" -replaceflag is available on both plan and apply. It was changed so that now, it prompts for manual approval-replaceappears to only work for a single resource
Importing Resources¶
When an approved manual addition of resource needs to be added to our state file,
we can use the terraform import command.
Command:
terraform import <RESOURCE_ADDRESS> <ID>
Usage:
- Define a placeholder for your imported resource in configuration files.
- Leave the body blank and fill it in after importing it. It will not be autofilled
resource "aws_instance" "example" {
# ...
}
- Import the resource using:
terraform import aws_instance.example i-abcd1234
Notes:
terraform importcommand can only import one resource at a time- Not all resources are importable, you need to check the bottom of resource documentation for support
Refreshing State¶
Use terraform apply -refresh-only to update Terraform state without changing
actual resources.
Previously: terraform refresh - deprecated due to updating the Terraform state
without prompting for approval .
Equivalent: terraform refresh → terraform apply -refresh-only -auto-approve
-refresh-onlyflag is supported by bothplanandapplycommands.
Cross-referencing stacks¶
terraform_remote_state data source retrieves root module output values from
another Terraform configuration:
data "terraform_remote_state" "vpc" {
backend = "remote"
config = {
organization = "hashicorp"
workspaces = {
name = "vpc-prod"
}
}
}
resource "aws_instance" "foo" {
subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
}
It can also reference local state files:
data "terraform_remote_state" "networking" {
backend = "local"
config = {
path = "${path.module}/networking/terraform.tfstate"
}
}
Notes:
- Only root-level outputs are accessible
- Nested module outputs must be exposed in the root module (otherwise, they are not accessible)
- instead of
terraform_remote_state, for which you need access on the entire state snapshot, it's recommended to use other data sources when possible.
State Locking¶
Terraform locks state for write operations automatically. This prevents others from acquiring the lock and potentially corrupting your state file.
Notes:
- Disable with
-lock=false(not recommended) - Force unlock:
terraform force-unlock <LOCK_ID>(useful when automatic unlocking fails)
Protecting Sensitive Data¶
Terraform state file can contain sensitive data (e.g. long-lived AWS credentials).
- Local backend → state stored in plaintext JSON → do not commit
- Remote/Cloud backends (Terraform Cloud / Enterprise) → state encrypted in transit & at rest (Enterprise also includes audit logging)
- Third-party storage (standard backends) → may ensure encryption, versioning, access controls, audit trails if you configure them
Terraform Ignore Files¶
.terraformignore (root only) excludes paths from remote operations.
This works like .gitignore, but only one file at root.
Default ignores: .git/, .terraform/
Output Values¶
Outputs expose useful information after Terraform runs:
- surface resource attributes
- feed external systems
- enable cross-stack references via terraform_remote_state
- provide debugging and visibility into deployed infrastructure
Outputs can be marked sensitive = true so it doesn't show in output of your
Terminal (but they will still be visible within the statefile).
CLI commands:
terraform output— list all outputsterraform output <name>— show one outputterraform output -json— print all outputs as json dataterraform output -raw— raw string output (preserve quotes for strings)