Infrastructure as code, and where Terraform fits
Why clicking in the console stops working, what infrastructure as code gives you, how Terraform works, how it differs from Ansible, and your first plan and apply.
By the end of this lesson you'll be able to
0 of 5 completeWhy clicking in the console doesn't scale
The first server is easy: open the AWS console, click through the wizard, done. Six months later you have 40 resources, and:
- Nobody remembers which settings staging was built with, so production is "almost the same".
- Rebuilding after a bad day means following a wiki page that's three changes out of date.
- A security group was opened "just for a minute" in March, and it's still open.
- There's no review: one wrong click goes straight to production, and there's no history of who did it.
None of that is anyone's fault. It's what happens when the only record of your infrastructure is the infrastructure itself.
Infrastructure as code
Infrastructure as code (IaC) means describing servers, networks, databases and permissions in text files, and letting a tool create them from those files. The files live in Git, next to the app. That gives you four things:
- Repeatable. Run the same code and get the same environment, for staging, production or a new region.
- Reviewed. A change is a pull request. Teammates read it, and CI checks it, before it touches anything real.
- Versioned.
git logtells you who changed the firewall, when and why, andgit reverttakes it back. - Documented. The code is always an up-to-date description of what exists.
Most IaC tools are declarative: you describe the end result ("one bucket, versioning on"), not the steps. The tool works out what to create, change or delete to get there.
How Terraform works
Terraform is the most widely used IaC tool. You write configuration in HCL, a readable language made of blocks, and Terraform talks to cloud APIs for you.
| Piece | What it does |
|---|---|
| Configuration | Your .tf files: the resources you want |
| Providers | Plugins that know one API: AWS, Azure, Google Cloud, Kubernetes, GitHub and hundreds more |
| State | terraform.tfstate: which real object each resource in your code belongs to |
| Plan | A preview of every create, change and destroy, before anything happens |
| Apply | Makes the plan real through the provider, then updates the state |
The workflow is the same for every provider, which is the main reason Terraform spread: learn it once for AWS and you can manage DNS, GitHub repos or Kubernetes the same way.
What teams use it for
- Building whole environments in the cloud: networks, servers, load balancers, databases.
- Creating the same setup in several regions or accounts from one module.
- Managing things around the cloud, too: DNS records, monitoring alerts, GitHub repositories and team permissions.
- Short-lived environments: a full copy of the stack for each pull request, destroyed when it merges.
Terraform vs Ansible
People often ask "Terraform or Ansible?" They mostly do different jobs:
| Terraform (provisioning) | Ansible (configuration management) | |
|---|---|---|
| Builds | The infrastructure: VMs, networks, buckets | What's inside a server: packages, files, services |
| Works through | Cloud and service APIs | SSH into existing machines |
| Style | Declarative, with a state file | Ordered tasks in playbooks, no state file |
| Typical use | "Create 3 VMs, a load balancer and a database" | "Install nginx, write its config, restart it" |
A common split: Terraform creates the servers, and Ansible, cloud-init or a pre-built image sets them up. With containers, there's often nothing left to configure inside the server at all.
Install it and run your first plan
# Ubuntu / Debian: add HashiCorp's signed package repository, then install $ wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list $ sudo apt update && sudo apt install terraform # macOS $ brew tap hashicorp/tap && brew install hashicorp/tap/terraform $ terraform version Terraform v1.x.x # your version will be newer or older; any recent 1.x works
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpgwgetdownload a file-Osave to this file (- = print it)-the previous directoryhttps://apt.releases.hashicorp.com/gpga URL|pipe: send output to the next commandsudorun the next command as rootgpgencrypt, sign and manage keys--dearmorconvert a key to binary-ooutput file/usr/share/keyrings/hashicorp-archive-keyring.gpga path
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.listechoprint text"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main"text, kept together by the quotes|pipe: send output to the next commandsudorun the next command as rootteewrite input to a file and pass it on/etc/apt/sources.list.d/hashicorp.lista path
sudo apt update && sudo apt install terraformsudorun the next command as rootaptDebian/Ubuntu package managerupdatea value the command works on&&run the next command only if this one workedsudorun the next command as rootaptDebian/Ubuntu package managerinstalla value the command works onterraforma value the command works on
brew tap hashicorp/tap && brew install hashicorp/tap/terraformbrewmacOS package managertapa value the command works onhashicorp/tapa value the command works on&&run the next command only if this one workedbrewmacOS package managerinstalla value the command works onhashicorp/tap/terraforma value the command works on
terraform versionterraforminfrastructure as codeversionprint the version
Your first configuration doesn't need a cloud account. The local provider manages files on
your own machine, which is perfect for learning the workflow:
# ~/tf-hello/main.tf terraform { required_providers { local = { source = "hashicorp/local" version = "~> 2.9" } } } resource "local_file" "hello" { filename = "${path.module}/hello.txt" content = "Built by Terraform" }
$ cd ~/tf-hello $ terraform init # downloads the providers into .terraform/ Terraform has been successfully initialized! $ terraform plan # local_file.hello will be created + resource "local_file" "hello" { + content = "Built by Terraform" + filename = "./hello.txt" ... } Plan: 1 to add, 0 to change, 0 to destroy. $ terraform apply # shows the plan again and waits for you to type yes Apply complete! Resources: 1 added, 0 changed, 0 destroyed. $ cat hello.txt Built by Terraform
cd ~/tf-hellocdchange directory~/tf-helloa path
terraform initterraforminfrastructure as codeinitdownload providers, set up the folder
terraform planterraforminfrastructure as codeplanpreview changes
terraform applyterraforminfrastructure as codeapplymake the changes
cat hello.txtcatprint a filehello.txta value the command works on
Read every plan before you apply it. The last line, Plan: 1 to add, 0 to change, 0 to destroy, is the one to check first: an unexpected number in the destroy column is how outages
start.
Let Terraform repair what you broke
Terraform manages ~/tf-hello/hello.txt. Someone deletes it by hand. Use Terraform to notice the drift and put the file back, without editing main.tf.
~/tf-hello/hello.txtReveal one safe solution
$ cd ~/tf-hello $ rm hello.txt # the "manual change" $ terraform plan # local_file.hello will be created ... Plan: 1 to add, 0 to change, 0 to destroy. $ terraform apply -auto-approve Apply complete! Resources: 1 added, 0 changed, 0 destroyed. $ cat hello.txt Built by Terraform
cd ~/tf-hellocdchange directory~/tf-helloa path
rm hello.txtrmdelete files, with no undohello.txta value the command works on
terraform planterraforminfrastructure as codeplanpreview changes
terraform apply -auto-approveterraforminfrastructure as codeapplymake the changes-auto-approveskip the yes prompt
cat hello.txtcatprint a filehello.txta value the command works on
Before planning, Terraform refreshes what it knows from the real world, sees the file is
missing, and plans to recreate it. That's drift detection, and on a real cloud account it's
how you catch the security group someone opened by hand. Use -auto-approve only when you
have just read the plan yourself.
Try it yourself
0 of 6 steps doneRun each task in your own account or terminal, then tick it off.
Quick check
What does terraform plan do?
Official reading for this lesson
Or get every quiz answer right and it completes itself.