Skip to Content
32 CheatsheetsCloudTerraform Commands Cheatsheet

Terraform Commands - Complete Cheatsheet

Master Terraform for Infrastructure as Code (IaC) - From basics to advanced enterprise usage


1. Initialization & Setup Commands

Command 1: Initialize Terraform working directory

terraform init

Command 2: Initialize with backend configuration

terraform init -backend-config="bucket=my-tf-state"

Command 3: Initialize and upgrade provider versions

terraform init -upgrade

Command 4: Initialize without backend

terraform init -backend=false

Command 5: Reconfigure backend

terraform init -reconfigure

Command 6: Migrate state to new backend

terraform init -migrate-state

Command 7: Initialize with specific plugin directory

terraform init -plugin-dir=/path/to/plugins

2. Planning Commands

Command 8: Create execution plan

terraform plan

Command 9: Save plan to file

terraform plan -out=tfplan

Command 10: Plan with variable file

terraform plan -var-file="prod.tfvars"

Command 11: Plan with inline variable

terraform plan -var="instance_type=t3.large"

Command 12: Plan for specific resource

terraform plan -target=aws_instance.web

Command 13: Plan with detailed output

terraform plan -json

Command 14: Plan with refresh disabled

terraform plan -refresh=false

Command 15: Plan and show resource addresses

terraform plan -no-color | grep "^[[:space:]]*[#~+-]"

Command 16: Show saved plan

terraform show tfplan

Command 17: Show plan in JSON format

terraform show -json tfplan

3. Apply & Deployment Commands

Command 18: Apply changes

terraform apply

Command 19: Apply without confirmation prompt

terraform apply -auto-approve

Command 20: Apply from saved plan

terraform apply tfplan

Command 21: Apply with variable file

terraform apply -var-file="prod.tfvars"

Command 22: Apply specific resource only

terraform apply -target=aws_instance.web

Command 23: Apply with parallelism limit

terraform apply -parallelism=10

Command 24: Apply and refresh state

terraform apply -refresh-only

4. Destroy Commands

Command 25: Destroy all resources

terraform destroy

Command 26: Destroy without confirmation

terraform destroy -auto-approve

Command 27: Destroy specific resource

terraform destroy -target=aws_instance.web

Command 28: Destroy with variable file

terraform destroy -var-file="prod.tfvars"

Command 29: Plan destroy (preview)

terraform plan -destroy

5. State Management Commands

Command 30: List resources in state

terraform state list

Command 31: Show specific resource in state

terraform state show aws_instance.web

Command 32: Move resource in state

terraform state mv aws_instance.web aws_instance.web_server

Command 33: Remove resource from state

terraform state rm aws_instance.web

Command 34: Pull remote state

terraform state pull

Command 35: Push local state to remote

terraform state push terraform.tfstate

Command 36: Replace provider in state

terraform state replace-provider hashicorp/aws registry.terraform.io/hashicorp/aws

Command 37: Backup state file

cp terraform.tfstate terraform.tfstate.backup

6. State Refresh & Sync

Use refresh-only plan and apply flows instead of the deprecated terraform refresh command.

Command 38: Preview refresh-only changes

terraform plan -refresh-only

Command 39: Apply refresh-only changes with variable file

terraform apply -refresh-only -var-file="prod.tfvars"

Command 40: Sync state without applying changes

terraform apply -refresh-only -auto-approve

7. Output Commands

Command 41: Show all outputs

terraform output

Command 42: Show specific output

terraform output instance_ip

Command 43: Show output in JSON

terraform output -json

Command 44: Show output raw value (no quotes)

terraform output -raw public_key

8. Validation & Formatting

Command 45: Validate configuration

terraform validate

Command 46: Format configuration files

terraform fmt

Command 47: Format and show diff

terraform fmt -diff

Command 48: Format recursively

terraform fmt -recursive

Command 49: Check formatting without changes

terraform fmt -check

9. Workspace Commands

Command 50: List workspaces

terraform workspace list

Command 51: Create new workspace

terraform workspace new dev

Command 52: Select workspace

terraform workspace select prod

Command 53: Show current workspace

terraform workspace show

Command 54: Delete workspace

terraform workspace delete dev

10. Import Commands

Command 55: Import existing resource

terraform import aws_instance.web i-1234567890abcdef0

Command 56: Import with variable file

terraform import -var-file="prod.tfvars" aws_instance.web i-1234567890abcdef0

Command 57: Import to specific state file

terraform import -state=path/to/terraform.tfstate aws_instance.web i-1234567890abcdef0

11. Taint & Untaint Commands

Command 58: Taint resource (mark for recreation)

terraform taint aws_instance.web

Command 59: Untaint resource

terraform untaint aws_instance.web

Command 60: Taint resource in module

terraform taint module.vpc.aws_subnet.private

12. Graph & Visualization

Command 61: Generate dependency graph

terraform graph

Command 62: Generate graph and create image

terraform graph | dot -Tpng > graph.png

Command 63: Graph with plan operation

terraform graph -type=plan

13. Provider Commands

Command 64: Show provider requirements

terraform providers

Command 65: Show provider schemas

terraform providers schema

Command 66: Lock provider versions

terraform providers lock

Command 67: Mirror providers locally

terraform providers mirror /path/to/mirror

14. Console & Testing

Command 68: Interactive console

terraform console

Command 69: Test expression in console

echo "var.instance_type" | terraform console

Command 70: Evaluate output expression

echo "aws_instance.web.public_ip" | terraform console

15. Version & Help

Command 71: Show Terraform version

terraform version

Command 72: Show detailed version info

terraform version -json

Command 73: Get help for command

terraform plan -help

Command 74: List all commands

terraform -help

16. Advanced State Operations

Command 75: Force unlock state

terraform force-unlock <lock-id>

Command 76: Show state file version

terraform state pull | jq '.version'

Command 77: List all resource addresses

terraform state list | sort

Command 78: Export state to JSON

terraform state pull > state.json

Command 79: Get specific attribute from state

terraform state show -json aws_instance.web | jq '.values.public_ip'

17. Environment Variables

Command 80: Set log level

export TF_LOG=DEBUG terraform apply

Command 81: Save logs to file

export TF_LOG_PATH=./terraform.log export TF_LOG=TRACE terraform apply

Command 82: Set variable via environment

export TF_VAR_instance_type=t3.large terraform plan

Command 83: Set credentials via environment

export AWS_ACCESS_KEY_ID="your-access-key" export AWS_SECRET_ACCESS_KEY="your-secret-key" terraform apply

Command 84: Disable color output

export TF_CLI_ARGS="-no-color" terraform plan

18. Testing & Validation (Terraform Test)

Command 85: Run Terraform tests

terraform test

Command 86: Run tests with specific filter

terraform test -filter=test_instance

Command 87: Run tests with variable file

terraform test -var-file="test.tfvars"

19. Configuration Management

Command 88: Get specific value from configuration

terraform console > var.region

Command 89: List all variables

grep -r "variable" *.tf

Command 90: Show required variables

terraform validate 2>&1 | grep "var."

20. Remote Operations

Command 91: Force remote execution

terraform apply -lock=true -lock-timeout=5m

Command 92: Run with specific backend config

terraform plan -backend-config="key=prod/terraform.tfstate"

21. Module Commands

Command 93: Get/update modules

terraform get

Command 94: Update modules to latest version

terraform get -update

Command 95: Initialize and get modules

terraform init -get=true

22. Login & Cloud Integration

Command 96: Login to Terraform Cloud

terraform login

Command 97: Logout from Terraform Cloud

terraform logout

23. Show & Inspect

Command 98: Show current state

terraform show

Command 99: Show in JSON format

terraform show -json

Command 100: Show specific resource

terraform state show aws_instance.web

24. Replace & Recreate

Command 101: Replace resource

terraform apply -replace=aws_instance.web

Command 102: Replace multiple resources

terraform apply -replace=aws_instance.web -replace=aws_instance.db

25. Metadata & Debugging

Command 103: Enable crash log

export TF_LOG_CORE=TRACE export TF_LOG_PROVIDER=TRACE terraform apply

Command 104: Validate JSON syntax

terraform providers schema -json | jq .

Command 105: Check for circular dependencies

terraform graph | grep -i cycle

Advanced Terraform Concepts

State Locking

Command 106: Disable state locking

terraform apply -lock=false

Command 107: Set lock timeout

terraform apply -lock-timeout=10m

Partial Configuration

Command 108: Apply with partial backend config

terraform init \ -backend-config="bucket=my-bucket" \ -backend-config="key=terraform.tfstate" \ -backend-config="region=us-east-1"

Parallelism Control

Command 109: Limit concurrent operations

terraform apply -parallelism=5

Command 110: Disable parallelism

terraform apply -parallelism=1

Interview Q&A Scenarios

Scenario 1: State file is corrupted or locked

# Check lock status cat .terraform/terraform.tfstate # Force unlock (use with caution!) terraform force-unlock <lock-id> # Pull state from remote terraform state pull > backup.tfstate # If corrupted, restore from backup terraform state push backup.tfstate # Re-initialize if needed terraform init -reconfigure

Scenario 2: Need to import existing infrastructure

# Step 1: Write configuration for the resource cat > main.tf &lt;<EOF resource "aws_instance" "web" { # Configuration will be populated after import lifecycle { prevent_destroy = false } } EOF # Step 2: Import the resource terraform import aws_instance.web i-1234567890abcdef0 # Step 3: Get current state terraform state show aws_instance.web # Step 4: Update configuration to match state # Step 5: Plan to verify no changes terraform plan

Scenario 3: Move resources between modules

# Move resource from one module to another terraform state mv module.old.aws_instance.web module.new.aws_instance.web # Verify the move terraform plan # Should show no changes

Scenario 4: Resource drift detected

# Detect drift terraform plan -refresh-only # Sync state with actual infrastructure terraform apply -refresh-only # Or fix the drift by reapplying terraform apply

Scenario 5: Upgrade Terraform version

# Step 1: Backup state terraform state pull > pre-upgrade-state.json # Step 2: Upgrade Terraform binary # (download new version) # Step 3: Upgrade provider versions terraform init -upgrade # Step 4: Verify with plan terraform plan # Step 5: Test in non-prod first terraform workspace select dev terraform plan

Scenario 6: Multiple environments (workspaces vs directories)

# Option 1: Workspaces terraform workspace new prod terraform workspace new staging terraform workspace select prod terraform apply -var-file=prod.tfvars # Option 2: Directories (preferred for different backends) cd environments/prod terraform init -backend-config=backend-prod.hcl terraform apply

Scenario 7: Sensitive data in state

# Mark outputs as sensitive output "db_password" { value = random_password.db.result sensitive = true } # Enable encryption at rest for remote backend terraform { backend "s3" { bucket = "my-tf-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/abcd1234" dynamodb_table = "terraform-locks" } } # Never commit state files to git echo "*.tfstate" >> .gitignore echo "*.tfstate.*" >> .gitignore

Scenario 8: Stuck in a pending state

# Check for locks terraform force-unlock <lock-id> # If remote backend, check backend storage # For S3: aws s3 ls s3://my-tf-state-bucket/ # For Azure: az storage blob list --account-name mystorageaccount --container-name tfstate # Verify state file integrity terraform state pull | jq .

Terraform Best Practices

1. State Management Best Practices

Always use remote state for teams

terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" } }

Enable state locking

  • S3 backend: Use DynamoDB table
  • Azure: Built-in locking
  • GCS: Built-in locking

Enable versioning on state bucket

aws s3api put-bucket-versioning \ --bucket my-terraform-state \ --versioning-configuration Status=Enabled

Never commit state files

# .gitignore *.tfstate *.tfstate.* .terraform/ *.tfvars # if contains secrets

2. Code Organization Best Practices

Use modules for reusability

module "vpc" { source = "./modules/vpc" version = "1.0.0" cidr_block = var.vpc_cidr environment = var.environment }

Separate environments properly

terraform/ ├── modules/ │ ├── vpc/ │ ├── eks/ │ └── rds/ ├── environments/ │ ├── dev/ │ │ ├── main.tf │ │ ├── variables.tf │ │ ├── outputs.tf │ │ └── terraform.tfvars │ ├── staging/ │ └── prod/ └── global/ └── iam/

Use consistent naming conventions

# Resource naming resource "aws_instance" "web_server" { # snake_case tags = { Name = "web-server-${var.environment}" # kebab-case for AWS Environment = var.environment ManagedBy = "Terraform" } }

3. Security Best Practices

1. Never hardcode credentials

# Bad provider "aws" { access_key = "AKIAIOSFODNN7EXAMPLE" secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" } # Good - use environment variables or IAM roles provider "aws" { region = var.aws_region }

2. Mark sensitive variables

variable "db_password" { type = string sensitive = true } output "db_password" { value = var.db_password sensitive = true }

3. Use data encryption

resource "aws_db_instance" "main" { storage_encrypted = true kms_key_id = aws_kms_key.db.arn }

4. Implement least privilege

resource "aws_iam_role_policy" "example" { role = aws_iam_role.example.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = ["ec2:DescribeInstances"] Resource = "*" } ] }) }

5. Enable deletion protection

resource "aws_db_instance" "production" { deletion_protection = true lifecycle { prevent_destroy = true } }

4. Version Control Best Practices

Pin provider versions

terraform { required_version = ">= 1.6.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" # Allow patch updates only } } }

Use version constraints wisely

# Pessimistic constraint (recommended) version = "~> 1.0" # >= 1.0, &lt; 2.0 # Exact version (most restrictive) version = "1.2.3" # Greater than version = ">= 1.0" # Range version = ">= 1.0, &lt; 2.0"

5. Performance Best Practices

Use depends_on sparingly

# Terraform usually auto-detects dependencies # Use depends_on only when needed resource "aws_instance" "web" { depends_on = [aws_security_group.web] }

Limit parallelism for API rate limits

terraform apply -parallelism=5

Use count vs for_each appropriately

# for_each - better for managing individual resources resource "aws_instance" "web" { for_each = toset(["web-1", "web-2", "web-3"]) tags = { Name = each.key } } # count - simpler for identical resources resource "aws_instance" "app" { count = 3 tags = { Name = "app-${count.index}" } }

6. Testing Best Practices

Validate before applying

terraform validate terraform fmt -check terraform plan

Use terraform test (Terraform 1.6+)

# tests/main.tftest.hcl run "verify_instance_type" { assert { condition = aws_instance.web.instance_type == "t3.micro" error_message = "Instance type must be t3.micro" } }

Implement pre-commit hooks

# .pre-commit-config.yaml repos: - repo: https://github.com/antonbabenko/pre-commit-terraform rev: v1.83.0 hooks: - id: terraform_fmt - id: terraform_validate - id: terraform_docs

7. Documentation Best Practices

Document variables

variable "instance_type" { description = "EC2 instance type for web servers" type = string default = "t3.micro" validation { condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type) error_message = "Instance type must be t3.micro, t3.small, or t3.medium." } }

Use meaningful outputs

output "web_server_public_ip" { description = "Public IP address of the web server" value = aws_instance.web.public_ip }

Add README with examples

# VPC Module ## Usage ```hcl module "vpc" { source = "./modules/vpc" cidr_block = "10.0.0.0/16" environment = "production" }
### 8. CI/CD Best Practices **Implement automated planning** ```yaml # GitHub Actions example - name: Terraform Plan run: | terraform init terraform plan -out=tfplan - name: Save Plan uses: actions/upload-artifact@v4 with: name: tfplan path: tfplan

Require approvals for applies

- name: Terraform Apply if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve tfplan environment: production

Use Terraform Cloud/Enterprise for teams

  • Remote state management
  • Policy as code (Sentinel)
  • Private module registry
  • Cost estimation
  • Audit logs

Common Pitfalls & Solutions

Pitfall 1: Not using remote state

Problem: Team members overwrite each other’s changes
Solution: Use remote backend with locking

terraform { backend "s3" { bucket = "terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" } }

Pitfall 2: Hardcoding values

Problem: Configuration not reusable, copying errors
Solution: Use variables and tfvars files

# variables.tf variable "instance_type" { type = string } # prod.tfvars instance_type = "t3.large"

Pitfall 3: Not using modules

Problem: Code duplication, inconsistent configurations
Solution: Create reusable modules

module "vpc" { source = "./modules/vpc" cidr = var.vpc_cidr }

Pitfall 4: Ignoring state file security

Problem: Sensitive data exposed in state
Solution: Encrypt state, use sensitive variables

variable "db_password" { sensitive = true }

Pitfall 5: Not pinning versions

Problem: Breaking changes from provider updates
Solution: Pin provider versions

required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }

Pitfall 6: Destroying production by mistake

Problem: Accidental terraform destroy
Solution: Use lifecycle prevent_destroy

resource "aws_db_instance" "prod" { lifecycle { prevent_destroy = true } }

Pitfall 7: Not validating input

Problem: Invalid configurations deployed
Solution: Use variable validation

variable "environment" { validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "Environment must be dev, staging, or prod." } }

Pitfall 8: Monolithic configuration

Problem: Hard to manage, slow planning
Solution: Split into multiple state files

environments/ ├── networking/ ├── compute/ ├── database/ └── security/

Pitfall 9: Not using .gitignore

Problem: Committing sensitive state files
Solution: Proper .gitignore

*.tfstate *.tfstate.* .terraform/ .terraform.lock.hcl # optional *.tfvars # if contains secrets

Pitfall 10: No testing before prod

Problem: Breaking changes in production
Solution: Use workspaces or separate directories

terraform workspace select staging terraform plan terraform apply # Test thoroughly terraform workspace select prod terraform apply

Key Differences (Interview Questions)

terraform plan vs terraform apply

Featureplanapply
PurposePreview changesExecute changes
State modificationNoYes
Resource creationNoYes
Safe to runAlwaysOnly when ready
OutputExecution planApplied changes

count vs for_each

Featurecountfor_each
Input typeNumberSet or map
AddressingIndex (0, 1, 2)Key/value
Resource removalRisky (shifts indexes)Safe (by key)
Best forIdentical resourcesNamed resources
# count - index-based resource "aws_instance" "app" { count = 3 # Accessed as aws_instance.app[0] } # for_each - key-based (preferred) resource "aws_instance" "web" { for_each = toset(["web-1", "web-2"]) # Accessed as aws_instance.web["web-1"] }

Variables vs Locals

FeatureVariablesLocals
InputExternal (CLI, tfvars)Internal calculation
OverrideYesNo
UsageUser-provided valuesComputed values
# Variable - user input variable "environment" { type = string } # Local - computed locals { common_tags = { Environment = var.environment ManagedBy = "Terraform" } }

terraform import vs writing config

ApproachImportWrite Config
SpeedFastSlower
AccuracyRequires manual configIntentional design
Use caseExisting infrastructureNew infrastructure

Workspaces vs Directories

FeatureWorkspacesDirectories
Same backendYesNo
State isolationSeparate stateCompletely separate
Code reuseYesVia modules
Best forSimple env differencesComplex environments
# Workspaces - same backend, different state terraform workspace new prod terraform workspace new staging # Directories - separate backends cd environments/prod terraform init -backend-config=backend-prod.hcl

Modules vs Resources

FeatureModulesResources
PurposeGrouping & reuseIndividual components
InstancesCan create multipleOne per block
VersioningYesN/A
SourceLocal or registryProvider

Data Sources vs Resources

FeatureData SourceResource
PurposeRead existingCreate new
Modifies infraNoYes
Namingdata.type.nameresource.type.name
# Data source - read existing data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] } # Resource - create new resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id }

terraform taint vs -replace

Featuretaint (deprecated)-replace
Terraform version< 1.0>= 0.15.2
ApproachMark then applyApply with flag
RecommendedNoYes
# Old way (deprecated) terraform taint aws_instance.web terraform apply # New way (preferred) terraform apply -replace=aws_instance.web

Production-Ready Terraform Structure

terraform-infrastructure/ ├── .gitignore ├── README.md ├── versions.tf # Terraform & provider versions ├── main.tf # Main configuration ├── variables.tf # Input variables ├── outputs.tf # Output values ├── locals.tf # Local values ├── data.tf # Data sources ├── terraform.tfvars # Default values (non-sensitive) ├── backend.tf # Backend configuration ├── modules/ │ ├── vpc/ │ │ ├── main.tf │ │ ├── variables.tf │ │ ├── outputs.tf │ │ └── README.md │ ├── eks/ │ ├── rds/ │ └── security-group/ ├── environments/ │ ├── dev/ │ │ ├── main.tf │ │ ├── variables.tf │ │ ├── terraform.tfvars │ │ └── backend.hcl │ ├── staging/ │ └── prod/ │ ├── main.tf │ ├── variables.tf │ ├── prod.tfvars │ ├── backend.hcl │ └── README.md └── tests/ ├── main.tftest.hcl └── integration/

Complete Example: Production VPC Module

modules/vpc/versions.tf

terraform { required_version = ">= 1.6.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }

modules/vpc/variables.tf

variable "environment" { description = "Environment name (dev, staging, prod)" type = string validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "Environment must be dev, staging, or prod." } } variable "vpc_cidr" { description = "CIDR block for VPC" type = string validation { condition = can(cidrhost(var.vpc_cidr, 0)) error_message = "Must be a valid IPv4 CIDR block." } } variable "availability_zones" { description = "List of availability zones" type = list(string) default = ["us-east-1a", "us-east-1b", "us-east-1c"] } variable "private_subnet_cidrs" { description = "CIDR blocks for private subnets" type = list(string) } variable "public_subnet_cidrs" { description = "CIDR blocks for public subnets" type = list(string) } variable "enable_nat_gateway" { description = "Enable NAT Gateway for private subnets" type = bool default = true } variable "single_nat_gateway" { description = "Use single NAT Gateway for all private subnets" type = bool default = false } variable "tags" { description = "Additional tags for resources" type = map(string) default = {} }

modules/vpc/main.tf

locals { common_tags = merge( var.tags, { Environment = var.environment ManagedBy = "Terraform" Module = "vpc" } ) } # VPC resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true tags = merge( local.common_tags, { Name = "${var.environment}-vpc" } ) } # Internet Gateway resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = merge( local.common_tags, { Name = "${var.environment}-igw" } ) } # Public Subnets resource "aws_subnet" "public" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.public_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index] map_public_ip_on_launch = true tags = merge( local.common_tags, { Name = "${var.environment}-public-subnet-${count.index + 1}" Type = "public" } ) } # Private Subnets resource "aws_subnet" "private" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.private_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index] tags = merge( local.common_tags, { Name = "${var.environment}-private-subnet-${count.index + 1}" Type = "private" } ) } # Elastic IPs for NAT Gateways resource "aws_eip" "nat" { count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.private_subnet_cidrs)) : 0 domain = "vpc" tags = merge( local.common_tags, { Name = "${var.environment}-nat-eip-${count.index + 1}" } ) depends_on = [aws_internet_gateway.main] } # NAT Gateways resource "aws_nat_gateway" "main" { count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.private_subnet_cidrs)) : 0 allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id tags = merge( local.common_tags, { Name = "${var.environment}-nat-${count.index + 1}" } ) depends_on = [aws_internet_gateway.main] } # Public Route Table resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id tags = merge( local.common_tags, { Name = "${var.environment}-public-rt" Type = "public" } ) } # Public Route resource "aws_route" "public_internet_gateway" { route_table_id = aws_route_table.public.id destination_cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } # Public Route Table Associations resource "aws_route_table_association" "public" { count = length(var.public_subnet_cidrs) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id } # Private Route Tables resource "aws_route_table" "private" { count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.private_subnet_cidrs)) : length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id tags = merge( local.common_tags, { Name = "${var.environment}-private-rt-${count.index + 1}" Type = "private" } ) } # Private Routes to NAT Gateway resource "aws_route" "private_nat_gateway" { count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.private_subnet_cidrs)) : 0 route_table_id = aws_route_table.private[count.index].id destination_cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.main[count.index].id } # Private Route Table Associations resource "aws_route_table_association" "private" { count = length(var.private_subnet_cidrs) subnet_id = aws_subnet.private[count.index].id route_table_id = var.single_nat_gateway ? aws_route_table.private[0].id : aws_route_table.private[count.index].id } # VPC Flow Logs resource "aws_flow_log" "main" { iam_role_arn = aws_iam_role.flow_log.arn log_destination = aws_cloudwatch_log_group.flow_log.arn traffic_type = "ALL" vpc_id = aws_vpc.main.id tags = merge( local.common_tags, { Name = "${var.environment}-vpc-flow-log" } ) } resource "aws_cloudwatch_log_group" "flow_log" { name = "/aws/vpc/${var.environment}" retention_in_days = 30 tags = local.common_tags } resource "aws_iam_role" "flow_log" { name = "${var.environment}-vpc-flow-log-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "vpc-flow-logs.amazonaws.com" } } ] }) tags = local.common_tags } resource "aws_iam_role_policy" "flow_log" { name = "${var.environment}-vpc-flow-log-policy" role = aws_iam_role.flow_log.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ] Effect = "Allow" Resource = "*" } ] }) }

modules/vpc/outputs.tf

output "vpc_id" { description = "ID of the VPC" value = aws_vpc.main.id } output "vpc_cidr" { description = "CIDR block of the VPC" value = aws_vpc.main.cidr_block } output "public_subnet_ids" { description = "IDs of public subnets" value = aws_subnet.public[*].id } output "private_subnet_ids" { description = "IDs of private subnets" value = aws_subnet.private[*].id } output "nat_gateway_ids" { description = "IDs of NAT Gateways" value = aws_nat_gateway.main[*].id } output "internet_gateway_id" { description = "ID of Internet Gateway" value = aws_internet_gateway.main.id }

environments/prod/main.tf

terraform { required_version = ">= 1.6.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } backend "s3" {} # Configuration in backend.hcl } provider "aws" { region = var.aws_region default_tags { tags = { Environment = "production" Project = "my-project" ManagedBy = "Terraform" CostCenter = "engineering" } } } module "vpc" { source = "../../modules/vpc" environment = var.environment vpc_cidr = var.vpc_cidr availability_zones = var.availability_zones public_subnet_cidrs = var.public_subnet_cidrs private_subnet_cidrs = var.private_subnet_cidrs enable_nat_gateway = true single_nat_gateway = false tags = var.additional_tags }

environments/prod/backend.hcl

bucket = "my-terraform-state-prod" key = "prod/vpc/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-state-lock-prod" kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/abc-def-ghi"

environments/prod/prod.tfvars

aws_region = "us-east-1" environment = "prod" vpc_cidr = "10.0.0.0/16" availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"] public_subnet_cidrs = [ "10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24" ] private_subnet_cidrs = [ "10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24" ] additional_tags = { Owner = "platform-team" CostCenter = "engineering" Compliance = "pci" }

.gitignore

# Local .terraform directories **/.terraform/* # .tfstate files *.tfstate *.tfstate.* # Crash log files crash.log crash.*.log # Exclude all .tfvars files (if they contain secrets) *.tfvars *.tfvars.json # Ignore override files override.tf override.tf.json *_override.tf *_override.tf.json # Include example tfvars !example.tfvars # Ignore CLI configuration files .terraformrc terraform.rc # Ignore plan files *.tfplan # Ignore lock files (optional) .terraform.lock.hcl

Advanced Terraform Patterns

1. Dynamic Blocks

resource "aws_security_group" "web" { name = "web-sg" vpc_id = var.vpc_id dynamic "ingress" { for_each = var.ingress_rules content { from_port = ingress.value.port to_port = ingress.value.port protocol = "tcp" cidr_blocks = ingress.value.cidr_blocks } } }

2. Conditional Resources

resource "aws_instance" "web" { count = var.create_instance ? 1 : 0 ami = var.ami_id instance_type = var.instance_type }

3. Data Lookups

data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] } }

4. Remote State Data Sources

data "terraform_remote_state" "vpc" { backend = "s3" config = { bucket = "my-terraform-state" key = "vpc/terraform.tfstate" region = "us-east-1" } } resource "aws_instance" "app" { subnet_id = data.terraform_remote_state.vpc.outputs.private_subnet_ids[0] }

5. Provider Aliases

provider "aws" { alias = "us_east_1" region = "us-east-1" } provider "aws" { alias = "us_west_2" region = "us-west-2" } resource "aws_instance" "east" { provider = aws.us_east_1 } resource "aws_instance" "west" { provider = aws.us_west_2 }


26. Drift Detection & Management

Command 111: Detect configuration drift

terraform plan -refresh-only

Command 112: Show drift in detail

terraform plan -refresh-only -out=drift.tfplan terraform show drift.tfplan

Command 113: Apply refresh to sync state

terraform apply -refresh-only -auto-approve

Command 114: Compare state with actual resources

terraform state pull | jq '.resources[] | {type: .type, name: .name}'

27. Multi-Cloud Commands

Command 115: Set multiple provider credentials

# AWS export AWS_PROFILE=production export AWS_DEFAULT_REGION=us-east-1 # Azure export ARM_SUBSCRIPTION_ID="xxx" export ARM_TENANT_ID="xxx" export ARM_CLIENT_ID="xxx" export ARM_CLIENT_SECRET="xxx" # GCP export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json" export GOOGLE_PROJECT="my-project-id" terraform plan

Command 116: Initialize with multiple providers

terraform init

Command 117: Plan multi-cloud deployment

terraform plan -out=multi-cloud.tfplan

28. Import Block (Terraform 1.5+)

Command 118: Import with import block

# main.tf import { to = aws_instance.web id = "i-1234567890abcdef0" } resource "aws_instance" "web" { # Configuration }
terraform plan -generate-config-out=generated.tf terraform apply

Command 119: Import multiple resources

import { to = aws_instance.web1 id = "i-111111111" } import { to = aws_instance.web2 id = "i-222222222" }

Command 120: Generate config from import

terraform plan -generate-config-out=imported.tf

29. Check Blocks (Terraform 1.5+)

Command 121: Add runtime assertions

check "health_check" { data "http" "example" { url = "https://${aws_instance.web.public_ip}" } assert { condition = data.http.example.status_code == 200 error_message = "Website is not responding" } }

Command 122: Validate with check blocks

terraform plan # Runs checks terraform apply # Runs checks again

30. Moved Blocks (Refactoring)

Command 123: Rename resource without recreation

moved { from = aws_instance.web to = aws_instance.web_server }

Command 124: Move to module

moved { from = aws_instance.web to = module.web.aws_instance.main }

Command 125: Verify moved block

terraform plan # Should show no changes

31. Removed Blocks (Terraform 1.7+)

Command 126: Remove from state without destroying

removed { from = aws_instance.old_server lifecycle { destroy = false } }

Command 127: Remove and destroy

removed { from = aws_instance.temporary lifecycle { destroy = true } }

32. Advanced Debugging

Command 128: Enable detailed logging

export TF_LOG=TRACE export TF_LOG_CORE=DEBUG export TF_LOG_PROVIDER=TRACE export TF_LOG_PATH=./terraform-debug.log terraform apply

Command 129: Debug specific operation

TF_LOG=DEBUG terraform plan 2>&1 | tee plan-debug.log

Command 130: Trace provider API calls

export TF_LOG_PROVIDER=TRACE terraform apply -auto-approve

Command 131: Debug state locking issues

export TF_LOG=DEBUG terraform apply 2>&1 | grep -i "lock"

Command 132: Inspect provider plugin cache

ls -la ~/.terraform.d/plugin-cache/ terraform providers

33. Performance Optimization

Command 133: Reduce parallelism for rate limiting

terraform apply -parallelism=3

Command 134: Optimize for large states

terraform plan -target=module.specific_module

Command 135: Skip provider validation

terraform init -backend=false -get=false -verify-plugins=false

Command 136: Use compact warnings

terraform apply -compact-warnings

34. State Backup & Recovery

Command 137: Create state backup

terraform state pull > "backup-$(date +%Y%m%d-%H%M%S).tfstate"

Command 138: Restore from backup

terraform state push backup-20240101-120000.tfstate

Command 139: Compare state files

diff &lt;(terraform state pull | jq -S .) &lt;(cat backup.tfstate | jq -S .)

Command 140: Export state for migration

terraform state pull | jq '.resources' > resources.json

35. Credential & Secret Management

Command 141: Use AWS SSM Parameter Store

data "aws_ssm_parameter" "db_password" { name = "/prod/db/password" with_decryption = true } resource "aws_db_instance" "main" { password = data.aws_ssm_parameter.db_password.value }

Command 142: Use Azure Key Vault

data "azurerm_key_vault_secret" "db_password" { name = "db-password" key_vault_id = data.azurerm_key_vault.main.id }

Command 143: Use HashiCorp Vault

data "vault_generic_secret" "db_creds" { path = "secret/database/prod" } resource "aws_db_instance" "main" { username = data.vault_generic_secret.db_creds.data["username"] password = data.vault_generic_secret.db_creds.data["password"] }

36. Resource Targeting

Command 144: Target module

terraform apply -target=module.vpc

Command 145: Target multiple resources

terraform apply \ -target=aws_instance.web \ -target=aws_security_group.web

Command 146: Target resource in module

terraform apply -target=module.eks.aws_eks_cluster.main

Command 147: Destroy specific module

terraform destroy -target=module.old_infrastructure

37. JSON Configuration

Command 148: Write config in JSON

# main.tf.json { "resource": { "aws_instance": { "web": { "ami": "ami-12345678", "instance_type": "t3.micro" } } } }

Command 149: Validate JSON configuration

terraform validate

Command 150: Convert HCL to JSON

# No native command, use tools like hcl2json

38. Private Module Registry

Command 151: Use Terraform Cloud registry

module "vpc" { source = "app.terraform.io/my-org/vpc/aws" version = "1.0.0" }

Command 152: Authenticate to private registry

terraform login app.terraform.io

Command 153: Publish module to registry

# Tag version in Git git tag v1.0.0 git push origin v1.0.0 # Registry auto-publishes

39. Override Files

Command 154: Create override file for development

# override.tf resource "aws_instance" "web" { instance_type = "t2.micro" # Override for dev }

Command 155: Use multiple override files

# Terraform automatically loads: # - override.tf # - override.tf.json # - *_override.tf # - *_override.tf.json

40. External Data Sources

Command 156: Call external program

data "external" "example" { program = ["python3", "${path.module}/script.py"] query = { environment = var.environment } } output "result" { value = data.external.example.result }

Command 157: Use template file

data "template_file" "user_data" { template = file("${path.module}/user_data.sh") vars = { environment = var.environment region = var.region } }

41. Null Resources & Provisioners

Command 158: Trigger on changes

resource "null_resource" "example" { triggers = { always_run = timestamp() } provisioner "local-exec" { command = "echo 'Resource updated'" } }

Command 159: Remote execution

resource "aws_instance" "web" { # ... provisioner "remote-exec" { inline = [ "sudo apt-get update", "sudo apt-get install -y nginx" ] connection { type = "ssh" user = "ubuntu" private_key = file("~/.ssh/id_rsa") host = self.public_ip } } }

Command 160: File provisioner

resource "aws_instance" "web" { # ... provisioner "file" { source = "app.conf" destination = "/etc/app/app.conf" connection { type = "ssh" user = "ubuntu" host = self.public_ip } } }

42. Terraform Cloud / Enterprise

Command 161: Configure Terraform Cloud backend

terraform { cloud { organization = "my-org" workspaces { name = "production" } } }

Command 162: Use multiple workspaces

terraform { cloud { organization = "my-org" workspaces { tags = ["production", "us-east-1"] } } }

Command 163: Run remote operations

terraform init terraform plan # Runs in Terraform Cloud

Command 164: Force local execution

terraform plan -lock=false

43. Cost Estimation

Command 165: Estimate costs (Terraform Cloud)

terraform plan # Cost estimate appears in Terraform Cloud UI

Command 166: Use Infracost (open source)

infracost breakdown --path . infracost diff --path .

44. Compliance & Policy

Command 167: Sentinel policy (Terraform Enterprise)

# Policy file import "tfplan/v2" as tfplan main = rule { all tfplan.resource_changes as _, rc { rc.type is "aws_instance" implies rc.change.after.instance_type in ["t3.micro", "t3.small"] } }

Command 168: OPA policy with Terraform

terraform plan -out=tfplan.binary terraform show -json tfplan.binary > tfplan.json opa eval --data policy.rego --input tfplan.json "data.terraform.deny"

45. Advanced Import Scenarios

Command 169: Import AWS VPC and subnets

# Import VPC terraform import aws_vpc.main vpc-12345678 # Import subnets terraform import aws_subnet.public[0] subnet-11111111 terraform import aws_subnet.public[1] subnet-22222222 terraform import aws_subnet.private[0] subnet-33333333

Command 170: Import with for_each

# For resources created with for_each terraform import 'aws_instance.web["web-1"]' i-1234567890abcdef0 terraform import 'aws_instance.web["web-2"]' i-0987654321fedcba0

Command 171: Import Azure resources

terraform import azurerm_resource_group.main /subscriptions/{subscription-id}/resourceGroups/{resource-group-name} terraform import azurerm_virtual_network.main /subscriptions/{subscription-id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet-name}

Command 172: Import GCP resources

terraform import google_compute_instance.main projects/{project}/zones/{zone}/instances/{instance-name} terraform import google_compute_network.vpc projects/{project}/global/networks/{network-name}

46. State Migration Scenarios

Command 173: Migrate from local to S3

# Step 1: Add backend configuration cat >> backend.tf &lt;<EOF terraform { backend "s3" { bucket = "my-tf-state" key = "prod/terraform.tfstate" region = "us-east-1" } } EOF # Step 2: Migrate terraform init -migrate-state

Command 174: Migrate between S3 buckets

# Update backend configuration terraform init -migrate-state -backend-config="bucket=new-bucket"

Command 175: Migrate from Terraform Cloud to S3

# Update backend from cloud to s3 terraform init -migrate-state

47. Module Development

Command 176: Initialize module

mkdir -p modules/my-module cd modules/my-module cat > main.tf cat > variables.tf cat > outputs.tf cat > README.md cat > versions.tf

Command 177: Test module locally

cd examples/basic terraform init terraform plan

Command 178: Validate module

terraform validate terraform fmt -check -recursive

Command 179: Generate module documentation

terraform-docs markdown . > README.md

48. GitOps Workflows

Command 180: Automated plan on PR

# .github/workflows/terraform-plan.yml name: Terraform Plan on: [pull_request] jobs: plan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v2 - run: terraform init - run: terraform plan -no-color

Command 181: Automated apply on merge

# .github/workflows/terraform-apply.yml name: Terraform Apply on: push: branches: [main] jobs: apply: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v2 - run: terraform init - run: terraform apply -auto-approve

49. Local Values & Functions

Command 182: Use built-in functions

echo 'upper("hello")' | terraform console # Output: HELLO echo 'cidrsubnet("10.0.0.0/16", 8, 1)' | terraform console # Output: 10.0.1.0/24 echo 'jsondecode("{\"key\": \"value\"}")' | terraform console # Output: {"key" = "value"}

Command 183: Test conditional expressions

echo 'var.environment == "prod" ? "t3.large" : "t3.micro"' | terraform console

Command 184: Evaluate complex expressions

cat > test.tf &lt;<EOF locals { subnets = { public = cidrsubnet(var.vpc_cidr, 8, 1) private = cidrsubnet(var.vpc_cidr, 8, 2) } } output "test" { value = local.subnets } EOF echo 'local.subnets' | terraform console

50. Terraform Aliases (Productivity)

Command 185: Create shell aliases

# Add to ~/.bashrc or ~/.zshrc alias tf='terraform' alias tfi='terraform init' alias tfp='terraform plan' alias tfa='terraform apply' alias tfd='terraform destroy' alias tfo='terraform output' alias tfs='terraform state' alias tfsl='terraform state list' alias tfss='terraform state show' alias tfv='terraform validate' alias tff='terraform fmt' alias tfiu='terraform init -upgrade' alias tfpn='terraform plan -out=tfplan' alias tfan='terraform apply tfplan' alias tfaa='terraform apply -auto-approve' alias tfda='terraform destroy -auto-approve' alias tfws='terraform workspace' alias tfwl='terraform workspace list' alias tfwn='terraform workspace new' alias tfws='terraform workspace select'

Command 186: Advanced aliases with functions

# Terraform plan and save tfps() { terraform plan -out="tfplan-$(date +%Y%m%d-%H%M%S)" } # Terraform apply from latest plan tfal() { local latest_plan=$(ls -t tfplan-* | head -1) terraform apply "$latest_plan" } # Terraform state backup tfsb() { terraform state pull > "state-backup-$(date +%Y%m%d-%H%M%S).tfstate" } # Terraform import interactive tfii() { echo "Resource address (e.g., aws_instance.web):" read resource_address echo "Resource ID:" read resource_id terraform import "$resource_address" "$resource_id" }

51. Remote State Locking Deep Dive

Command 187: Configure DynamoDB for S3 locking

resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-state-locks" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID" attribute { name = "LockID" type = "S" } tags = { Name = "Terraform State Lock Table" } }

Command 188: Manually check lock status

# For S3 backend with DynamoDB aws dynamodb get-item \ --table-name terraform-state-locks \ --key '{"LockID": {"S": "my-bucket/prod/terraform.tfstate-md5"}}'

Command 189: Clear stuck lock

# Get lock ID from error message terraform force-unlock <lock-id> # Or delete from DynamoDB (dangerous!) aws dynamodb delete-item \ --table-name terraform-state-locks \ --key '{"LockID": {"S": "<lock-id>"}}'

52. Experimental Features

Command 190: Enable experimental features

terraform { experiments = [module_variable_optional_attrs] }

Command 191: Use optional attributes

variable "server_config" { type = object({ name = string size = optional(string, "t3.micro") tags = optional(map(string), {}) }) }

53. Replace & Dependency Management

Command 192: Replace resource with dependencies

# This will also recreate dependent resources terraform apply -replace=aws_security_group.web

Command 193: Show resource dependencies

terraform graph | grep aws_instance.web

Command 194: Create explicit dependency

resource "aws_instance" "web" { # ... depends_on = [aws_security_group.web] }

54. Meta-arguments

Command 195: Use lifecycle meta-argument

resource "aws_instance" "web" { # ... lifecycle { create_before_destroy = true prevent_destroy = true ignore_changes = [tags] } }

Command 196: Use timeouts

resource "aws_db_instance" "example" { # ... timeouts { create = "60m" update = "60m" delete = "2h" } }

55. Terraform Backends Comparison

Command 197: S3 Backend (AWS)

terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" kms_key_id = "arn:aws:kms:..." } }

Command 198: Azure Backend

terraform { backend "azurerm" { resource_group_name = "terraform-rg" storage_account_name = "tfstate" container_name = "tfstate" key = "prod.terraform.tfstate" } }

Command 199: GCS Backend (GCP)

terraform { backend "gcs" { bucket = "my-terraform-state" prefix = "prod" } }

Command 200: Terraform Cloud Backend

terraform { cloud { organization = "my-org" workspaces { name = "production" } } }

Bonus: Troubleshooting Commands

Command 201: Check Terraform installation

terraform version which terraform terraform -version -json

Command 202: Verify provider installation

ls -la .terraform/providers/ terraform providers schema -json | jq '.provider_schemas | keys'

Command 203: Test provider connectivity

# AWS aws sts get-caller-identity # Azure az account show # GCP gcloud auth list gcloud config list

Command 204: Debug graph generation

terraform graph | dot -Tsvg > graph.svg open graph.svg

Command 205: Clean and reinitialize

rm -rf .terraform .terraform.lock.hcl terraform init -upgrade

Command 206: Compact state file

# State files can grow large with many operations terraform state pull | jq -c > compact-state.tfstate terraform state push compact-state.tfstate

Practice Directory: ./terraform/
Related Folders: aks/, eks/, gke/

Interview Topics Covered: ✅ 200+ Terraform commands across 55+ categories
✅ State management (local & remote)
✅ Workspaces for environment management
✅ Import existing infrastructure (AWS, Azure, GCP)
✅ Module development & usage
✅ Remote backends (S3, Azure, GCS, Terraform Cloud)
✅ Provider version management
✅ Drift detection & management
✅ Multi-cloud deployments (AWS + Azure + GCP)
Latest Terraform 1.5-1.7 features (import blocks, check blocks, moved blocks, removed blocks)
Interview Q&A scenarios (8 real-world problems)
Best practices (state, security, code organization, testing, CI/CD)
Common pitfalls & solutions (10 critical mistakes)
Key differences (plan vs apply, count vs for_each, workspaces vs directories)
Production-ready VPC module (complete 400+ line example with flow logs, NAT, security)
Advanced patterns (dynamic blocks, conditionals, remote state, for_each, functions)
GitOps integration (GitHub Actions examples)
Security practices (KMS encryption, secrets management, Vault integration)
Cost estimation (Terraform Cloud, Infracost)
Policy as Code (Sentinel, OPA)
Productivity aliases (30+ shell aliases and functions)

Modern Terraform Features (1.5-1.7):

  • ✅ terraform test framework
  • ✅ import blocks (declarative imports)
  • ✅ check blocks (runtime assertions)
  • ✅ moved blocks (refactoring without recreation)
  • ✅ removed blocks (state-only removal)
  • ✅ -replace flag (taint replacement)
  • ✅ -generate-config-out (auto-generate configs from imports)
  • ✅ Native variable validation
  • ✅ Optional object type attributes
  • ✅ Sensitive values protection
  • ✅ Enhanced provider functions
  • ✅ Improved JSON output

Cloud Provider Coverage:

  • ☁️ AWS: EC2, VPC, S3, RDS, EKS, IAM, DynamoDB, CloudWatch
  • ☁️ Azure: Resource Groups, VNet, AKS, Key Vault, Storage
  • ☁️ GCP: Compute Engine, VPC, GKE, Cloud Storage

Complete Workflow Coverage:

  1. ✅ Initialization & Setup (7 commands)
  2. ✅ Planning & Preview (10 commands)
  3. ✅ Apply & Deployment (7 commands)
  4. ✅ Destroy Operations (5 commands)
  5. ✅ State Management (40+ commands)
  6. ✅ Import Strategies (15+ commands)
  7. ✅ Module Development (10+ commands)
  8. ✅ Testing & Validation (8+ commands)
  9. ✅ Debugging & Troubleshooting (15+ commands)
  10. ✅ CI/CD Integration (5+ commands)
Last updated on