Infrastructure as code starts with a file
Infrastructure as code (IaC) means describing the servers, networks and settings a system needs in text files instead of setting them up by hand. That matters because a file can be reviewed and repeated, and a tool can show its changes before it makes them.
A college that wants the same set-up every term can keep it in one folder. OpenTofu is a free tool that reads such a folder and builds what it describes.
By the end of this lesson
Note
I can run a plan, apply it and say what the state file is.
Key words
| Word | What it means | Example |
|---|---|---|
| Desired state | what the files say should exist | |
| Plan | the list of changes, shown before any change | |
| Apply | carry out the changes in the plan | |
| State | the tool's own record of what it has made | |
| Resource | one thing a file describes | terraform_data |
| Provider | a plug-in that talks to a real service |
The cells students fill in are left blank in this preview.
You describe the end result, not the steps
A script lists steps: make this folder, then copy that file. A description says what should exist, and the tool works out the steps.
Run a script twice and it may do the work twice. Apply a description twice and the second time finds nothing to do, because the result already matches. That result is the desired state.
One file, two resources
# main.tf
resource "terraform_data" "hours" {
input = "09:00-17:00"
}
resource "terraform_data" "notice" {
input = "Closed on Sundays"
}
Nothing real is made in this lab
Important
Real clouds are reached through providers, which OpenTofu downloads from a registry. This lab cannot download one, so it uses terraform_data, a resource built into OpenTofu. It only stores a value. Plans, applies and state work exactly as they do with a cloud. OpenTofu itself is downloaded when the lab starts, so the lab needs a free account.
Make a folder for the project
mkdir -p ~/iac-demo/libraryShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Go into it
cd ~/iac-demo/libraryShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the file shown above
printf '%s\n' 'resource "terraform_data" "hours" {' ' input = "09:00-17:00"' '}' '' 'resource "terraform_data" "notice" {' ' input = "Closed on Sundays"' '}' > main.tfShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A plan shows the changes before anything happens
tofu init prepares the folder. A cloud project downloads its providers here. This folder has none to fetch, so it is quick.
tofu plan compares your files with the state and lists what it would do. A + means create, and the last line adds it up. A plan changes nothing. tofu apply then does what the plan listed. The Runs below keep only the lines that read the same on every machine.
Prepare the folder
tofu init -no-color | grep successfullyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Plan: two things to create
tofu plan -no-color | grep -E "will be|^Plan"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Apply: make them
tofu apply -auto-approve -no-color | grep "Apply complete"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Plan again straight away
tofu plan -no-color | grep "No changes"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think OpenTofu looks at the real world each time to see what exists. It does not. It compares your files with its own state. If the state says something exists, OpenTofu believes it. If the state is lost, OpenTofu plans to make it all again.
The state is the tool's memory
After an apply, OpenTofu writes terraform.tfstate in the folder. It is a JSON file that records every resource it made and the values it holds.
A plan is the difference between the files and that record. Real teams keep the state somewhere safe and never edit it by hand.
Worked example: what a plan decides
| Files say | State holds | The plan says |
|---|---|---|
| hours is 09:00 | nothing | create hours |
| hours is 09:00 | hours is 09:00 | nothing to do |
| hours is 10:00 | hours is 09:00 | change hours |
| nothing | notice exists | destroy notice |
The cells students fill in are left blank in this preview.
List what the state records
tofu state listShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read the state file itself
jq -r '.resources[].name' terraform.tfstateShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Change the opening hours in the file
sed -i 's/09:00-17:00/10:00-16:00/' main.tfShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Plan the change
tofu plan -no-color | grep -E "will be|^Plan"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A plan in a dozen lines of Python
# Compare what is wished with what is recorded.
state = {"hours": "09:00", "notice": "Closed Sundays"}
wish = {"hours": "10:00", "phone": "Call 1234"}
# Walk the wish first: what is new, what has changed.
for name in wish:
if name not in state:
print("create", name)
elif state[name] != wish[name]:
print("change", name)
# Then walk the state: what is no longer wished.
for name in state:
if name not in wish:
print("destroy", name)
# Change a value in wish and run it again.