- DevOps Lab Notes
- Posts
- Set Up Terraform in 10 Minutes — The Right Way
Set Up Terraform in 10 Minutes — The Right Way
A quick, opinionated starter guide to get your Terraform project off the ground
DevOps Lab Notes #1
From my terminal to yours — real DevOps experiments.
🚀 Set Up Terraform in 10 Minutes — The Right Way
Whether you're bootstrapping a new Terraform repo or helping someone get started, these are the essential steps to do it right from the beginning — without overcomplicating things.
✅ Goal: Have a working, validated Terraform setup with state backend and version pinning — all under 10 minutes.
🧰 Prerequisites
Make sure you have the following:
Terraform installed (v1.5+ preferred)
A working terminal
A folder for your project (e.g.
devops-lab-notes-1
)Optional:
tfenv
if you want to manage multiple Terraform versions
📁 Directory Structure (Recommended)
devops-lab-notes-1/
├── main.tf
├── variables.tf
├── outputs.tf
├── provider.tf
├── .terraform.lock.hcl
└── .terraform-version # If using tfenv
✅ Step-by-Step Setup
1️⃣ Pin Your Terraform Version
If you're using tfenv
to manage Terraform versions, create a .terraform-version
file and add the required version:
echo "1.6.6" > .terraform-version
This ensures your terminal always uses the right Terraform version in this project.
OR, make sure you enforce version via required_version
in provider.tf
:
terraform {
required_version = "~> 1.6.6"
}
If you use
tfenv
, you should create a.terraform-version
file — it's howtfenv
knows which version to activate.If you don’t use
tfenv
, this file is ignored by Terraform itself. You must rely on therequired_version
block insideprovider.tf
to enforce version constraints.
2️⃣ Configure Your Backend
To keep it simple, start with local backend. Add this to provider.tf
:
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
We'll cover remote backends (like S3) in a future post.
3️⃣ Define Your Provider
Still in provider.tf
, define your provider:
provider "aws" {
region = var.region
}
4️⃣ Define Variables
Create a variables.tf
file:
variable "region" {
description = "AWS region to deploy to"
type = string
default = "us-east-1"
}
5️⃣ Create Your First Resource
In main.tf
, create a dummy resource:
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo Hello, Terraform!"
}
}
6️⃣ Validate Your Setup
Run the following commands in your project folder:
terraform init
terraform validate
terraform plan
You should see Terraform download the provider and show you a plan with no errors.
📤 7. Define Outputs
Create an outputs.tf
file to expose values that other modules or users might need.
Example:
output "region" {
description = "The AWS region in use"
value = var.region
}
Outputs are helpful for debugging or for passing values to other modules or CI/CD pipelines.
✅ 8. Apply the Changes
Once you're happy with the plan:
terraform apply
Terraform will show you the plan again and ask:
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
to proceed. Terraform will now provision the resource (local-exec) and execute the command to print “hello, Terraform!”.
🔐 8. Understand .terraform.lock.hcl
When you run terraform init
, Terraform generates a file called .terraform.lock.hcl
.
This file locks the exact provider versions (and their dependency hashes) used in the project.
Example content:
provider "registry.terraform.io/hashicorp/aws" {
version = "5.37.0"
constraints = "~> 5.0"
hashes = [
"h1:xxx...",
...
]
}
Do:
Commit this file to Git
Use it to ensure consistent provider versions across teams and environments
Don’t:
Edit it manually
🔁 Bonus: Lock Your Provider Versions
Add this to provider.tf
to pin the AWS provider version:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
✅ Summary
By now, you should have:
A consistent project structure
Version pinning in place
A working local backend
Validated Terraform code
🔒 This minimal but opinionated setup is production-friendly — and a solid base to grow from.
👋 Want More?
Want me to extend this into a full GKE cluster lab or CI/CD pipeline example?
Reply to this email or connect with me on LinkedIn.
I'm building these labs live, one note at a time.
See you next week.
— Anuj