Day 8: Terraform CLI Commands Deep Dive

I'm a cloud-native enthusiast and tech blogger, sharing insights on Kubernetes, AWS, CI/CD, and Linux across my blog and Facebook page. Passionate about modern infrastructure and microservices, I aim to help others understand and leverage cloud-native technologies for scalable, efficient solutions.
Welcome to Week 2! Last week you learned the fundamentals. This week we’ll dive deeper into Terraform’s powerful features. Today, we’ll master the Terraform CLI - your primary tool for infrastructure management.
🎯 Today’s Goals
Master all essential Terraform CLI commands
Learn command options and flags
Understand command workflows
Practice debugging and troubleshooting
Explore advanced CLI features
🔧 Terraform CLI Structure
terraform <command> [options] [arguments]
Example:
terraform apply -auto-approve -var="region=us-west-2"
│ │ │
Command Options Arguments
📚 Essential Commands Reference
1. init - Initialize Working Directory
# Basic initialization
terraform init
# Upgrade providers
terraform init -upgrade
# Reconfigure backend
terraform init -reconfigure
# Copy from existing backend
terraform init -migrate-state
# Skip provider plugins
terraform init -backend=false
What init does:
Downloads provider plugins
Initializes backend
Creates
.terraformdirectoryGenerates lock file
Example:
terraform init -upgrade -backend-config="bucket=my-state-bucket"
2. plan - Preview Changes
# Basic plan
terraform plan
# Save plan to file
terraform plan -out=tfplan
# Show resource changes
terraform plan -detailed-exitcode
# Target specific resources
terraform plan -target=aws_instance.web
# Refresh state before planning
terraform plan -refresh=true
# Variable passing
terraform plan -var="instance_type=t2.small"
terraform plan -var-file="production.tfvars"
Exit codes:
0 = No changes
1 = Error
2 = Successful plan with changes
Example:
terraform plan -out=production.tfplan -var-file="prod.tfvars"
3. apply - Execute Changes
# Interactive apply (prompts for confirmation)
terraform apply
# Auto-approve (skip confirmation)
terraform apply -auto-approve
# Apply saved plan
terraform apply tfplan
# Target specific resource
terraform apply -target=aws_instance.web
# Parallelism control
terraform apply -parallelism=10
# Replace specific resource
terraform apply -replace=aws_instance.web
Example:
terraform apply -auto-approve -var="environment=production"
4. destroy - Delete Infrastructure
# Interactive destroy
terraform destroy
# Auto-approve
terraform destroy -auto-approve
# Destroy specific resource
terraform destroy -target=aws_instance.web
# Destroy with variables
terraform destroy -var-file="dev.tfvars"
Example:
terraform destroy -target=aws_s3_bucket.temp -auto-approve
5. validate - Check Configuration
# Validate syntax
terraform validate
# JSON output
terraform validate -json
Checks for:
Syntax errors
Invalid resource references
Missing required arguments
Example:
terraform validate && echo "Configuration is valid!"
6. fmt - Format Code
# Format current directory
terraform fmt
# Format recursively
terraform fmt -recursive
# Check if formatting is needed
terraform fmt -check
# Show diff
terraform fmt -diff
# Write to specific file
terraform fmt main.tf
Example:
terraform fmt -recursive -diff
7. show - Display State or Plan
# Show current state
terraform show
# Show specific resource
terraform state show aws_instance.web
Example:
terraform show -json | jq '.values.root_module.resources'
8. output - Display Outputs
# Show all outputs
terraform output
# Specific output
terraform output vpc_id
# Raw output (no quotes)
terraform output -raw public_ip
# JSON format
terraform output -json
Example:
# Use output in scripts
PUBLIC_IP=$(terraform output -raw instance_public_ip)curl http://$PUBLIC_IP
10. import - Import Existing Resources
# Import resource into state
terraform import aws_instance.web i-1234567890abcdef0
# Import with variable
terraform import -var-file="prod.tfvars" aws_vpc.main vpc-12345
Example:
# First, write the resource blockresource "aws_instance" "existing" {
# ... configuration}
# Then import
terraform import aws_instance.existing i-1234567890abcdef0
🗂️ State Management Commands
11. state list - List Resources
# List all resources
terraform state list
# Filter by pattern
terraform state list | grep aws_instance
# List module resources
terraform state list module.vpc
12. state show - Display Resource
# Show resource details
terraform state show aws_instance.web
# With address
terraform state show 'aws_instance.web[0]'
13. state mv - Move Resources
# Rename resource
terraform state mv aws_instance.web aws_instance.webserver
# Move to module
terraform state mv aws_instance.web module.compute.aws_instance.web
# Move from module
terraform state mv module.old.aws_instance.web aws_instance.web
14. state rm - Remove Resources
# Remove from state (doesn't delete resource)
terraform state rm aws_instance.web
# Remove multiple
terraform state rm aws_instance.web aws_instance.db
# Remove with index
terraform state rm 'aws_subnet.public[1]'
15. state pull/push
# Download remote state
terraform state pull > backup.tfstate
# Upload state (dangerous!)
terraform state push backup.tfstate
16. force-unlock - Remove Lock
# Unlock stuck state
terraform force-unlock LOCK_ID
📊 Workspace Commands
# List workspaces
terraform workspace list
# Create workspace
terraform workspace new dev
# Switch workspace
terraform workspace select prod
# Show current workspace
terraform workspace show
# Delete workspace
terraform workspace delete dev
🔍 Advanced Commands
17. graph - Visualize Dependencies
# Generate dependency graph
terraform graph
# For planned changes
terraform graph -type=plan
# For destroy operation
terraform graph -type=plan-destroy
# Visualize with Graphviz
terraform graph | dot -Tpng > graph.png
18. providers - Show Providers
# List providers
terraform providers
# Show provider schema
terraform providers schema
# Mirror providers locally
terraform providers mirror ./providers
# Lock providers
terraform providers lock
🧪 Hands-On Lab: CLI Commands Mastery
Let’s practice all these commands!
Step 1: Create Project
mkdir terraform-cli-lab
cd terraform-cli-lab
Step 2: Create Configuration
main.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
variable "region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "instance_count" {
description = "Number of instances"
type = number
default = 2
}
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "cli-lab-vpc-${var.environment}"
Environment = var.environment
}
}
# Subnets
resource "aws_subnet" "public" {
count = var.instance_count
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "public-subnet-${count.index + 1}"
}
}
# Data source
data "aws_availability_zones" "available" {
state = "available"
}
# Outputs
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_ids" {
value = aws_subnet.public[*].id
}
output "region" {
value = var.region
}
Step 3: Practice Commands
Initialization
# Initializeterraform init
# Check what was createdls -la .terraform/
cat .terraform.lock.hcl
Validation and Formatting
# Check format
terraform fmt -check
# Format files
terraform fmt
# Validate
terraform validate
Planning
# Basic plan
terraform plan
# Plan with variables
terraform plan -var="environment=staging"
# Save plan
terraform plan -out=dev.tfplan
# View saved plan
terraform show dev.tfplan
Apply
# Apply saved plan
terraform apply dev.tfplan
# Direct apply with auto-approve
terraform apply -auto-approve -var="instance_count=3"
State Operations
# List all resources
terraform state list
# Show specific resource
terraform state show aws_vpc.main
# Show subnet with index
terraform state show 'aws_subnet.public[0]'
Outputs
# All outputs
terraform output
# Specific output
terraform output vpc_id
# Raw output for scripting
terraform output -raw region
# JSON output
terraform output -json | jq
Graph Visualization
# Generate graph
terraform graph > graph.dot
# If you have Graphviz installed:
terraform graph | dot -Tpng > infrastructure.png
Targeted Operations
# Plan specific resource
terraform plan -target=aws_subnet.public[0]
# Apply to specific resource
terraform apply -target=aws_vpc.main -auto-approve
# Destroy specific resource
terraform destroy -target='aws_subnet.public[1]' -auto-approve
Step 4: Practice State Manipulation
# Pull state for backup
terraform state pull > backup.tfstate
# List resources
terraform state list
# Move resource (rename)
terraform state mv 'aws_subnet.public[0]' aws_subnet.primary
# Show renamed resource
terraform state show aws_subnet.primary
# Move it back
terraform state mv aws_subnet.primary 'aws_subnet.public[0]'
Step 5: Workspaces
# List workspaces
terraform workspace list
# Create new workspace
terraform workspace new staging
# Switch workspaces
terraform workspace select default
terraform workspace select staging
# Deploy to staging
terraform apply -auto-approve -var="environment=staging"
# Switch back to default
terraform workspace select default
# Delete staging workspace
terraform destroy -auto-approve
# In staging workspace first
terraform workspace select default
terraform workspace delete staging
Step 6: Cleanup
terraform destroy -auto-approve
🎯 Command Cheat Sheet
Daily Commands
# Initialize project
terraform init
# Format code
terraform fmt
# Check syntax
terraform validate
# Preview changes
terraform plan
# Apply changes
terraform apply
# Show outputs
terraform output
# Delete everything
terraform destroy
Advanced
# Import existing
terraform import
# Manage workspaces
terraform workspace
# Manage providers
terraform providers
# Unlock state
terraform force-unlock
📝 CLI Best Practices
✅ DO:
Always run plan before apply
terraform plan && terraform applySave plans for review
terraform plan -out=plan.tfplan # Review the plan terraform apply plan.tfplanUse auto-approve only in automation
# In CI/CD terraform apply -auto-approveFormat before committing
terraform fmt -recursive git add . git commit -m "Formatted Terraform files"Validate regularly
terraform validate
❌ DON’T:
Don’t skip planning in production
Don’t use
auto-approveinteractivelyDon’t forget to backup before state operations
Don’t use
state pushunless absolutely necessary
🐛 Debugging Commands
# Enable debug logging
export TF_LOG=DEBUG
terraform apply
# Log to file
export TF_LOG=TRACE
export TF_LOG_PATH=./terraform.log
terraform apply
# Disable logging
unset TF_LOG
unset TF_LOG_PATH
# Crash logs
cat crash.log
Log Levels:
TRACE- Most verboseDEBUG- Debug informationINFO- General informationWARN- WarningsERROR- Errors only
📝 Summary
Today you learned:
✅ All essential Terraform CLI commands
✅ Command options and flags
✅ State management commands
✅ Workspace commands
✅ Debugging and troubleshooting
✅ CLI best practices
✅ Command workflows
🚀 Tomorrow’s Preview
Day 9: Input Variables - Types & Validation
Tomorrow we’ll:
Deep dive into variable types
Master complex variable structures
Learn advanced validation rules
Work with variable precedence
Build type-safe configurations
💭 Challenge Exercise
Create a script that:
Runs
terraform planand saves to fileChecks exit code
If changes exist (exit code 2), shows the plan
Asks for confirmation before applying
Backs up state after apply
#!/bin/bash
terraform plan -out=plan.tfplan -detailed-exitcode
EXIT_CODE=$?
if [ $EXIT_CODE -eq 2 ];
then terraform show plan.tfplan
read -p "Apply changes? (yes/no): " CONFIRM
if [ "$CONFIRM" = "yes" ];
then terraform state pull > backup.tfstate
terraform apply plan.tfplan
fi
fi
← Day 6: State Management | Day 9: Input Variables Deep Dive →
Remember: The CLI is your primary interface to Terraform. Master it!



