Skip to main content

Command Palette

Search for a command to run...

Day 8: Terraform CLI Commands Deep Dive

Updated
8 min read
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 .terraform directory

  • Generates 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:

  1. Always run plan before apply

     terraform plan && terraform apply
    
  2. Save plans for review

     terraform plan -out=plan.tfplan
    
     # Review the plan
     terraform apply plan.tfplan
    
  3. Use auto-approve only in automation

     # In CI/CD
     terraform apply -auto-approve
    
  4. Format before committing

     terraform fmt -recursive
     git add .
     git commit -m "Formatted Terraform files"
    
  5. Validate regularly

     terraform validate
    

DON’T:

  1. Don’t skip planning in production

  2. Don’t use auto-approve interactively

  3. Don’t forget to backup before state operations

  4. Don’t use state push unless 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 verbose

  • DEBUG - Debug information

  • INFO - General information

  • WARN - Warnings

  • ERROR - 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:

  1. Runs terraform plan and saves to file

  2. Checks exit code

  3. If changes exist (exit code 2), shows the plan

  4. Asks for confirmation before applying

  5. 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!

More from this blog

S

StackOps - Diary

33 posts

Welcome to the StackOps - Diary. We’re dedicated to empowering the tech community. We delve into cloud-native and microservices technologies, sharing knowledge to build modern, scalable solutions.