Install Terraform via the HashiCorp tap
Hark, automation Warrior! In the previous quest you clicked and typed your way through the AWS console, summoning servers one command at a time. It worked - but it was a ritual of memory and toil, impossible to repeat exactly and dangerous to hand to another. This quest, Infrastructure as Code, teaches you to inscribe your infrastructure into a spellbook of declarative code, so that an entire environment can be conjured - or banished - with a single incantation.
With Terraform, you describe the world you want and the tool figures out how to make reality match. Check that description into Git and your infrastructure becomes reviewable, versioned, and reproducible. By the end you will understand providers and resources, the sacred plan-and-apply workflow, the all-important state file, and the principle of idempotency that makes it all safe.
๐ The Legend Behind This Quest¶
In the dark age of operations, servers were "pets" - hand-raised, uniquely configured, and irreplaceable. When one fell ill, a sysadmin would log in and nurse it back by hand, and no two machines were ever quite alike. This "snowflake" infrastructure was fragile and unknowable.
Infrastructure as Code ended that age. By describing infrastructure in text files and applying them with tooling, servers became "cattle" - identical, disposable, and rebuildable from source. Terraform, released by HashiCorp in 2014, became the lingua franca of this movement: one declarative language to provision across AWS, Azure, Google Cloud, and hundreds of other providers. This quest teaches you to think declaratively - to describe the destination and trust the tool with the route.
๐ฏ Quest Objectives¶
By the time you complete this journey, you will have mastered:
Primary Objectives (Required for Quest Completion)¶
- Providers and Resources - Declare a provider and define resources in HCL
- The plan / apply Workflow - Preview changes with
plan, enact them withapply, and reverse withdestroy - Terraform State - Explain what the state file tracks and why it is critical
- Idempotency - Understand why running
applytwice is safe and produces no extra changes
Secondary Objectives (Bonus Achievements)¶
- Variables and Outputs - Parameterize a configuration and expose useful values
- Remote State - Explain why teams store state remotely with locking
- Data Sources - Read existing infrastructure without managing it
Mastery Indicators¶
You'll know you've truly mastered this quest when you can:
- [ ] Read a terraform plan and predict exactly what will be created, changed, or destroyed
- [ ] Explain to a teammate why the state file must never be edited by hand or committed with secrets
- [ ] Re-run apply on an unchanged config and explain why "No changes" appears
- [ ] Refactor hard-coded values into variables without altering the result
๐บ๏ธ Quest Prerequisites¶
๐ Knowledge Requirements¶
- Completion of AWS Essentials (the examples provision AWS resources)
- Comfort with the terminal and editing text files
- Basic Git for versioning your configurations
๐ ๏ธ System Requirements¶
- Modern operating system (Windows 10+, macOS 10.14+, or Linux)
- Terraform installed (or OpenTofu, the open-source drop-in)
- A cloud account with credentials configured (AWS Free Tier recommended)
- A text editor with HCL support (VS Code + the HashiCorp Terraform extension)
๐ง Skill Level Indicators¶
This ๐ด Hard quest expects: - [ ] You will run real provisioning against a live account and clean it up - [ ] You are ready to think in terms of desired state, not step-by-step commands - [ ] Ready for 120-150 minutes of focused, hands-on work
๐ Choose Your Adventure Platform¶
You need the Terraform binary and configured cloud credentials. Install the CLI for your OS.
๐ macOS Kingdom Path¶
Click to expand macOS instructions
๐ช Windows Empire Path¶
Click to expand Windows instructions
๐ง Linux Territory Path¶
Click to expand Linux instructions
# Add the HashiCorp apt repo (Debian/Ubuntu) and install
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [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
terraform version
โ๏ธ Cloud Realms Path¶
Click to expand Cloud/Container instructions
๐งโโ๏ธ Chapter 1: Providers and Resources - The Vocabulary of HCL¶
Terraform configurations are written in HCL (HashiCorp Configuration Language). Two nouns dominate: the provider you talk to, and the resources you ask it to manage.
โ๏ธ Skills You'll Forge in This Chapter¶
- Declaring a provider with version constraints
- Defining a resource block
- The difference between resources and data sources
๐๏ธ Your First Configuration¶
A provider is a plugin that knows how to talk to a platform (AWS, Azure, GitHub, Cloudflare, and hundreds more). A resource is a single managed object - a bucket, an instance, a DNS record. Create a directory and a file named main.tf:
# main.tf โ declare the AWS provider and one S3 bucket
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "quest" {
bucket = "iac-quest-bucket-change-me-12345"
tags = {
Project = "it-journey-quest"
Managed = "terraform"
}
}
The syntax resource "<type>" "<local-name>" declares a resource: aws_s3_bucket is the type, and quest is the name you use to reference it elsewhere in your code (e.g., aws_s3_bucket.quest.id).
A data source is the read-only cousin of a resource - it looks up something that already exists rather than creating it:
# Read the most recent Amazon Linux 2023 AMI without managing it
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
๐ Knowledge Check: Providers and Resources¶
- What is the role of a provider versus a resource?
- What does the
~> 5.0version constraint mean? - How does a data source differ from a resource?
โก Quick Wins and Checkpoints¶
- Config written: You have a
main.tfwith a provider and a resource - Vocabulary clear: You can point to the provider, resource, and (optional) data source
๐งโโ๏ธ Chapter 2: The plan / apply Workflow and State¶
Terraform never changes your infrastructure blindly. It first computes a plan - a precise diff between the world it sees and the world you want - and only then, on your command, makes it real. The bridge between the two is the state file.
โ๏ธ Skills You'll Forge in This Chapter¶
- The full init -> plan -> apply -> destroy lifecycle
- What the state file is and why it matters
- Why state must be protected and stored remotely for teams
๐๏ธ The Core Lifecycle¶
# 1. init: download the provider plugins and prepare the working directory
terraform init
# 2. plan: preview what will change โ creates nothing yet
terraform plan
# 3. apply: enact the plan after you confirm with "yes"
terraform apply
# 4. destroy: tear everything in the state back down when done
terraform destroy
A terraform plan is read carefully before every apply. Its symbols are a language:
+ create a new resource will be added
- destroy an existing resource will be removed
~ update an attribute will change in place
-/+ replace the resource must be destroyed and recreated
Plan: 1 to add, 0 to change, 0 to destroy.
๐๏ธ Understanding State¶
After apply, Terraform writes a state file (terraform.tfstate) - a JSON record mapping each resource in your code to the real object it created in the cloud. State is how Terraform knows that aws_s3_bucket.quest is the bucket iac-quest-bucket-..., so the next plan can compute an accurate diff instead of trying to recreate everything.
Three rules of state:
- Never edit it by hand. Use
terraform statecommands if you must manipulate it. - Never commit it to Git if it contains secrets. State can hold sensitive values in plaintext.
- Store it remotely for teams. A shared remote backend (e.g., an S3 bucket with DynamoDB locking, or Terraform Cloud) gives everyone one source of truth and prevents two people applying at once.
# Example remote backend โ state lives in S3, locking via DynamoDB
terraform {
backend "s3" {
bucket = "my-team-tfstate"
key = "iac-quest/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "tf-locks"
encrypt = true
}
}
๐ Knowledge Check: Workflow and State¶
- What does
terraform plando thatapplydoes not? - What does the state file map together?
- Name two reasons teams use a remote backend.
๐งโโ๏ธ Chapter 3: Idempotency, Variables, and Outputs¶
The deepest magic of Terraform is idempotency - the property that describing a desired state and applying it repeatedly always converges to that same state, with no surprises. Variables and outputs make your spellbook reusable.
โ๏ธ Skills You'll Forge in This Chapter¶
- The meaning and value of idempotency
- Parameterizing a configuration with variables
- Exposing computed values with outputs
๐๏ธ Idempotency in Practice¶
Run terraform apply once and your bucket is created. Run it again, with the same config, and Terraform reports:
No changes. Your infrastructure matches the configuration.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
That is idempotency: the same input always yields the same end state. Because Terraform compares desired state (your code) against actual state (the state file plus a refresh of reality), it only ever does the work needed to close the gap - and if there is no gap, it does nothing. This is what makes IaC safe to run in automation: a pipeline can apply on every commit without fear of duplicating resources.
๐๏ธ Variables and Outputs¶
Hard-coded values do not scale. Variables parameterize a config; outputs surface useful results.
# variables.tf โ declare inputs
variable "bucket_name" {
description = "Globally unique name for the quest bucket"
type = string
}
variable "region" {
description = "AWS region to deploy into"
type = string
default = "us-east-1"
}
# main.tf โ use the variable
resource "aws_s3_bucket" "quest" {
bucket = var.bucket_name
}
# outputs.tf โ expose a result for humans and other tools
output "bucket_arn" {
description = "ARN of the created bucket"
value = aws_s3_bucket.quest.arn
}
Pass a variable at apply time, and read the output afterward:
๐ Knowledge Check: Idempotency and Reuse¶
- Why does a second
applyon an unchanged config make no changes? - How does a variable improve a configuration's reusability?
- What is an output good for that a variable is not?
๐ฎ Mastery Challenges¶
๐ข Novice Challenge: Create and Destroy¶
Objective: Write a minimal config that creates one S3 bucket, then destroy it.
Requirements:
- [ ] A main.tf with a provider and one resource
- [ ] Run init, plan, apply, then destroy
- [ ] Confirm the bucket is gone after destroy
Validation: terraform plan after destroy reports nothing to create or change beyond a fresh build.
๐ก Intermediate Challenge: Parameterize It¶
Objective: Refactor the bucket name and region into variables and expose the bucket ARN as an output.
Requirements:
- [ ] A variables.tf with at least two variables (one with a default)
- [ ] The resource references var. values
- [ ] An outputs.tf exposing the bucket ARN
- [ ] Apply passing the bucket name via -var, then read it back with terraform output
Validation: Changing only the variable value, not the resource block, changes the result.
๐ด Advanced Challenge: Prove Idempotency and Reason About State¶
Objective: Demonstrate idempotency and explain the role of state in your own words.
Requirements:
- [ ] Apply your config, then apply again and capture the "No changes" output
- [ ] Open the terraform.tfstate file and identify the mapping between your code and the real resource
- [ ] Write a short note on why state must not be hand-edited or committed with secrets
- [ ] Bonus: configure a remote S3 backend and re-init
Validation: You can show a "0 added, 0 changed, 0 destroyed" apply and explain why.
๐ Quest Rewards & Achievements¶
๐๏ธ Badges Earned: - ๐ Forgemaster - You provision infrastructure from declarative code - ๐ Keeper of the State Scroll - You understand and protect Terraform state
๐ ๏ธ Skills Unlocked: - Terraform plan/apply Workflow - Preview and enact infrastructure changes safely - Declarative Infrastructure Design - Describe the destination, not the route
๐ Unlocked Quests: - Kubernetes Fundamentals - Provision and orchestrate container clusters - Advanced IaC patterns - Modules, workspaces, and multi-environment pipelines
๐ Progression Points: +100 XP
๐บ๏ธ Next Steps in Your Journey¶
Continue the Main Story: - ๐ฏ Kubernetes Fundamentals - Orchestrate containers atop the infrastructure you now automate
Explore Side Adventures: - โ๏ธ AWS Essentials - Revisit the services you are now automating - โ๏ธ Azure Ascension - Apply IaC thinking to a managed platform deploy
Character Class Recommendations¶
๐ป Software Developer: Continue to Kubernetes Fundamentals ๐๏ธ System Engineer: Master modules and remote state for team workflows ๐ก๏ธ Security Specialist: Audit state handling and secret management in your pipelines
๐ Resources¶
Official Documentation¶
- Terraform Documentation - The complete official reference
- Terraform AWS Provider - Every AWS resource and data source
- Terraform State - How state works and why it matters
- HCL Configuration Language - Syntax and semantics of
.tffiles
Community Resources¶
- OpenTofu - The open-source, drop-in fork of Terraform
- Terraform Registry - Providers and reusable modules
- Stack Overflow: terraform tag - Community Q&A
Learning Materials¶
- HashiCorp Learn: Terraform Tutorials - Free, hands-on guided tutorials
- Terraform: Get Started on AWS - The official AWS quickstart
๐ค Quest Completion Checklist¶
- โ Completed all primary objectives
- โ Created and destroyed a resource through the full Terraform lifecycle
- โ Answered all knowledge check questions
- โ Completed at least one mastery challenge
- โ Explored the resource library
- โ Destroyed all billable resources to avoid charges
๐ธ๏ธ Knowledge Graph¶
Structured wiki-links connect this quest to the IT-Journey knowledge graph. Open the Obsidian Graph View to explore connections.
Level hub: [[Level 1000 (8) - Cloud Computing]] Overworld: [[๐ฐ Overworld - Master Quest Map]] Prerequisites: [[AWS Essentials: Core Services and Cloud Architecture Patterns]] Unlocks: [[Kubernetes Fundamentals: Container Orchestration Essentials]] Obsidian docs: [[Obsidian Knowledge Graph and Wiki Links]]