Skip to main content

Command Palette

Search for a command to run...

Step-by-Step Terraform Techniques for Deploying in Production

Updated
5 min read
Step-by-Step Terraform Techniques for Deploying in Production
H

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:


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-file for 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

CommandPurpose
terraform initInitialize backend, providers, modules.
terraform validateCheck syntax errors.
terraform plan -out=...Generate an execution plan.
terraform apply tfplanApply changes safely.
terraform workspace ...Manage isolated environments.
terraform state ...Inspect or modify state.
terraform outputExtract 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

  1. Develop: Write code → terraform fmt → PR review.

  2. Plan: terraform plan -out=tfplan -var-file=prod.tfvars.

  3. Apply: terraform apply tfplan (after approval).

  4. Monitor: Use terraform output to 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! 🚀

More from this blog

H

HarryDevOps

37 posts