Step-by-Step Terraform Techniques for Deploying in Production

I'm an IT professional and business analyst, sharing my day-to-day troubleshooting challenges to help others gain practical experience while exploring the latest technology trends and DevOps practices. My goal is to create a space for exchanging ideas, discussing solutions, and staying updated with evolving tech practices.
Introduction
Terraform has become the go-to Infrastructure-as-Code (IaC) tool for automating cloud resources, but using it in production requires a well-structured workflow. A robust Terraform lifecycle ensures scalability, security, and consistency in infrastructure management. This blog explores the essential phases of a production Terraform workflow, offering best practices and key commands for each stage.
Production Terraform Lifecycle Phases
1. Code Authoring & Development
Goal: Define infrastructure as code (IaC) using modules, variables, and providers.
Key Commands:
terraform init # Initialize a new Terraform config
terraform validate # Validate syntax
terraform fmt # Format code
Best Practices:
Use versioned modules (e.g.,
source = "git::https://github.com/...?ref=v1.2.0").Separate environments using workspaces or directory structures.
2. Initialization
Goal: Download providers, modules, and set up the backend.
Command:
terraform init \
-backend-config="bucket=my-tf-state" \
-backend-config="key=prod/network.tfstate"
Backend Types:
Remote Storage: S3, GCS, Azure Blob.
Terraform Cloud/Enterprise:
backend "remote" {
hostname = "app.terraform.io"
organization = "my-org"
workspaces { name = "prod-network" }
}
3. Planning
Goal: Preview changes before applying.
Command:
terraform plan -out=tfplan # Save plan to a file
Best Practices:
Automate plan checks in CI/CD pipelines.
Use
-var-filefor environment-specific variables:
terraform plan -var-file="prod.tfvars"
4. Review & Collaboration
Tools:
Pull Requests (PRs): Code reviews for IaC changes.
Policy Enforcement: Sentinel (Terraform Enterprise) or Open Policy Agent (OPA).
Cost Estimation: Tools like Infracost.
5. Applying Changes
Goal: Safely apply approved infrastructure changes.
Command:
terraform apply tfplan # Apply a saved plan
Best Practices:
Use state locking (e.g., DynamoDB for S3 backend) to prevent conflicts.
Destroy resources cautiously:
terraform destroy -target=aws_instance.example
6. State Management
Goal: Securely store and audit infrastructure state.
Key Commands:
terraform state list # List resources in state
terraform state rm aws_s3_bucket.old_bucket # Remove a resource from state
terraform import aws_instance.my_server i-1234567890abcdef0 # Import existing resources into state
Security:
Encrypt state files (e.g., AWS S3 + KMS).
Restrict access using IAM policies.
7. Drift Detection & Remediation
Goal: Identify and fix deviations from the desired state.
Commands:
terraform refresh # Refresh state against real infrastructure
terraform plan # Compare refreshed state with code
Automation: Schedule periodic plan jobs to detect drift.
8. Versioning & Dependency Management
Goal: Manage Terraform and provider versions.
Code Snippet:
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
9. Workspaces & Environment Separation
Goal: Isolate prod/dev/staging environments.
Commands:
terraform workspace new prod # Create a workspace for prod
terraform workspace select prod # Switch workspaces
Alternative: Directory-based separation:
├── prod
│ ├── main.tf
│ └── variables.tf
└── dev
├── main.tf
└── variables.tf
10. Outputs & Integration
Goal: Share outputs with other systems (e.g., Kubernetes, CI/CD).
Code:
output "vpc_id" {
value = aws_vpc.main.id
}
Command:
terraform output -json > outputs.json
Key Terraform Commands Cheat Sheet
| Command | Purpose |
terraform init | Initialize backend, providers, modules. |
terraform validate | Check syntax errors. |
terraform plan -out=... | Generate an execution plan. |
terraform apply tfplan | Apply changes safely. |
terraform workspace ... | Manage isolated environments. |
terraform state ... | Inspect or modify state. |
terraform output | Extract outputs for integration. |
Best Practices for Production
Remote State: Use S3/Azure Blob/GCS with versioning and encryption.
Locking: Enable state locking (DynamoDB for AWS).
Modularize: Reuse code with versioned modules.
Least Privilege: Restrict IAM roles for Terraform.
CI/CD Integration: Automate plan and apply via GitHub Actions, GitLab CI, etc.
Policy as Code: Enforce guardrails with Sentinel/OPA.
Example Terraform Workflow
Develop: Write code →
terraform fmt→ PR review.Plan:
terraform plan -out=tfplan -var-file=prod.tfvars.Apply:
terraform apply tfplan(after approval).Monitor: Use
terraform outputto pass VPC IDs to Kubernetes.
Example : Production-Level Terraform Project
Provider Configuration
terraform {
required_version = ">= 1.5.0"
backend "s3" {
bucket = "my-tf-state"
key = "prod/network.tfstate"
region = "ap-south-1"
encrypt = true dynamodb_table = "terraform-lock"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-south-1"
}
VPC Module
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "prod-vpc"
cidr = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
Security Group
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP and SSH"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22 to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
EC2 Instance
resource "aws_instance" "web" {
ami = "ami-12345678" # Replace with a real
AMI instance_type = "t3.medium"
security_groups = [aws_security_group.web_sg.name]
tags = {
Name = "prod-web-server"
}
}
Outputs
output "vpc_id" {
value = module.vpc.vpc_id
}
output "instance_ip" {
value = aws_instance.web.public_ip
}
Tools to Enhance Production Workflows
Terragrunt: Reduce Terraform boilerplate.
Atlantis: PR automation for Terraform.
Checkov: Static analysis for security.
Spacelift: Managed IaC platform.
Conclusion
A well-structured Terraform workflow in production ensures reliability, auditability, and collaboration. By following best practices like remote state management, CI/CD integration, and policy enforcement, teams can maintain secure, scalable, and efficient infrastructure. As Terraform evolves, staying updated with automation tools and best practices will further optimize infrastructure management. Happy Terraforming! 🚀




