Introduction to Terraform and Infrastructure as Code
My journey from clicking through cloud consoles to declarative infrastructure management
Table of Contents
Introduction: The Friday Night Disaster
It was 5:47 PM on a Friday when my phone rang. My heart sank when I saw it was the junior developer on call.
"The staging environment is gone. All of it."
Gone. Not broken. Not misconfigured. Gone. Someone had accidentally deleted the wrong resource group in Azure while cleaning up a test environment. And because we managed everything through the cloud console, there was no code to redeploy. No version control. Just my memory of the dozens of resources I'd manually created over the past 3 months.
I spent the next 6 hours clicking through Azure Portal, AWS Console, and various other cloud interfaces, trying to recreate everything from memory and scattered screenshots. Security groups with 47 individual rules. Load balancers with specific health check configurations. Database instances with exact parameter settings. Tag after tag after tag.
I missed my daughter's 8th birthday dinner.
That Saturday morning, exhausted and frustrated, I searched for "how to automate cloud infrastructure." That's when I discovered Infrastructure as Code and Terraform. It would fundamentally change how I approached infrastructure management.
This article is the beginning of your Infrastructure as Code journey. I'll share everything I wish someone had told me on that frustrating Friday night.
What is Infrastructure as Code?
Infrastructure as Code (IaC) is the practice of managing and provisioning infrastructure through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.
Let me break that down with a simple analogy:
The Traditional Approach: The Recipe Card Method
Imagine you're teaching someone to bake a cake, but instead of giving them a recipe, you stand next to them and say:
"First, turn the oven to 350Β°F"
"Now add 2 cups of flour"
"Mix for 3 minutes"
"Wait, did I say 2 cups or 3 cups? Let me check my notes..."
Every time you bake the cake, you have to remember all the steps, in the right order, with the right quantities. If someone else tries to bake it, they might miss a step or use different ingredients.
The IaC Approach: The Written Recipe
With Infrastructure as Code, you write down the recipe once:
Now anyone can bake the same cake, consistently, every single time. That's Infrastructure as Code.
Why This Matters for Infrastructure
When you define infrastructure as code:
Version Control: Track every change in Git, like you do with application code
Reproducibility: Deploy identical environments consistently
Documentation: The code IS the documentation
Collaboration: Teams can review infrastructure changes like code reviews
Automation: Integrate with CI/CD pipelines
Disaster Recovery: Redeploy entire environments with one command
Why Not Just Use Cloud Consoles?
I spent 2 years managing infrastructure through cloud consoles before learning IaC. Here's what I learned the hard way:
The Console Clicking Nightmare
Problem 1: No Version History
Problem 2: Environment Drift
Dev environment has 2GB memory
Staging has 4GB (someone clicked "upgrade" last month)
Production has 8GB (because we had an incident)
Nobody knows which configuration is "correct"
Problem 3: Knowledge Silos
Problem 4: Human Error
Click the wrong button β resources deleted
Forget a step β broken deployments
Misconfigure settings β security vulnerabilities
No way to catch mistakes before they hit production
Problem 5: Scaling Impossibility
Need 3 identical web servers? Click 3 times through 15-step wizard
Need to update all of them? Click 45 times
Need to add 10 more? Please, just... no.
My Console Clicking Horror Story
In 2018, I was managing infrastructure for a financial services application across three environments (dev, staging, production). Everything was done through the AWS Console.
One day, I needed to update a security group rule in production. Simple task, right?
What I intended to do:
Add rule allowing HTTPS from new load balancer IP
What I actually did:
Opened wrong security group (they had similar names)
Modified production database security group
Accidentally removed a rule while adding the new one
Didn't notice because Console doesn't show "diff" of changes
Result:
Production database became unreachable
Application down for 37 minutes
Lost ~$15,000 in revenue
Spent 2 hours in post-mortem meetings
Wrote "incident report" that basically said "I clicked wrong button"
With Infrastructure as Code, this would have been:
Made change in code
Reviewed diff:
terraform planshows exactly what will changeTeam member reviews pull request: "Hey, why are you touching the database security group?"
Mistake caught before production impact
Understanding Infrastructure as Code Tools
Not all IaC tools are created equal. Let me break down the landscape:
Configuration Management vs Infrastructure Provisioning
Configuration Management Tools (Ansible, Chef, Puppet, SaltStack)
Focus: Configure and manage existing servers
Strength: Application deployment, software installation, configuration updates
Example: "Install Nginx on these 10 servers and configure them identically"
Infrastructure Provisioning Tools (Terraform, CloudFormation, Pulumi)
Focus: Create and manage infrastructure resources
Strength: Networks, servers, databases, cloud resources
Example: "Create 10 servers, a load balancer, and a VPC with specific subnets"
Declarative vs Imperative
Imperative Approach (Like cooking instructions)
Declarative Approach (Like a recipe's ingredient list)
The Major Players
Terraform
Declarative, Multi-cloud
Provider-agnostic, huge ecosystem
Learning curve, state management
CloudFormation
Declarative, AWS-only
Deep AWS integration, free
AWS-locked, verbose YAML
Pulumi
Declarative, Multi-cloud
Real programming languages
Newer, smaller community
Ansible
Imperative/Declarative
Simple, agentless
Not ideal for infrastructure
Why Terraform? My Choice Explained
After evaluating all major IaC tools, I chose Terraform. Here's why:
1. Provider-Agnostic Architecture
The Problem I Had:
AWS for compute
Azure for legacy applications
GCP for data analytics
Cloudflare for DNS
GitHub for code repositories
Terraform's Solution:
One configuration language. One workflow. One state file. Multiple clouds.
2. Massive Provider Ecosystem
Terraform has 3,000+ providers for everything imaginable:
Cloud Providers: AWS, Azure, GCP, Oracle Cloud, Alibaba Cloud
SaaS Platforms: GitHub, GitLab, Datadog, PagerDuty, Slack
Databases: MongoDB, PostgreSQL, MySQL
DNS/CDN: Cloudflare, Route53, Fastly
Monitoring: Datadog, New Relic, Splunk
And even: Spotify playlists, Home Assistant, your coffee maker (probably)
3. Declarative and Predictable
4. State Management
Terraform tracks what it created in a state file. This means:
Knows what exists vs what should exist
Can detect drift (manual changes)
Can update resources in place vs recreate
Prevents duplicate resource creation
5. Massive Community
70,000+ modules in Terraform Registry
Active community on Reddit, Stack Overflow, HashiCorp forums
Extensive documentation
Regular updates and improvements
6. Free and Open Source
Core Terraform is 100% free
Optional paid features (Terraform Cloud) for teams
No vendor lock-in
When NOT to Use Terraform
Use Ansible instead if:
Primarily configuring existing servers
Need to run commands on remote systems
Focused on application deployment
Use CloudFormation instead if:
100% AWS-only, forever
Need deep AWS-specific features
Want AWS support for the IaC tool itself
Use Pulumi instead if:
Want to write infrastructure in Python/TypeScript/Go
Need complex programmatic logic
Willing to trade ecosystem maturity for familiar languages
Installing Terraform
Let's get Terraform installed. I'll show you the best method for each operating system.
macOS Installation
Option 1: Homebrew (Recommended)
Option 2: Manual Download
Linux Installation
Ubuntu/Debian:
RHEL/CentOS/Fedora:
Windows Installation
Option 1: Chocolatey (Recommended)
Option 2: Manual Download
Download from https://www.terraform.io/downloads
Extract ZIP file
Add to PATH environment variable
Restart terminal
Run
terraform version
Verification
After installation, you should see output like:
Enable tab completion:
Terraform Architecture Overview
Before we write code, let's understand how Terraform works:
Key Components
1. Configuration Files (.tf files)
Where you define infrastructure in HCL
Human-readable and version-controllable
Contains resources, providers, variables, outputs
2. Terraform CLI
Command-line tool you run
Executes commands:
init,plan,apply,destroyOrchestrates everything
3. Providers
Plugins that talk to APIs (AWS, Azure, GCP, etc.)
Downloaded during
terraform initEach provider knows how to create/read/update/delete its resources
4. State File
Terraform's "database" of what it created
Maps configuration to real-world resources
Tracks metadata and resource dependencies
Critical: Lose this, lose Terraform's knowledge of your infrastructure
5. Execution Engine
Builds dependency graph
Determines order of operations
Executes create/update/delete operations
Handles errors and rollbacks
Your First Terraform Configuration
Let's start with the simplest possible example. We'll create a file on your local computer - no cloud accounts needed yet.
Step 1: Create a Project Directory
Step 2: Create Your First Configuration File
Create a file named main.tf:
Step 3: Initialize Terraform
What you'll see:
What just happened:
Terraform read your configuration
Detected you're using the
localproviderDownloaded the provider plugin
Created a
.terraformdirectory to store pluginsReady to execute commands
Understanding the Terraform Workflow
Terraform has a standard workflow. Let's go through it step by step:
The Four Core Commands
1. terraform init - Initialize
Downloads provider plugins
Prepares backend for state storage
Initializes modules
Run this once per project (or when adding new providers)
2. terraform plan - Preview Changes
Shows what Terraform will do
Compares desired state (config) vs current state
No changes are made - it's a preview
Always run this before apply
3. terraform apply - Execute Changes
Actually creates/modifies/deletes resources
Shows plan and asks for confirmation
Updates state file
This makes real changes
4. terraform destroy - Clean Up
Deletes all resources Terraform created
Useful for testing and cleanup
Be very careful - this is destructive
Let's Execute Our First Plan
Output:
Reading the output:
+means "will be created"~means "will be modified"-means "will be destroyed"(known after apply)- values determined during creation
Now Let's Actually Create
Terraform shows the plan again and asks:
Type yes and press Enter.
Output:
Verify It Worked
You should see both files with the exact content you defined!
Auto-Approve (Use Carefully)
Breaking Down What Just Happened
Let's examine our configuration in detail:
Resource Block Anatomy
Resource Type: local_file
Format:
<provider>_<resource_type>local= provider namefile= resource type within that provider
Resource Name: welcome
Your custom identifier for this resource
Used to reference it elsewhere in config
Must be unique within this resource type
Arguments: filename, content, file_permission
Configuration for this resource
Each resource type has different arguments
Some required, some optional
Special Functions and Expressions
${path.module} - Module Path
timestamp() - Current Time
Heredoc String (<<-EOT ... EOT)
The State File
After applying, check your directory:
You'll see:
terraform.tfstate- THE STATE FILEterraform.tfstate.backup- Previous state version
Let's peek inside:
This is Terraform's memory of what it created. Guard it with your life (we'll learn proper state management in Article 6).
Common Mistakes and How to Avoid Them
Let me share the mistakes I made when starting with Terraform:
Mistake #1: Not Running terraform plan First
terraform plan FirstWhat I Did:
What I Should Have Done:
Lesson: Always plan before apply. Always.
Mistake #2: Editing Resources Manually
What I Did:
What Happened:
Lesson: Don't manually modify Terraform-managed resources. Change the configuration instead.
Mistake #3: Committing State Files to Git
What I Did:
What I Should Have Done:
Lesson: State files can contain secrets. Never commit them to Git (unless using encrypted remote state).
Mistake #4: Deleting State Files
What I Did:
What Happened:
Why: Terraform lost its memory of creating the file, so it tries to create it again.
Lesson: State files are sacred. Back them up, store them securely, but never delete them.
Mistake #5: Using Hardcoded Values Everywhere
What I Did:
What I Should Have Done (we'll learn this in Article 3):
Lesson: Use variables for reusability. Hardcoding doesn't scale.
Best Practices from Day One
Start with good habits immediately:
1. Always Use Version Control
2. Organize Your Files
Bad:
Good:
3. Use Meaningful Resource Names
Bad:
Good:
4. Add Comments
5. Start with Plan, End with Destroy
6. Keep State Files Safe
For now (learning):
Don't delete state files
Don't edit state files manually
Don't commit to Git
Later (production):
Use remote state (S3, Azure Storage, Terraform Cloud)
Enable state locking
Enable versioning/backups
What I Learned About Infrastructure as Code
Looking back at my journey from that Friday night disaster to confident IaC practices:
1. Infrastructure IS Code
The biggest mindset shift: Treat infrastructure with the same rigor as application code.
Version control everything
Code review infrastructure changes
Test before deploying
Document through code
2. Declarative Beats Imperative
Describing what you want is better than scripting how to create it.
Imperative (Bash script):
Declarative (Terraform):
3. State Management is Critical
The state file is Terraform's memory. Respect it:
Back it up
Secure it (contains secrets)
Use remote state for teams
Never edit manually
4. Start Simple, Grow Complexity
Don't try to terraform your entire infrastructure on day one:
Week 1: Local file resources (learning) Week 2: Simple cloud resources (VPC, subnets) Week 3: Add modules (networking, compute) Month 2: Multi-environment setup Month 3: CI/CD integration Month 6: Enterprise-scale patterns
5. The Community is Amazing
When stuck:
Terraform Registry - Browse providers and modules
HashiCorp Learn - Official tutorials
Terraform Documentation - Provider docs
Reddit r/Terraform - Community help
Stack Overflow - Specific questions
6. Errors are Learning Opportunities
Every Error: message taught me something:
Don't fear errors. Read them carefully. They're usually helpful.
Next Steps
Congratulations! You've taken your first steps into Infrastructure as Code. Here's what you've accomplished:
β Understood what Infrastructure as Code is and why it matters β Installed Terraform on your system β Created your first Terraform configuration β Learned the core Terraform workflow (init, plan, apply, destroy) β Understood the role of state files β Established best practices from day one
Practice Exercises
Before moving to Article 2, solidify your understanding:
Exercise 1: Create Multiple Files
Exercise 2: Modify and Reapply
Exercise 3: Destroy and Recreate
Exercise 4: Experiment with Functions
Coming Up Next
In Article 2: Providers, Resources, and the Magic of State Files, we'll dive deeper into:
How providers work and how to configure them
Resource block anatomy in detail
State file deep dive and management
Data sources for reading information
Multi-provider configurations
Real-world example: Building a simple multi-resource infrastructure
Your Infrastructure Journey
Remember that Friday night when I manually rebuilt an entire environment? That was my last Friday night spent clicking through cloud consoles.
With Terraform:
Lost environments can be rebuilt with
terraform applyChanges are reviewed before deployment
Documentation lives in the code
Teams can collaborate effectively
Sleep soundly knowing infrastructure is reproducible
You're on your way to the same confidence. Keep practicing, keep learning, and remember: every expert started exactly where you are now.
Practice Exercise for This Week: Create a Terraform configuration that creates 3 files representing different environments (dev, staging, prod). Each file should contain:
Environment name
Creation timestamp
A motivational message about IaC
Don't worry about making it perfect. Focus on running through the workflow (init, plan, apply) multiple times until it feels natural.
See you in Article 2! π
"Infrastructure as Code isn't about technology. It's about treating infrastructure with the same discipline and rigor we apply to application development. Once you understand that, everything else is just syntax." - Me, after rebuilding that staging environment for the last time
Last updated