Terraform Basics Guide — Infrastructure as Code with HCL

Learn Terraform from scratch: write HCL, manage state, use modules, and provision cloud infrastructure safely.

What Is Terraform?

Terraform is an open-source Infrastructure as Code (IaC) tool that lets you define, provision, and manage cloud infrastructure using a declarative configuration language called HCL (HashiCorp Configuration Language). Write code once, deploy anywhere — AWS, GCP, Azure, or any provider.

Core Concepts

  • Provider — plugin that connects to a cloud/service API (aws, google, azurerm)
  • Resource — infrastructure object to manage (EC2 instance, S3 bucket, RDS database)
  • State — file that maps config to real-world resources (terraform.tfstate)
  • Module — reusable group of resources
  • Variable — input parameter for your configuration
  • Output — exported values from your configuration

Basic Terraform Configuration

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

# Create an S3 bucket
resource "aws_s3_bucket" "app_assets" {
  bucket = "my-app-assets-${var.environment}"

  tags = {
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

# Reference an existing resource
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]  # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"]
  }
}

Variables and Outputs

# variables.tf
variable "environment" {
  type        = string
  description = "Deployment environment"
  default     = "dev"
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Must be dev, staging, or prod."
  }
}

variable "aws_region" {
  type    = string
  default = "us-east-1"
}

# outputs.tf
output "bucket_name" {
  value       = aws_s3_bucket.app_assets.bucket
  description = "Name of the created S3 bucket"
}

output "bucket_arn" {
  value = aws_s3_bucket.app_assets.arn
}

The Terraform Workflow

# 1. Initialize — download providers
terraform init

# 2. Plan — preview changes
terraform plan
terraform plan -var="environment=staging"
terraform plan -out=tfplan  # save plan

# 3. Apply — create/update resources
terraform apply
terraform apply tfplan      # apply saved plan

# 4. Destroy — remove all resources
terraform destroy
terraform destroy -target=aws_s3_bucket.app_assets  # specific resource

Remote State with S3

# Store state in S3 for team collaboration
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"  # state locking
  }
}

Modules

# Using a public 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
}

Frequently Asked Questions

Should I commit terraform.tfstate to git?

No. State files can contain sensitive values. Use remote state (S3, Terraform Cloud) for team workflows and add *.tfstate to your .gitignore.

What is terraform.tfstate.backup?

Terraform creates a backup of your state before each operation. It's a safety net for recovering from bad applies.

→ Explore Free Developer Tools at DevKits
aiforeverthing.com — 100+ tools, no signup required