Day 8: Terraform CLI Commands Deep Dive

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!



