Clicking through a cloud console to create servers works once. But what about doing it consistently, 50 times, across three environments, with a full audit trail? That’s where Infrastructure as Code (IaC) comes in, and Terraform is the most popular tool for the job.
What is Infrastructure as Code?
Instead of manually creating resources, you describe them in code. Then a tool makes reality match your description. Benefits:
- Repeatable — same result every time.
- Versioned — your infra lives in Git alongside your app.
- Reviewable — changes go through pull requests.
- Documented — the code is the documentation.
Why Terraform?
- Works across AWS, Azure, GCP, and 100s of other providers.
- Declarative, you say what you want, not how to build it.
- Huge community and module ecosystem.
Install it here, then check:
terraform version
The core concepts
| Concept | Meaning |
|---|---|
| Provider | The platform you’re managing (AWS, etc.) |
| Resource | A thing you create (a server, bucket, network) |
| State | Terraform’s record of what it has created |
| Plan | A preview of changes before applying |
Your first configuration
Create a file main.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "my_bucket" {
bucket = "devops-adda-demo-bucket-12345"
tags = {
Name = "Demo Bucket"
Environment = "Learning"
}
}
The core workflow
terraform init # download the provider plugins
terraform plan # preview what will be created/changed
terraform apply # make it happen (type 'yes' to confirm)
terraform destroy # tear it all down when you're done
Always read the plan output before you apply. It tells you exactly what’s about to change.
Variables (don’t hardcode)
variable "region" {
description = "AWS region to deploy into"
default = "us-east-1"
}
provider "aws" {
region = var.region
}
Outputs
Print useful values after applying:
output "bucket_name" {
value = aws_s3_bucket.my_bucket.bucket
}
Understanding state
Terraform keeps a terraform.tfstate file mapping your code to real resources. Treat it carefully:
- Never edit it by hand.
- Don’t commit it to Git (it can contain secrets).
- On a team, store it remotely (e.g., an S3 backend with locking).
Best practices
- Use modules to reuse configurations.
- Keep environments (dev/staging/prod) separate.
- Run
terraform fmtto keep code tidy andterraform validateto catch errors. - Always
destroylearning resources to avoid charges.
Practice challenge 🏋️
- Write a config that creates a single S3 bucket.
- Run
init,plan, thenapply. - Confirm it exists in the AWS console.
- Run
destroyto clean up.
What’s next?
You can build infrastructure on demand. Now let’s orchestrate all those containers at scale.
👉 Next up: Kubernetes 101