Types of Blocks in Terraform

terraform-learning Hands-on Terraform configs, modules, and practice projects on GitHub.

Every Terraform file is made up of blocks. Each block type serves a different purpose — here are the eight you’ll use most often.

01 terraform

Configures Terraform itself, such as the Terraform version and required providers.

terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}
02 provider

Configures the infrastructure provider.

provider "aws" {
  region = "ap-south-1"
}

Terraform supports these providers:

provider "aws" {}
provider "google" {}
provider "azurerm" {}
provider "kubernetes" {}
03 resource

Tells Terraform to create or manage infrastructure.

resource "aws_instance" "backend" {
  ami           = "ami-123456"
  instance_type = "t3.micro"
}
resource "aws_instance" "my_instance"
    │          │            │
    │          │            └── Local name (you can give it any name of your choice)
    │          └─────────────── Resource type
    └────────────────────────── Block type
04 data

Reads information from existing infrastructure instead of creating it.

data "aws_availability_zones" "available" {
  filter {
    name   = "opt-in-status"
    values = ["opt-in-not-required"]
  }
}
05 variable

Defines values that users can provide to their Terraform configuration.

variable "instance_type" {
  type        = string
  default     = "t3.micro"
  description = "EC2 instance type"
}

resource "aws_instance" "backend" {
  instance_type = var.instance_type
}
06 locals

Creates reusable values inside a Terraform configuration.

locals {
  project_name = "taskify"
  environment  = "production"
}

resource "aws_s3_bucket" "uploads" {
  bucket = "${local.project_name}-uploads"
}

Syntax difference between variable and locals:

variable → var.instance_type
local    → local.project_name
07 output

Returns information you want to print after infrastructure is created.

output "instance_public_ip" {
  value = aws_instance.backend.public_ip
}
08 module

Lets you reuse existing configuration.

module "vpc" {
  source = "./modules/vpc"

  vpc_cidr = "10.0.0.0/16"
}

A module can come from a local path or a public registry.

Local:

module "vpc" {
  source = "./modules/vpc"

  vpc_cidr = "10.0.0.0/16"
}

Public registry:

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 21.0"

  name               = "example"
  kubernetes_version = "1.33"

  tags = {
    Environment = "dev"
    Terraform   = "true"
  }
}