Infrastructure as Code (IaC) has transformed how we manage cloud resources. Instead of clicking through web consoles, you define your infrastructure in code that can be versioned, reviewed, and automated. Terraform by HashiCorp is the most popular IaC tool, supporting hundreds of cloud providers and services.
Why Terraform?
- Multi-cloud: Works with AWS, Azure, GCP, and 3000+ providers
- Declarative: You describe what you want, Terraform figures out how to get there
- State management: Tracks the real state of your infrastructure
- Plan before apply: Preview changes before making them
- Modular: Reuse infrastructure patterns with modules
Installation
# Ubuntu/Debian
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# Verify
terraform version
Your First Terraform Configuration
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-west-1"
}
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
Environment = "production"
}
}
output "public_ip" {
value = aws_instance.web_server.public_ip
}
Terraform Workflow
# Initialize - download providers
terraform init
# Format code
terraform fmt
# Validate configuration
terraform validate
# Preview changes
terraform plan
# Apply changes
terraform apply
# Destroy resources
terraform destroy
Variables and Outputs
# variables.tf
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}
variable "environment" {
description = "Deployment environment"
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "Environment must be dev, staging, or production."
}
}
# terraform.tfvars
instance_type = "t3.small"
environment = "production"
State Management
# Remote state backend (recommended for teams)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Modules
# modules/vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
tags = { Name = var.name }
}
# Root main.tf
module "production_vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
name = "production"
}
Best Practices
- Always use remote state with locking
- Never commit
.tfstatefiles to version control - Use
terraform planbefore everyapply - Organize code with modules for reusability
- Pin provider versions to avoid surprises
- Use workspaces or separate state files per environment
- Tag all resources for cost tracking
- Implement CI/CD for Terraform with plan review
Terraform transforms infrastructure management from a manual, error-prone process into a reliable, repeatable practice. Start small with a single resource and gradually build up your Infrastructure as Code skills.