Terraform & IaC
Infrastructure as Code (IaC) manages cloud resources through version-controlled configuration files instead of manual console clicks. Terraform is the industry standard for multi-cloud IaC, supporting AWS, Azure, GCP with a single tool.
45 min•By Priygop Team•Last updated: Feb 2026
Terraform Essentials
- HCL (HashiCorp Configuration Language) — Describes desired infrastructure state declaratively. Terraform compares with actual state and applies changes
- terraform init — Downloads providers (AWS, Azure, GCP plugins) and initializes backend for remote state
- terraform plan — Shows what WILL change before applying. Always review plan before apply
- terraform apply — Creates/updates/destroys resources to match configuration. Generates state file
- State file (terraform.tfstate) — Tracks what Terraform has created. Store remotely (S3 + DynamoDB) in teams
- Modules — Reusable infrastructure components. module 'vpc' { source = './modules/vpc' }
- Variables & outputs — var.region for inputs, output 'instance_ip' for results. tfvars files for environments
- Workspaces — terraform workspace new staging/production for environment separation
Terraform Code
Example
# main.tf — AWS EC2 + RDS example
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "us-east-1"
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" { default = "us-east-1" }
variable "instance_type" { default = "t3.micro" }
variable "db_password" { sensitive = true }
# VPC (reusable module)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
}
# EC2 instance
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = module.vpc.public_subnets[0]
tags = { Name = "web-server", Environment = "production" }
}
# RDS database
resource "aws_db_instance" "postgres" {
engine = "postgres"
engine_version = "16.1"
instance_class = "db.t3.micro"
db_name = "myapp"
username = "admin"
password = var.db_password
subnet_group_name = aws_db_subnet_group.main.name
skip_final_snapshot = true
}
output "web_public_ip" { value = aws_instance.web.public_ip }
output "db_endpoint" { value = aws_db_instance.postgres.endpoint }