What is Terraform?
Terraform is an infrastructure-as-code tool that enables you to safely and predictably create, change, and improve infrastructure.
Basic Syntax
hcl
# main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}Variables
hcl
# variables.tf
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
variable "environment" {
description = "Environment name"
type = string
}
# terraform.tfvars
instance_type = "t2.micro"
environment = "production"Outputs
hcl
# outputs.tf
output "instance_public_ip" {
description = "Public IP of the EC2 instance"
value = aws_instance.web.public_ip
}
output "instance_id" {
description = "ID of the EC2 instance"
value = aws_instance.web.id
}VPC Configuration
hcl
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "us-east-1a"
tags = {
Name = "public-subnet"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-gateway"
}
}Security Groups
hcl
resource "aws_security_group" "web" {
name = "web-sg"
description = "Allow web traffic"
vpc_id = aws_vpc.main.id
ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "SSH"
from_port = 22
to_port = 22
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"]
}
}Load Balancer
hcl
resource "aws_lb" "web" {
name = "web-lb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.web.id]
subnets = aws_subnet.public[*].id
tags = {
Environment = "production"
}
}
resource "aws_lb_target_group" "web" {
name = "web-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
path = "/"
interval = 30
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
}RDS Database
hcl
resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "postgres"
engine_version = "14.7"
instance_class = "db.t2.micro"
db_name = "mydb"
username = "admin"
password = var.db_password
parameter_group_name = "default.postgres14"
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.main.name
}
resource "aws_db_subnet_group" "main" {
name = "main-db-subnet-group"
subnet_ids = aws_subnet.private[*].id
tags = {
Name = "My DB subnet group"
}
}S3 Bucket
hcl
resource "aws_s3_bucket" "assets" {
bucket = "my-app-assets"
tags = {
Name = "Assets Bucket"
}
}
resource "aws_s3_bucket_versioning" "assets" {
bucket = aws_s3_bucket.assets.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_website_configuration" "assets" {
bucket = aws_s3_bucket.assets.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}Modules
hcl
# Using modules
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
environment = "production"
}
module "ec2" {
source = "./modules/ec2"
instance_count = 3
instance_type = "t2.micro"
subnet_ids = module.vpc.public_subnet_ids
}State Management
hcl
# Backend configuration
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}Commands
bash
# Initialize
terraform init
# Format code
terraform fmt
# Validate
terraform validate
# Plan changes
terraform plan
# Apply changes
terraform apply
# Destroy resources
terraform destroy
# Import existing resources
terraform import aws_instance.web i-1234567890Best Practices
- 1Use version control: Track Terraform code in git
- 2Remote state: Store state remotely
- 3State locking: Prevent concurrent modifications
- 4Use modules: Reuse infrastructure code
- 5Separate environments: Dev, staging, production
- 6Tag resources: Organize and track costs
- 7Validate plans: Always review before applying
- 8Use variables: Make code reusable
Conclusion
Terraform enables infrastructure as code, making infrastructure management predictable and efficient.