terraform state Commands: Inspecting and Manipulating State
Scenario
You need to rename a resource in your config without destroying and recreating it. You also want to remove a resource from Terraform's management (without deleting it from AWS), and inspect what's currently tracked in state. The terraform state family of commands gives you direct control over the state file.
- Use terraform state list to see all tracked resources.
- Use terraform state show to inspect a resource's details.
- Use terraform state mv to rename a resource in state (without destroy/recreate).
- Use terraform state rm to remove a resource from state (without deleting it from AWS).
- Use terraform state pull to download remote state.
Additional Context
state mv is the CLI-based rename. For a declarative approach, use moved blocks (Lab 29). Both achieve the same result — moving a resource to a new address in state without destroying it.
state rm removes a resource from Terraform's tracking WITHOUT deleting it from the cloud. The resource still exists in AWS; Terraform just stops managing it. This is useful when transferring ownership of a resource to another Terraform config or to manual management.
main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" { region = "us-east-1" }
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "old_name" {
bucket = "state-cmds-demo-${data.aws_caller_identity.current.account_id}"
tags = { ManagedBy = "terraform" }
}
resource "aws_s3_bucket" "unmanaged" {
bucket = "soon-unmanaged-${data.aws_caller_identity.current.account_id}"
tags = { ManagedBy = "terraform" }
}Workflow Commands
terraform init && terraform apply
# ─── state list: See everything Terraform tracks ───
terraform state list
# data.aws_caller_identity.current
# aws_s3_bucket.old_name
# aws_s3_bucket.unmanaged
# ─── state show: Inspect a specific resource ───
terraform state show aws_s3_bucket.old_name
# Shows all attributes: bucket, arn, region, tags, etc.
# ─── state mv: Rename in state (no destroy/recreate) ───
# Step 1: Rename the resource in main.tf: old_name → new_name
# Step 2: Move in state to match
terraform state mv aws_s3_bucket.old_name aws_s3_bucket.new_name
# Move "aws_s3_bucket.old_name" to "aws_s3_bucket.new_name"
# Successfully moved 1 object(s).
# Now terraform plan shows no changes (state matches config)
terraform plan # "No changes."
# ─── state rm: Stop managing a resource (keep it in AWS) ───
terraform state rm aws_s3_bucket.unmanaged
# Removed aws_s3_bucket.unmanaged
# Successfully removed 1 resource instance(s).
# The bucket still exists in AWS, but Terraform no longer tracks it
terraform state list # only shows aws_s3_bucket.new_name
# ─── state pull: Download remote state as JSON ───
terraform state pull > state-backup.json
terraform destroy# aws_s3_bucket.old_name:
resource "aws_s3_bucket" "old_name" {
arn = "arn:aws:s3:::state-cmds-demo-123456789012"
bucket = "state-cmds-demo-123456789012"
bucket_regional_domain_name = "state-cmds-demo-123456789012.s3.us-east-1.amazonaws.com"
id = "state-cmds-demo-123456789012"
region = "us-east-1"
tags = { "ManagedBy" = "terraform" }
tags_all = { "ManagedBy" = "terraform" }
}
