Terraform is the industry-standard Infrastructure as Code tool by HashiCorp — define your entire cloud infrastructure in declarative config files, version it in Git, and deploy with one command.
Why Terraform?
- Multi-cloud — AWS, GCP, Azure, DigitalOcean, Cloudflare, 3000+ providers
- Declarative — describe the desired state, Terraform figures out how to get there
- Plan before apply — preview changes before executing them
- State management — tracks what exists vs what you want
- Modules — reusable infrastructure components
- Free and open source — OpenTofu fork also available
Quick Start
# Install
brew install terraform
# or
curl -fsSL https://releases.hashicorp.com/terraform/1.9.0/terraform_1.9.0_linux_amd64.zip -o tf.zip && unzip tf.zip
terraform --version
Your First Infrastructure
# main.tf — Deploy a web server on AWS
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = { Name = "my-vpc" }
}
# Subnet
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
}
# Security group
resource "aws_security_group" "web" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EC2 instance
resource "aws_instance" "web" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
echo "Hello from Terraform!" > /var/www/html/index.html
EOF
tags = { Name = "web-server" }
}
output "public_ip" {
value = aws_instance.web.public_ip
}
terraform init # Download providers
terraform plan # Preview changes
terraform apply # Create infrastructure
terraform destroy # Tear everything down
Variables and Outputs
# variables.tf
variable "environment" {
type = string
default = "staging"
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "Must be dev, staging, or production."
}
}
variable "instance_count" {
type = number
default = 2
}
variable "allowed_ips" {
type = list(string)
default = ["0.0.0.0/0"]
}
# terraform.tfvars
environment = "production"
instance_count = 3
allowed_ips = ["203.0.113.0/24", "198.51.100.0/24"]
Modules (Reusable Infrastructure)
# modules/web-app/main.tf
variable "name" { type = string }
variable "instance_type" { default = "t3.micro" }
variable "min_size" { default = 1 }
variable "max_size" { default = 3 }
resource "aws_launch_template" "app" {
name_prefix = var.name
image_id = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
}
resource "aws_autoscaling_group" "app" {
name = "${var.name}-asg"
min_size = var.min_size
max_size = var.max_size
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
}
# Usage
module "api" {
source = "./modules/web-app"
name = "api"
instance_type = "t3.small"
min_size = 2
max_size = 10
}
module "worker" {
source = "./modules/web-app"
name = "worker"
instance_type = "t3.medium"
min_size = 1
max_size = 5
}
Remote State (Team Collaboration)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Terraform vs Pulumi vs CloudFormation vs CDK
| Feature | Terraform | Pulumi | CloudFormation | CDK |
|---|---|---|---|---|
| Language | HCL | Any (TS, Python, Go) | YAML/JSON | TypeScript |
| Multi-cloud | Yes (3000+ providers) | Yes | AWS only | AWS only |
| State | Self-managed/Cloud | Pulumi Cloud | AWS-managed | AWS-managed |
| Plan | terraform plan | pulumi preview | Change sets | cdk diff |
| Community | Largest | Growing | AWS only | AWS only |
| Learning | HCL (easy) | Your language | YAML (verbose) | TypeScript |
| Cost | Free (OSS) | Free tier | Free | Free |
Need to scrape data from any website and get it in structured JSON? Check out my web scraping tools on Apify — no coding required, results in minutes.
Have a custom data extraction project? Email me at spinov001@gmail.com — I build tailored scraping solutions for businesses.
Top comments (0)