π Hey there, tech enthusiasts!
I'm Sarvar, a Cloud Architect with a passion for transforming complex technological challenges into elegant solutions. With extensive experience spanning Cloud Operations (AWS & Azure), Data Operations, Analytics, DevOps, and Generative AI, I've had the privilege of architecting solutions for global enterprises that drive real business impact. Through this article series, I'm excited to share practical insights, best practices, and hands-on experiences from my journey in the tech world. Whether you're a seasoned professional or just starting out, I aim to break down complex concepts into digestible pieces that you can apply in your projects.
"The journey from clicking to coding starts with a single resource."
π― Welcome Back!
Remember in Article 1 when I showed you the pain of clicking through AWS Console for hours? And in Article 2 we got Terraform installed?
Today, you'll experience the magic moment - creating real AWS infrastructure with just a few lines of code.
By the end of this article, you'll:
- β Understand the Terraform workflow (the 4 commands you'll use forever)
- β
Write your first
.tffile - β Create an actual S3 bucket on AWS
- β Understand what a state file is and why it matters
- β Clean up resources properly
Time Required: 20 minutes
Cost: $0 (S3 bucket is free tier)
Difficulty: Beginner-friendly
Let's create some infrastructure! π
π‘ Quick Theory: The Terraform Workflow
Before we dive in, you need to know the 4 commands that form the core Terraform workflow. You'll use these commands for every project, whether you're creating a simple S3 bucket or a complex multi-tier application.
The Magic 4 Commands:
terraform init # Initialize - Download providers
terraform plan # Preview - See what will change
terraform apply # Execute - Create the resources
terraform destroy # Cleanup - Remove everything
Think of it like cooking:
- init = Get your ingredients and tools ready
- plan = Read the recipe and imagine the final dish
- apply = Actually cook the meal
- destroy = Clean up the kitchen
That's it! Master these 4 commands, and you've mastered the Terraform workflow.
π Understanding Terraform Files
Terraform uses files with .tf extension written in HCL (HashiCorp Configuration Language). Don't worry - it's much simpler than it sounds!
Basic Structure:
# This is a comment
block_type "label" "name" {
argument = "value"
another_argument = 123
}
Three main block types you'll use:
- terraform - Configuration settings
- provider - Which cloud (AWS, Azure, GCP)
- resource - What to create (S3, EC2, etc.)
Let's see them in action!
π οΈ Hands-On: Create Your First S3 Bucket
Step 1: Create Your Project Directory
# Create a directory for your first Terraform project
mkdir -p ~/terraform-first-resource
cd ~/terraform-first-resource
Step 2: Write Your First Terraform Code
Create a file called main.tf:
nano main.tf
# Or use your favorite editor: vim, VS Code, etc.
Copy this code:
# Terraform configuration block
# Specifies Terraform version and required providers
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Provider configuration
# Tells Terraform to use AWS in us-east-1 region
provider "aws" {
region = "us-east-1"
}
# Resource block - This creates the actual S3 bucket
resource "aws_s3_bucket" "my_first_bucket" {
# Bucket name must be globally unique across ALL AWS accounts
# Replace 'yourname' with your actual name or username
bucket = "terraform-first-bucket-yourname-2026"
# Tags help organize and track resources
tags = {
Name = "My First Terraform Bucket"
Environment = "Learning"
ManagedBy = "Terraform"
CreatedBy = "YourName"
Updated = "Yes"
}
}
# Output block - Displays information after creation
output "bucket_name" {
value = aws_s3_bucket.my_first_bucket.id
description = "The name of the S3 bucket"
}
output "bucket_arn" {
value = aws_s3_bucket.my_first_bucket.arn
description = "The ARN of the S3 bucket"
}
output "bucket_region" {
value = aws_s3_bucket.my_first_bucket.region
description = "The region where bucket is created"
}
β οΈ Important: Change yourname in the bucket name to something unique (your name, username, or random string). S3 bucket names must be globally unique across ALL AWS accounts!
Save the file (Ctrl+X, then Y, then Enter if using nano)
π The 4 Commands in Action
Now comes the exciting part! Let's run our 4 magic commands.
Command 1: terraform init
This downloads the AWS provider plugin.
terraform init
You'll see:
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.x.x...
- Installed hashicorp/aws v5.x.x
Terraform has been successfully initialized!
What just happened?
- Terraform downloaded the AWS provider plugin
- Created a
.terraform/directory (hidden folder) - Created
.terraform.lock.hclfile (locks provider versions)
Pro Tip: You only need to run init once per project, or when you add new providers.
Command 2: terraform plan
This shows you what Terraform will create (without actually creating it).
terraform plan
You'll see:
Terraform will perform the following actions:
# aws_s3_bucket.my_first_bucket will be created
+ resource "aws_s3_bucket" "my_first_bucket" {
+ bucket = "terraform-first-bucket-yourname-2026"
+ bucket_domain_name = (known after apply)
+ id = (known after apply)
+ region = (known after apply)
+ tags = {
+ "CreatedBy" = "YourName"
+ "Environment" = "Learning"
+ "ManagedBy" = "Terraform"
+ "Name" = "My First Terraform Bucket"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Understanding the output:
-
+means "will be created" -
~means "will be modified" (you'll see this later) -
-means "will be destroyed" -
(known after apply)means AWS will generate this value
This is your safety check! Always review the plan before applying.
Command 3: terraform apply
This actually creates the resources on AWS.
terraform apply
Terraform will show the plan again and ask for confirmation:
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Type yes and press Enter.
You'll see:
aws_s3_bucket.my_first_bucket: Creating...
aws_s3_bucket.my_first_bucket: Creation complete after 2s [id=terraform-first-bucket-yourname-2026]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::terraform-first-bucket-yourname-2026"
bucket_name = "terraform-first-bucket-yourname-2026"
bucket_region = "us-east-1"
π Congratulations! You just created your first AWS resource with code!
Verify in AWS Console
Let's confirm it's really there:
- Go to AWS S3 Console
- You should see your bucket:
terraform-first-bucket-yourname-2026 - Click on it and check the Tags tab - you'll see all the tags you defined!
This is the "aha!" moment - you created AWS infrastructure without clicking through the console!
ποΈ Understanding the State File
After running terraform apply, you'll notice a new file: terraform.tfstate
ls -la
You'll see:
.terraform/
.terraform.lock.hcl
main.tf
terraform.tfstate
What is the State File?
The state file is Terraform's memory. It stores:
- What resources Terraform created
- Current configuration of those resources
- Metadata and dependencies
Let's peek inside:
cat terraform.tfstate
You'll see JSON with details about your S3 bucket - its name, ARN, region, tags, etc.
Why Does State Matter?
When you run terraform plan or terraform apply again, Terraform:
- Reads the state file to know what exists
- Compares it with your
.tffiles - Calculates what needs to change
Without state, Terraform wouldn't know what it created!
β οΈ Important State Rules:
- Never edit state files manually
- Never delete state files (you'll lose track of resources)
- Never commit state files to Git (they contain sensitive data)
- For teams, use remote state (we'll cover this in Article 8)
π§ͺ Let's Make a Change
Now let's see Terraform's power - making changes to existing infrastructure.
Edit your main.tf file and add a new tag:
resource "aws_s3_bucket" "my_first_bucket" {
bucket = "terraform-first-bucket-yourname-2026"
tags = {
Name = "My First Terraform Bucket"
Environment = "Learning"
ManagedBy = "Terraform"
CreatedBy = "YourName"
Updated = "Yes"
LastUpdated = "Today" # β Add this new tag
}
}
Run plan again:
terraform plan
You'll see:
# aws_s3_bucket.my_first_bucket will be updated in-place
~ resource "aws_s3_bucket" "my_first_bucket" {
~ tags = {
+ "Updated" = "Yes"
# (5 unchanged elements hidden)
}
}
Plan: 0 to add, 1 to change, 0 to destroy.
Notice the ~ symbol - it means "modify existing resource"!
Apply the change:
terraform apply
Type yes when prompted.
Check AWS Console - your bucket now has the new tag!
This is Infrastructure as Code magic - you changed infrastructure by editing a text file!
π§Ή Command 4: terraform destroy
Always clean up resources you're not using (to avoid unexpected charges).
terraform destroy
Terraform will show what it will delete:
# aws_s3_bucket.my_first_bucket will be destroyed
- resource "aws_s3_bucket" "my_first_bucket" {
- bucket = "terraform-first-bucket-yourname-2026"
...
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Enter a value:
Type yes to confirm.
aws_s3_bucket.my_first_bucket: Destroying...
aws_s3_bucket.my_first_bucket: Destruction complete after 1s
Destroy complete! Resources: 1 destroyed.
Verify in AWS Console - your bucket is gone!
π What You Just Learned
Let's recap what you accomplished:
β The Terraform Workflow:
-
init- Initialize project -
plan- Preview changes -
apply- Create resources -
destroy- Clean up
β HCL Basics:
- terraform block (configuration)
- provider block (cloud provider)
- resource block (what to create)
- output block (display information)
β State Management:
- State file tracks resources
- Never edit state manually
- State enables change detection
β Real Infrastructure:
- Created actual AWS S3 bucket
- Modified existing resource
- Destroyed resources cleanly
π Common Issues and Solutions
Issue 1: Bucket Name Already Exists
Error:
Error: creating S3 Bucket: BucketAlreadyExists
Solution: S3 bucket names are globally unique. Change your bucket name to something more unique:
bucket = "terraform-first-bucket-yourname-12345-2026"
Issue 2: Invalid Bucket Name
Error:
Error: invalid bucket name
Solution: S3 bucket names must:
- Be 3-63 characters long
- Use only lowercase letters, numbers, and hyphens
- Start with a letter or number
- Not use uppercase or underscores
Bad: My_Bucket_Name
Good: my-bucket-name
Issue 3: AWS Credentials Not Found
Error:
Error: No valid credential sources found
Solution: Configure AWS credentials (from Article 2):
aws configure
Enter your AWS Access Key ID and Secret Access Key.
Issue 4: Permission Denied
Error:
Error: AccessDenied: Access Denied
Solution: Your AWS user needs S3 permissions. Attach the AmazonS3FullAccess policy to your IAM user in AWS Console.
π‘ Best Practices You Should Follow
1. Always Use Version Control
git init
echo ".terraform/" >> .gitignore
echo "terraform.tfstate*" >> .gitignore
echo "*.tfvars" >> .gitignore
git add main.tf .gitignore
git commit -m "Add first Terraform resource"
2. Use Meaningful Names
Bad:
resource "aws_s3_bucket" "b" {
bucket = "bucket1"
}
Good:
resource "aws_s3_bucket" "application_logs" {
bucket = "myapp-logs-production-2026"
}
3. Always Add Tags
Tags help with:
- Cost tracking
- Resource organization
- Automation
- Compliance
Minimum tags:
tags = {
Name = "Resource purpose"
Environment = "dev/staging/prod"
ManagedBy = "Terraform"
Owner = "team-name"
}
4. Run Plan Before Apply
Never skip terraform plan! It's your safety net.
5. Use Descriptive Outputs
Outputs make it easy to get important information:
output "bucket_name" {
value = aws_s3_bucket.my_first_bucket.id
description = "The name of the S3 bucket"
}
π Understanding What Happened Behind the Scenes
When you ran terraform apply, here's what happened:
-
Terraform read your
main.tffile- Parsed the HCL syntax
- Understood you want an S3 bucket
-
Terraform checked the state file
- Found it was empty (first run)
- Knew it needed to create the bucket
-
Terraform called AWS API
- Used your AWS credentials
- Made API call:
CreateBucket - Set the tags with
PutBucketTagging
-
AWS created the bucket
- Generated unique bucket ID
- Returned bucket details
-
Terraform updated state file
- Saved bucket information
- Recorded all attributes
-
Terraform displayed outputs
- Showed the values you defined
This is the power of Infrastructure as Code - complex API calls abstracted into simple, readable code!
π― Challenge: Try It Yourself
Before moving to the next article, try these challenges:
Challenge 1: Create Multiple Buckets
Create 2 different S3 buckets in the same main.tf file.
Hint:
resource "aws_s3_bucket" "bucket_one" {
bucket = "my-first-bucket-yourname"
}
resource "aws_s3_bucket" "bucket_two" {
bucket = "my-second-bucket-yourname"
}
Challenge 2: Use Different Region
Change the provider region to us-west-2 and create a bucket there.
Challenge 3: Add More Tags
Add 3 more custom tags to your bucket (Project, CostCenter, Department).
Challenge 4: Format Your Code
Run terraform fmt to automatically format your code:
terraform fmt
Challenge 5: Validate Your Code
Run terraform validate to check for syntax errors:
terraform validate
π Additional Terraform Commands
Beyond the core 4 commands, here are useful ones:
# Format your code (auto-fix indentation)
terraform fmt
# Validate syntax
terraform validate
# Show current state
terraform show
# List resources in state
terraform state list
# Get detailed resource info
terraform state show aws_s3_bucket.my_first_bucket
# View outputs without applying
terraform output
# View specific output
terraform output bucket_name
π Useful Resources
- Terraform AWS Provider Docs: https://registry.terraform.io/providers/hashicorp/aws/latest/docs
- S3 Bucket Resource: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket
- HCL Syntax: https://developer.hashicorp.com/terraform/language/syntax/configuration
- Terraform CLI Commands: https://developer.hashicorp.com/terraform/cli/commands
π¬ What's Next?
In Article 4: Understanding Terraform State, we'll dive deeper into:
- How state files work internally
- State commands (
state list,state show,state mv) - Importing existing AWS resources
- State locking and remote state (preview)
- Recovering from state issues
You'll learn:
- Why state is Terraform's most important file
- How to inspect and manipulate state safely
- What to do when state gets out of sync
- Preparing for team collaboration
π Summary
Today you learned the foundation of Terraform:
The 4 Core Commands:
terraform init # Get ready
terraform plan # Preview
terraform apply # Execute
terraform destroy # Cleanup
Key Concepts:
-
.tffiles contain your infrastructure code - State files track what Terraform created
- HCL syntax is simple and readable
- Always plan before applying
- Tags help organize resources
You created real infrastructure with code! No more clicking through AWS Console for simple tasks.
π Wrapping Up
Thank you for reading. I hope this article provided practical insights and a clearer understanding of the topic.
If you found this useful:
- β€οΈ Like if it added value
- π¦ Unicorn if youβre applying it today
- πΎ Save it for your next optimization session
- π Share it with your team
π‘ Whatβs Next
More deep dives are coming soon on:
- Cloud Operations
- GenAI & Agentic AI
- DevOps Automation
- Data & Platform Engineering
Follow along for weekly insights and hands-on guides.
π Portfolio & Work
You can explore my full body of work, certifications, architecture projects, and technical articles here:
π Visit My Website
π οΈ Services I Offer
If you're looking for hands-on guidance or collaboration, I provide:
- Cloud Architecture Consulting (AWS / Azure)
- DevSecOps & Automation Design
- FinOps Optimization Reviews
- Technical Writing (Cloud, DevOps, GenAI)
- Product & Architecture Reviews
- Mentorship & 1:1 Technical Guidance
π€ Letβs Connect
Iβd love to hear your thoughts. Feel free to drop a comment or connect with me on:
π LinkedIn
For collaborations, consulting, or technical discussions, reach out at:
Found this helpful? Share it with your team.
β Star the repo β’ π Follow the series β’ π¬ Ask questions
Made by Sarvar Nadaf
π https://sarvarnadaf.com















Top comments (0)