Terraform Explained for Beginners: Infrastructure as Code, Providers, Resources, State and Variables
If you have worked with AWS, you may have created resources by opening the AWS Console, selecting options, clicking buttons, and waiting for AWS to finish creating each resource.
This works, but imagine having to create the same infrastructure again and again.
You would have to remember:
- Which VPC to create
- Which subnet to create
- Which route table to use
- Which Internet Gateway to attach
- Which security group to configure
- Which region to use
- Which settings were changed last time
This is where Terraform becomes useful.
Instead of manually creating infrastructure through the AWS Console, we can describe the infrastructure in code.
Terraform lets us describe the infrastructure we want, and Terraform works with the cloud provider to create or change that infrastructure.
The notes for this article introduce Terraform through exactly this problem: replacing manual AWS Console operations with Infrastructure as Code.
1. What Is Terraform?
Terraform is an Infrastructure as Code (IaC) tool.
The basic idea is:
Terraform Configuration
↓
Terraform
↓
AWS Provider
↓
AWS API
↓
AWS Resources
Instead of manually clicking:
AWS Console
↓
Create VPC
↓
Create Subnet
↓
Create Route Table
↓
Create Internet Gateway
we write the desired infrastructure in Terraform configuration files.
The notes summarize the concept as:
Write instructions
↓
Terraform reads them
↓
Terraform calls AWS API
↓
AWS creates/changes resources
and explain that Terraform uses .tf files for its configuration.
2. What Is Infrastructure as Code?
Infrastructure as Code means:
We define infrastructure using code instead of creating everything manually.
For example, instead of clicking through the AWS Console to create a VPC, we can write:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Now the infrastructure configuration is stored as a file.
This has an important advantage:
Terraform files
↓
Git
↓
Version History
Because .tf files are plain text, they can be stored in Git.
You can then see:
- What changed
- Who changed it
- When it changed
- Why it changed
The notes specifically highlight storing Terraform configuration in Git for version history and tracking changes.
3. Terraform Is Declarative
This is one of the most important Terraform concepts.
Terraform is a declarative Infrastructure as Code tool.
Let’s understand what that means.
Imperative Approach
In an imperative approach, you tell the system exactly what steps to perform.
For example:
1. Create VPC
2. Wait for VPC
3. Create subnet
4. Wait for subnet
5. Create Internet Gateway
6. Attach Internet Gateway to VPC
You are describing how to do something step by step.
The notes illustrate this using operations such as:
CreateVpc()
WaitUntilVpcCreated()
CreateSubnet()
WaitUntilSubnetCreated()
CreateInternetGateway()
AttachInternetGatewayToVPC()
4. Declarative Approach
Terraform works differently.
Instead of saying:
“Create the VPC first, then wait, then create the subnet.”
we say:
“I want this VPC and this subnet to exist.”
Terraform determines what needs to happen.
For example:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
We are not explicitly writing:
Call AWS API
Wait
Check status
Call another API
We are describing the desired state.
The notes emphasize this distinction: Terraform doesn’t require us to specify what happens first, what happens second, when to wait, or which API to call.
5. Desired State
This is the easiest way to understand Terraform.
Suppose you write:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
You are saying:
I want an AWS VPC with this configuration to exist.
You are not necessarily saying:
“Create a VPC every time.”
This distinction is very important.
The notes explicitly point out that a resource block doesn’t simply mean “CREATE this resource.”
It means:
This resource should exist.
Terraform checks the current state and determines what action is required.
6. Terraform Architecture
Now let’s understand what happens internally.
A simplified Terraform architecture looks like this:
.tf Files
│
↓
┌───────────────┐
│ Terraform Core│
└───────┬───────┘
│
↓
Provider Plugin Interface
│ │ │
↓ ↓ ↓
AWS Azure Google
Provider Provider Provider
│ │ │
↓ ↓ ↓
AWS API Azure API Google API
│ │ │
↓ ↓ ↓
Resources Resources Resources
The diagram in the notes shows Terraform Core communicating through a Provider Plugin Interface with provider plugins for AWS, Azure, and Google.
7. Terraform Core
Terraform Core is responsible for important Terraform operations.
According to the notes, Terraform Core:
- Reads and parses
.tffiles. - Validates the syntax.
- Creates a dependency graph.
- Uses the state information.
- Generates a plan.
Let’s understand these one by one.
8. Terraform Reads the .tf Files
Terraform first reads your configuration files.
For example:
main.tf
variables.tf
outputs.tf
The files contain Terraform configuration.
Terraform needs to understand what resources and settings you’ve defined.
9. Terraform Validates the Configuration
Terraform also validates the configuration.
For example, it can detect syntax problems such as:
Missing bracket
Duplicate blocks
Invalid configuration
The notes specifically mention syntax validation such as missing brackets and duplicate blocks.
This is useful because Terraform can catch configuration problems before attempting to create infrastructure.
10. Dependency Graph
Terraform also creates a dependency graph.
Why?
Because resources can depend on other resources.
For example:
VPC
↓
Subnet
↓
EC2
An EC2 instance may depend on a subnet.
A subnet depends on the VPC.
Terraform can use these relationships to determine the appropriate order for operations.
The notes specifically mention creating a dependency graph to figure out the order.
11. What Is Terraform State?
One of Terraform’s most important concepts is state.
Terraform maintains information about infrastructure using a state file, commonly:
terraform.tfstate
The notes explain that the state manager reads the .tfstate information to determine which resources are already known to Terraform.
Think about it like this:
Terraform Configuration
↓
"What should exist?"
while:
Terraform State
↓
"What does Terraform know about the existing infrastructure?"
Terraform can compare these pieces of information to determine what needs to change.
12. How Terraform Decides What to Do
Suppose your Terraform file says:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Terraform checks the current state.
It also queries the AWS provider to understand the existing resource.
Then it compares the desired configuration with the current situation.
Conceptually:
.tf configuration
+
terraform.tfstate
+
AWS information
↓
Terraform comparison
↓
Required changes
The notes describe this comparison process as part of the State Manager’s work.
13. Terraform Plan
After comparing the desired configuration with the current state, Terraform generates a plan.
The plan can show:
Resources to create
Resources to update
Resources to delete
The notes explicitly describe these three categories as outputs of the plan generator.
This is one of the most useful features of Terraform.
Before making infrastructure changes, you can inspect what Terraform intends to change.
14. Terraform Providers
Terraform itself does not directly contain every cloud provider’s implementation.
Instead, it uses provider plugins.
For example:
Terraform Core
│
↓
Provider Plugin Interface
│
┌────┼─────┐
↓ ↓ ↓
AWS Azure Google
The notes show AWS, Azure, and Google provider plugins connected to the provider interface.
15. What Does an AWS Provider Do?
The AWS provider understands how to communicate with AWS.
For example, when Terraform needs to create an AWS VPC:
Terraform
↓
AWS Provider
↓
AWS SDK/API
↓
AWS VPC
The notes explain that the provider plugin is responsible for communicating with the cloud provider and that the AWS SDK is embedded inside the provider plugin.
16. Provider Plugin Interface
The notes use a simplified interface example:
interface ProviderPlugin {
ResourceState create(ResourceConfig config);
ResourceState read(String id);
ResourceState update(ResourceConfig config);
void delete(String id);
}
This is used to explain the basic idea of a common provider interface.
Different providers implement the required behavior for their own cloud platforms.
For example:
AWS Provider
↓
AWS API
Azure Provider
↓
Azure API
Google Provider
↓
Google API
The notes present this as a conceptual model of how Terraform communicates with different providers.
17. What Are Terraform Blocks?
Terraform configuration is written using blocks.
A block can be thought of as a container containing configuration.
The general structure shown in the notes is:
block_type "label1" "label2" {
key = value
key = value
}
For example:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Here:
resource
is the block type.
aws_vpc
is the resource type.
main
is the local name.
18. Terraform Block
The first block we need to understand is the:
terraformblock
The Terraform block configures Terraform itself.
It does not create AWS resources.
The notes explicitly state that the Terraform block is used to configure Terraform and does not create resources.
Example:
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
19. Understanding the Terraform Block
Let’s break it down.
Required Terraform version
required_version = ">= 1.0"
This specifies the Terraform Core version requirement.
Required provider
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
This tells Terraform that we want to use the AWS provider.
The notes explain:
aws→ the provider we wantsource→ where the provider comes fromversion→ which provider version to use
20. Provider Block
The next important block is the:
providerblock
Example:
provider "aws" {
region = "us-east-1"
}
This tells the AWS provider which region to use for resources where that provider configuration applies.
The notes specifically explain that the provider block can configure the region, but the block itself does not create an AWS resource.
21. Terraform Block vs Provider Block
This is an easy place to get confused.
Terraform block
terraform {
required_version = ">= 1.0"
}
Purpose:
Configure Terraform
Provider block
provider "aws" {
region = "us-east-1"
}
Purpose:
Configure AWS provider
Neither of these blocks directly creates a VPC, subnet, EC2 instance, etc.
22. Resource Block
Now we reach one of the most important Terraform blocks:
resource
A resource block tells Terraform:
This resource should exist.
The notes define the resource block using this general structure:
resource "resource_type" "resource_name" {
argument = value
}
For example:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Here:
aws_vpc
means the AWS VPC resource type.
main
is our local Terraform name for this resource.
23. Resource Does Not Mean “Create Every Time”
This is extremely important.
If you write:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
you are not saying:
Create a new VPC every time Terraform runs.
You are saying:
A VPC with this desired configuration should exist.
Terraform checks the existing state and determines whether it needs to create, update, or delete resources.
The notes emphasize this distinction directly.
24. Where Do We Find Resource Names?
A common beginner question is:
How do I know that the resource name is
aws_vpc?
And:
How do I know which arguments are available?
The answer is the:
Terraform Registry
The notes direct learners to the Terraform Registry to find resource types, arguments, and attributes.
For AWS resources, you can look up the relevant resource documentation and find:
- Resource name
- Arguments
- Required arguments
- Optional arguments
- Attributes
- Examples
25. Arguments vs Attributes
Terraform resource documentation contains information about arguments and attributes.
For example:
Arguments
↓
Values you provide
Attributes
↓
Values Terraform/provider exposes about the resource
The notes give examples such as:
region
cidr_block
as arguments, and:
arn
id
as attributes.
26. What Happens If We Remove a Resource?
Suppose initially we have:
resource "aws_vpc" "main" {
}
resource "aws_subnet" "public" {
}
Now imagine we remove the subnet block:
resource "aws_vpc" "main" {
}
Terraform sees that the current configuration no longer requires the subnet.
It compares:
Current .tf configuration
+
State
↓
Difference
and can generate a plan reflecting that the subnet is no longer required.
The notes use this exact example to explain how state and configuration differences influence the plan.
27. Why Do We Need Variables?
Imagine we have three places where we specify:
region = "us-east-1"
For example:
provider "aws" {
region = "us-east-1"
}
resource "aws_subnet" "public" {
region = "us-east-1"
}
resource "aws_subnet" "private" {
region = "us-east-1"
}
Now suppose we want to change the region.
We would need to change it in multiple places.
This is where variables help.
28. Variable Block
Instead of hardcoding the region everywhere, define it once:
variable "aws_region" {
description = "region where resources will be created"
type = string
default = "us-east-1"
}
Then use it:
provider "aws" {
region = var.aws_region
}
And:
resource "aws_subnet" "public" {
region = var.aws_region
}
Now if the region changes, we have a single place to update.
The notes demonstrate exactly this idea and explain that changing the region then requires changing it in only one place.
29. Why Variables Are Useful
Variables make Terraform configurations:
- Easier to maintain
- Reusable
- Easier to modify
- Less repetitive
Instead of:
us-east-1
us-east-1
us-east-1
us-east-1
we can use:
var.aws_region
This becomes especially useful as Terraform projects become larger.
30. Terraform Variable Types
The notes introduce several common Terraform types.
String
"us-east-1"
Example:
variable "region" {
type = string
}
Number
Example:
20
The notes list number with 20 as an example.
Boolean
Boolean values are:
true
false
Example:
variable "enabled" {
type = bool
}
31. List
A list can contain multiple values.
Example:
["a", "b"]
The notes show list(string) with this example.
Example:
variable "availability_zones" {
type = list(string)
default = ["us-east-1a", "us-east-1b"]
}
32. Set
A set is a collection where duplicates are removed and ordering is not maintained.
The notes illustrate:
["a", "b", "a"]
and explain that duplicates are removed but order is not maintained.
Conceptually:
Input:
["a", "b", "a"]
Set:
["a", "b"]
33. Map
A map stores key-value pairs.
Example:
{
name1 = "value1"
name2 = "value2"
}
The notes list map(string) with this structure.
For example:
variable "tags" {
type = map(string)
default = {
environment = "dev"
project = "myapp"
}
}
34. A Simple Terraform Example
Let’s combine the concepts from the notes.
Terraform configuration
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
Variable
variable "aws_region" {
description = "Region where resources will be created"
type = string
default = "us-east-1"
}
Provider
provider "aws" {
region = var.aws_region
}
VPC
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Now we have three important ideas:
Terraform block
↓
Provider block
↓
Resource block
plus:
Variable
35. Terraform’s Overall Flow
Let’s now understand everything together.
When you run Terraform, conceptually the process looks like:
.tf Files
│
↓
Terraform Core
│
┌───────┴────────┐
│ │
Parse/Validate State
│ │
└───────┬────────┘
↓
Dependency Graph
↓
Plan Generator
↓
Provider Plugin
↓
AWS Provider
↓
AWS API
↓
AWS Resources
The architecture and responsibilities described in the uploaded notes follow this overall model.
36. Terraform vs AWS Console
Let’s compare the two approaches.
AWS Console
Open AWS Console
↓
Click VPC
↓
Create VPC
↓
Click Subnet
↓
Create Subnet
↓
Configure Route Table
↓
Configure Gateway
↓
Configure Security
This can become difficult to reproduce consistently.
Terraform
.tf files
↓
terraform plan
↓
Review changes
↓
terraform apply
↓
Infrastructure
And because the .tf files are code, they can be stored in Git.
37. Why Terraform Is Useful
Terraform provides several practical advantages.
1. Infrastructure becomes code
Your infrastructure configuration exists as files.
2. Version control
You can store Terraform files in Git and track changes.
3. Repeatability
The same configuration can be used to build similar infrastructure again.
4. Desired state
You describe what infrastructure should exist rather than manually writing every API operation.
5. Plan before changes
Terraform can show what it intends to create, update, or delete.
6. Multiple providers
Terraform’s provider architecture supports different cloud platforms through provider plugins.
38. The Most Important Terraform Concepts
If you are just starting Terraform, focus on these concepts first:
Terraform
↓
Infrastructure as Code
↓
Declarative Configuration
↓
Terraform Core
↓
Provider
↓
Resource
↓
State
↓
Plan
↓
Variables
Once these are clear, Terraform becomes much easier to learn.
39. Quick Revision
What is Terraform?
An Infrastructure as Code tool used to define infrastructure through configuration.
What is IaC?
Managing infrastructure through code/configuration rather than only manual console operations.
Is Terraform imperative?
No. Terraform uses a declarative approach.
What is a .tf file?
A Terraform configuration file.
What is Terraform Core?
The core Terraform component that processes configuration, validates it, works with state, builds dependencies, and generates plans.
What is a Provider?
A plugin that allows Terraform to interact with a platform such as AWS.
What is a Resource?
A declaration of infrastructure that should exist.
What is Terraform State?
Information Terraform uses to track the infrastructure it manages.
What is a Variable?
A reusable input that helps avoid hardcoding values.
Where do I find Terraform resource documentation?
The Terraform Registry.
Conclusion
Terraform changes the way we think about infrastructure.
Instead of manually creating infrastructure:
Click
→ Select
→ Create
→ Configure
→ Repeat
we can define what we want:
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/23"
}
Terraform then compares the desired configuration with the state and existing infrastructure and determines what changes are required.
The key concept is:
Terraform configuration describes the infrastructure you want to exist. Terraform Core processes that configuration, works with state and dependencies, and uses provider plugins to communicate with platforms such as AWS.
The uploaded notes build this understanding progressively—from the problem Terraform solves, to declarative IaC, Terraform Core and providers, blocks, Terraform/provider/resource blocks, state, and finally variables and data types.
Suggested SEO Title
Terraform Tutorial for Beginners: IaC, Providers, Resources, State and Variables
Suggested URL Slug
terraform-tutorial-infrastructure-as-code-providers-resources-state
Suggested Meta Description
Learn Terraform from scratch with simple examples. Understand Infrastructure as Code, declarative configuration, Terraform Core, providers, resources, state, variables, and Terraform blocks.