Managing Terraform State
1. Understanding State Files
| Property | Description | Default Value | Notes |
|---|---|---|---|
| backend | Defines where Terraform stores its state file | local | Can be remote, s3, azurerm, etc. |
| workspace | Workspace name for state isolation | default | Each workspace has its own state file |
| path | Local path to the state file | terraform.tfstate |
Only used with local backend |
Example: State file structure
{
"version": 4,
"terraform_version": "1.8.0",
"serial": 1,
"lineage": "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6",
"outputs": {},
"resources": [
{
"module": "",
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider["registry.terraform.io/hashicorp/aws"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-12345678",
"instance_type": "t2.micro"
}
}
]
}
]
}
Note: State files are critical for Terraform to track and manage infrastructure. Never manually edit state files.
2. Listing State Resources
| Command | Description | Flags |
|---|---|---|
| terraform state list | List all resources in the state | -state=<path> to specify state file |
Example: Listing resources with a specific state file
terraform state list -state=/path/to/terraform.tfstate
Note: The
terraform state list command outputs a list of all managed resources in the current state, including their full address (e.g., aws_instance.example).
3. Showing Resource State
| Command | Description | Notes |
|---|---|---|
| terraform show | Display the current state file in a human-readable format | Shows all resources and their attributes |
| terraform show <resource_address> | Display a specific resource's state | Useful for inspecting individual resources |
| terraform show -json | Display the state in JSON format | Useful for programmatic consumption |
Note: The
terraform show command reads the current state file and displays it in a human-readable format. It's useful for inspecting what Terraform currently knows about your infrastructure.
4. Moving Resources
| Operation | Description | Command | Notes |
|---|---|---|---|
| terraform state mv | Moves an instance in the state file | terraform state mv <source> <destination> |
Can move resources, modules, or outputs |
Note: Always run
terraform plan after moving resources to verify the changes.
Warning: Moving resources can cause drift between the state and actual infrastructure if not handled carefully.
5. Removing Resources
| Resource Type | Description | Notes |
|---|---|---|
| aws_instance | Represents an EC2 instance in AWS | Use terraform destroy to remove |
| aws_s3_bucket | Represents an S3 bucket in AWS | State must be managed properly to avoid data loss |
| google_compute_instance | Represents a Compute Engine instance in GCP | Ensure state is updated after manual deletion |
Example: Removing an AWS Instance
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "web-server"
}
}
# To remove this resource, run:
# terraform destroy -target=aws_instance.web
Note: Always verify that the resource is no longer needed before running
terraform destroy. State files must be updated to reflect the removal.
Warning: Removing resources via Terraform will delete the actual infrastructure. Ensure backups or snapshots are created if necessary.
6. Replacing Provider Addresses
| Address Format | Description | Example |
|---|---|---|
| registry.terraform.io/hashicorp/aws | Official provider from Terraform Registry | provider "aws" { source = "registry.terraform.io/hashicorp/aws" } |
| hashicorp/aws | Short name for official providers (resolved automatically) | provider "aws" { source = "hashicorp/aws" } |
| mycorp/aws | Custom namespace for providers (e.g., from private registry) | provider "aws" { source = "mycorp/aws" } |
| ./local-provider | Local provider path (relative or absolute) | provider "aws" { source = "./local-provider" } |
Example: Replacing Provider Address
provider "aws" {
source = "registry.terraform.io/hashicorp/aws"
version = "5.0.0"
}
Note: When replacing provider addresses, ensure that the new address resolves to the same provider version or update the
version constraint accordingly.
Warning: Changing provider addresses can cause drift in state if not handled carefully. Always backup your state before making such changes.
7. Pulling Remote State
| Command | Description | Notes |
|---|---|---|
| terraform state pull | Downloads and outputs the current state from its configured backend | Useful for inspecting or backing up state without modifying it |
Example: Pulling Remote State
$ terraform state pull
{
"version": 4,
"terraform_version": "1.7.0",
"serial": 1,
"lineage": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"outputs": {},
"resources": [
{
"module": "",
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider["registry.terraform.io/hashicorp/aws"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-12345678",
"id": "i-1234567890abcdef0",
"instance_type": "t2.micro"
}
}
]
}
]
}
Note: The pulled state is in JSON format and can be saved to a file for backup or inspection purposes.
8. Pushing Local State
Note: This section assumes you are using a local state file and want to push it to a remote backend like S3, GCS, or Azure Blob Storage.
| Command | Description | Example |
|---|---|---|
| terraform init | Initializes the Terraform configuration and backend. | terraform init |
| terraform remote config | Configures the remote backend (deprecated in favor of backend block). |
terraform remote config -backend=s3 -backend-config=bucket=example-state-bucket |
| terraform state push | Pushes the local state file to the remote backend. | terraform state push ./terraform.tfstate |
Warning: Ensure that the remote backend is properly configured before pushing to avoid state corruption or loss.
9. Refreshing State
Refreshing Terraform state updates the local state file to reflect the actual infrastructure in the cloud.
| Command | Description | Flags |
|---|---|---|
| terraform refresh | Updates the state file with current resource attributes from the cloud provider | -backup=<path> - Backup the previous state file-lock=<bool> - Lock state during refresh-lock-timeout=<duration> - Timeout for state lock |
Note: Refreshing state does not modify infrastructure, only updates the local state file to match real-world resources.
Warning: If resources have been deleted externally (e.g., manually in AWS console),
terraform refresh will detect the drift but won't remove them from state. Use terraform state list to verify and terraform state rm if needed.
10. Backing Up State Files
| Command | Description | Notes |
|---|---|---|
| terraform state pull | Downloads the current state from the backend and outputs it to stdout | Useful for manual backups or scripting state retrieval |
| terraform state push | Uploads a local state file to the backend | Can be used to restore a previous state from a backup |
| terraform backup | Creates a backup of the current state file | Available in Terraform 0.12+, creates a .backup file |
Note: For remote backends like S3, Azure Blob Storage, or GCS, ensure the backup is stored securely and has appropriate access controls.
11. Recovering from State Corruption
Note: State corruption can occur due to concurrent operations, manual edits to state files, or system failures. Recovery strategies depend on the severity and cause of corruption.
| Recovery Method | Description | Conditions | Notes |
|---|---|---|---|
| Backup Restoration | Restore state from a known good backup. | Backups exist and are recent. | Ensure backups are encrypted and stored securely. |
| State Locking | Release locks manually if stuck in a corrupted state. | Lock file is present and invalid. | Use terraform force-unlock with caution. |
| State Pull & Reapply | Manually pull state and reapply changes. | State file is readable but inconsistent. | Requires careful manual reconciliation of resources. |
Warning: Manual state file edits can lead to further inconsistencies. Always verify backups before restoring.