What is Terraform?
Terraform is an open-source tool that lets you write code to create and manage cloud infrastructure. Instead of clicking through AWS console to create resources manually, you write configuration files that describe what you want, and Terraform builds it for you.
Think of it like this: Instead of building a LEGO house brick by brick, you write down instructions, and Terraform builds it automatically every time.
What is Infrastructure as Code (IaC)?
Infrastructure as Code (IaC) means managing your servers, databases, networks, and other infrastructure using code files instead of manual configuration.
Benefits:
Repeatable: Create the same infrastructure multiple times without errors
Version Control: Track changes using Git, just like application code
Documentation: Your code becomes living documentation
Collaboration: Teams can review and collaborate on infrastructure changes
Use Cases:
Setting up development, staging, and production environments that are identical
Quickly spinning up infrastructure for new projects
Disaster recovery - rebuild everything from code if something breaks
Sharing infrastructure setups across teams
What is a Terraform Provider?
A provider is a plugin that allows Terraform to interact with a specific cloud platform or service (like AWS, Azure, Google Cloud, etc.).
Think of providers as translators - they translate your Terraform code into API calls that the cloud platform understands.
Setup Guide
1. Create IAM User with S3 Full Access
Before we can create S3 buckets, we need AWS credentials with proper permissions.
Steps:
Log into AWS Console → Go to IAM service
Click "Users" → "Create user"
Username: Enter
terraform-demo-userClick "Next"
Attach policies directly → Search and select
AmazonS3FullAccessClick "Next" → "Create user"
Click on the user → Go to "Security credentials" tab
Click "Create access key"
Select "Command Line Interface (CLI)"
Check the confirmation box → "Next"
"Create access key"
IMPORTANT: Save both:
* Access Key ID
* Secret Access Key (you won't see this again!)
2. Configure AWS CLI
Install AWS CLI (if not already installed):
# For Mac (using Homebrew)
brew install awscli
Configure with your access keys:
aws configure
You'll be prompted to enter:
AWS Access Key ID: [paste your access key]
AWS Secret Access Key: [paste your secret key]
Default region name: ap-south-1
Default output format: json
Verify it works:
aws s3 ls
4. Create Terraform Alias (Optional)
# Add to your shell config file (~/.zshrc for Mac)
echo 'alias tf="terraform"' >> ~/.zshrc
# Reload your shell
source ~/.zshrc
# Test it
tf version
5. Setup VS Code
Open VS Code
Go to Extensions (Cmd+Shift+X)
Search for "HashiCorp Terraform"
Install the official extension
Benefits:
Syntax highlighting
Auto-completion
Format on save
Validation
Understanding the Terraform Configuration
Create a file named main.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "ap-south-1"
}
# Create S3 Bucket
resource "aws_s3_bucket" "my_first_bucket" {
bucket = "ijas-tf-test-bucket-12345"
tags = {
Name = "My bucket"
Environment = "Dev"
}
}
The terraform {} block is used to configure Terraform itself. Inside it, required_providers tells Terraform which providers are needed for the project. In this case, aws is the name we use to refer to the AWS provider, and source specifies that it should be downloaded from HashiCorp’s official registry.
The line version = "~> 6.0" means Terraform can use any 6.x version of the provider, allowing minor updates but not major ones. The ~> symbol is called a pessimistic constraint, which lets Terraform update safely without breaking changes.
The provider "aws" block is used to set up the AWS provider. Inside it, the region tells Terraform where to create your AWS resources, in this case, Mumbai. Terraform automatically uses the login details you already set up earlier with aws configure, so you don’t need to write your credentials again.
The resource keyword is used to define an infrastructure item in Terraform. "aws_s3_bucket" specifies that you’re creating an S3 bucket using the AWS provider. "my_first_bucket" is just a local name you give this resource inside your Terraform code. The bucket field sets the real S3 bucket name in AWS, which must be globally unique. Finally, tags are optional labels you add to help organize resources and track costs.
Terraform Workflow
Step 1: Initialise Terraform
terraform init
# or using alias
tf init
What happens:
Downloads the AWS provider plugin
Sets up the backend (where state is stored)
Prepares the working directory
Output you'll see:
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 6.0"...
- Installing hashicorp/aws v6.x.x...
Terraform has been successfully initialized!
Step 2: Plan the Changes
terraform plan
# or
tf plan
What it does:
Compares your code with the current state
Shows what will be created, modified, or destroyed
Like a "preview" before making actual changes
Output:
Terraform will perform the following actions:
# aws_s3_bucket.my_first_bucket will be created
+ resource "aws_s3_bucket" "my_first_bucket" {
+ bucket = "ijas-tf-test-bucket-12345"
+ tags = {
+ "Environment" = "Dev"
+ "Name" = "My bucket"
}
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
Symbols:
+= Will be created~= Will be modified-= Will be destroyed
Optional: Save the Plan
tf plan -out=tfplan
Why use this?
Saves the exact plan to a file
When you run
tf apply tfplan, it executes exactly what was plannedPrevents surprises if something changes between plan and apply
Good practice for production environments
Step 3: Apply the Changes
terraform apply
# or
tf apply
Terraform will show the plan again and ask:
Do you want to perform these actions?
Enter a value:
Type yes and press Enter.
Skip the confirmation:
tf apply -auto-approve
What happens:
Terraform makes API calls to AWS
Creates the S3 bucket
Saves the state to
terraform.tfstatefile
Step 4: Verify in AWS Console
Go to AWS Console → S3
You'll see your bucket:
ijas-tf-test-bucket-12345Click on it → Properties tab → Tags
You'll see the tags you defined
Step 5: Modify and Reapply
Let's change a tag in main.tf:
resource "aws_s3_bucket" "my_first_bucket" {
bucket = "ijas-tf-test-bucket-12345"
tags = {
Name = "My bucket"
Environment = "Development" # Changed from "Dev"
Owner = "Ijas" # Added new tag
}
}
Run:
tf plan
You'll see:
# aws_s3_bucket.my_first_bucket will be updated in-place
~ resource "aws_s3_bucket" "my_first_bucket" {
~ tags = {
~ "Environment" = "Dev" -> "Development"
+ "Owner" = "Ijas"
"Name" = "My bucket"
}
}
Plan: 0 to add, 1 to change, 0 to destroy.
Apply the changes:
tf apply -auto-approve
Go back to AWS Console → refresh → see the updated tags!
Step 6: Destroy Resources
When you're done experimenting:
terraform destroy
# or
tf destroy
Terraform shows what will be destroyed:
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Enter a value:
Type yes or use:
tf destroy -auto-approve
What happens:
Terraform deletes the S3 bucket from AWS
Updates the state file (now empty)
Key Concepts Summary
| Concept | Simple Explanation |
|---|---|
| Terraform | Tool to write code that builds cloud infrastructure |
| IaC | Managing infrastructure through code files instead of clicking |
| Provider | Plugin that connects Terraform to cloud platforms (AWS, Azure, etc.) |
| Resource | A piece of infrastructure you want to create (S3 bucket, EC2 instance) |
| State | Terraform's memory of what exists in the cloud |
| Plan | Preview of changes before applying them |
| Apply | Actually create/update/delete resources |
| Destroy | Delete all resources managed by Terraform |
Common Commands Cheat Sheet
# Initialize project (run once)
tf init
# Preview changes
tf plan
tf plan -out=tfplan # Save plan to file
# Apply changes
tf apply
tf apply -auto-approve # Skip confirmation
tf apply tfplan # Apply saved plan
# Show current state
tf show
# List resources
tf state list
# Destroy everything
tf destroy
tf destroy -auto-approve
# Format code (clean up spacing/indentation)
tf fmt
# Validate syntax
tf validate




Top comments (0)