State Management¶
Overview¶
This document covers Terraform state management including backends, locking, import, and state commands. State management accounts for 15% of the exam (Domain 7) and is one of the most critical topics, as state is the foundation of how Terraform tracks and manages infrastructure.
π State Overview - Terraform state documentation
Purpose of State¶
Why Terraform Uses State¶
- Resource mapping: Maps configuration resources to real-world infrastructure objects
- Metadata tracking: Stores resource dependencies and provider information
- Performance: Caches resource attributes to avoid unnecessary API calls
- Collaboration: Enables teams to share infrastructure state
State File Contents¶
- JSON format by default
- Contains:
- Terraform version
- Serial number (incremented on each change)
- Resource instances with attributes
- Provider configurations
- Output values
- Dependencies between resources
π Purpose of State - Why state is needed
Sensitive Data in State¶
- State files may contain sensitive data (passwords, keys, tokens)
- Local state is stored in plaintext JSON
- Always use remote backends with encryption for production
- Never commit state files to version control
- Use
sensitive = trueon outputs (hides from CLI but still in state)
π Sensitive Data in State - Handling sensitive state data
Local State¶
Default Behavior¶
- State stored in
terraform.tfstatein the working directory - Previous state saved as
terraform.tfstate.backup - No locking mechanism
- Suitable only for individual use, not team collaboration
- No encryption at rest
Local Backend Configuration¶
terraform {
backend "local" {
path = "relative/path/to/terraform.tfstate"
}
}
Remote Backends¶
Why Remote Backends?¶
- Collaboration: Multiple team members can access shared state
- Locking: Prevent concurrent modifications
- Encryption: State encrypted at rest and in transit
- Versioning: State history and rollback capabilities
- Security: Centralized access control
S3 Backend (AWS)¶
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "project/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
- State stored in S3 bucket
- Locking requires DynamoDB table (S3 alone does not provide locking)
- Server-side encryption with SSE-S3 or SSE-KMS
- Versioning recommended on the S3 bucket
π S3 Backend - AWS S3 backend configuration
GCS Backend (Google Cloud)¶
terraform {
backend "gcs" {
bucket = "my-terraform-state"
prefix = "project/state"
}
}
- Built-in state locking
- Built-in encryption
- Object versioning support
Azure Blob Backend¶
terraform {
backend "azurerm" {
resource_group_name = "tfstate-rg"
storage_account_name = "tfstateaccount"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
- Built-in state locking via blob leases
- Built-in encryption
Consul Backend¶
terraform {
backend "consul" {
address = "consul.example.com:8500"
scheme = "https"
path = "full/path"
}
}
- Built-in state locking
- Optional encryption
π Backend Configuration - Backend types and configuration π Remote State - Remote state overview
Terraform Cloud Backend¶
terraform {
cloud {
organization = "my-org"
workspaces {
name = "my-workspace"
}
}
}
- Built-in locking, encryption, and versioning
- Remote execution capability
- Team access controls
- The
cloudblock replaces the olderremotebackend
π Terraform Cloud Configuration - Cloud integration setup
Backend Comparison¶
| Backend | Locking | Encryption | Notes |
|---|---|---|---|
| Local | No | No | Default, single user only |
| S3 | DynamoDB required | SSE (configurable) | Most common AWS backend |
| GCS | Built-in | Built-in | Most common GCP backend |
| Azure Blob | Built-in (blob lease) | Built-in | Most common Azure backend |
| Consul | Built-in | Optional | HashiCorp service |
| Terraform Cloud | Built-in | Built-in | Recommended for teams |
State Locking¶
How Locking Works¶
- Prevents concurrent state modifications
- Automatically acquired during operations that write state
- Automatically released when operation completes
- Prevents race conditions in team environments
Locked Operations¶
terraform applyterraform destroyterraform plan(acquires read lock)terraform statesubcommands that modify state
Force Unlock¶
terraform force-unlock <LOCK_ID>
π State Locking - State locking mechanism
State Commands¶
terraform state list¶
# List all resources in state
terraform state list
# Filter by resource type
terraform state list aws_instance
# Filter by module
terraform state list module.vpc
terraform state show¶
# Show detailed information about a resource
terraform state show aws_instance.web
# Show a specific indexed resource
terraform state show 'aws_instance.web[0]'
terraform state mv¶
# Rename a resource (update state without destroying/recreating)
terraform state mv aws_instance.old aws_instance.new
# Move resource into a module
terraform state mv aws_instance.web module.app.aws_instance.web
# Move between state files
terraform state mv -state-out=other.tfstate aws_instance.web aws_instance.web
terraform state rm¶
# Remove resource from state (does not destroy the actual resource)
terraform state rm aws_instance.web
# Remove an indexed resource
terraform state rm 'aws_instance.web[0]'
terraform state pull / push¶
# Pull remote state to stdout
terraform state pull
# Push local state to remote backend
terraform state push terraform.tfstate
π State Commands - State CLI reference
Backend Migration¶
Migrating Between Backends¶
# Change backend configuration in terraform block, then:
terraform init -migrate-state
- Terraform detects backend change during init
- Prompts to migrate existing state to new backend
-migrate-stateexplicitly requests migration-reconfigurediscards existing state (use with caution)
Migration Scenarios¶
- Local to S3: Add S3 backend config, run
terraform init -migrate-state - S3 to Terraform Cloud: Change to cloud block, run
terraform init -migrate-state - Backend to backend: Update backend config, run
terraform init -migrate-state
Terraform Import¶
CLI Import¶
terraform import aws_instance.web i-1234567890abcdef0
- Imports one resource at a time
- Requires corresponding resource block in configuration
- Does not generate configuration (you must write it)
- Resource ID format varies by resource type
π Import Command - Import CLI reference
Import Block (Terraform 1.5+)¶
import {
to = aws_instance.web
id = "i-1234567890abcdef0"
}
- Declarative approach to importing
- Can generate configuration with
terraform plan -generate-config-out=generated.tf - Supports multiple imports in a single operation
- Preview with
terraform plan
π Import Block - Import block configuration
Import Key Points (Exam)¶
- Import only adds to state - does not create cloud resources
- Import does not automatically generate configuration
- Configuration must match the imported resource exactly
- Run
terraform planafter import to verify no changes - Import block is the modern approach (1.5+), CLI import is legacy
Terraform Refresh¶
Behavior¶
- Updates state to match real-world infrastructure
- Detects drift from manual changes
- Does not modify infrastructure
- Deprecated as standalone command - use
terraform plan -refresh-only
# Modern approach
terraform plan -refresh-only
terraform apply -refresh-only
π Refresh Command - Refresh behavior (deprecated)
Remote State Data Source¶
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "vpc/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_instance" "web" {
subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id
}
- Read output values from another Terraform state
- Enables cross-project references
- Read-only access to the remote state
π Remote State Data Source - Cross-project state references
Key Exam Points¶
High-Priority Topics¶
- S3 backend requires DynamoDB for locking (not S3 alone)
terraform refreshis deprecated - useplan -refresh-onlyterraform importdoes not generate configuration- State file contains sensitive data and must be secured
terraform state rmremoves from state but does not destroy resources-migrate-statevs-reconfigureduring backend changes- Remote state data source for cross-project references
- The
cloudblock replaces theremotebackend for Terraform Cloud