The server nobody can rebuild
Tom set up the shop's server by hand three years ago. Then Tom left the company.
Last night the server's disk failed. Nobody knows which settings Tom chose, or what he installed.
Rebuilding it takes two days of guessing. A team that had written the server down in a file could rebuild it in minutes.
By the end of this lesson
Note
I can explain why servers are described in files.
Key words
| Word | What it means |
|---|---|
| Infrastructure | the servers, networks and storage an app runs on |
| Infrastructure as code | describing infrastructure in files a tool can build from |
| Desired state | what the file says should exist |
| Drift | a difference between the file and what really runs |
| Plan | the list of changes a tool would make |
| Apply | making those changes for real |
The cells students fill in are left blank in this preview.
A file remembers what a person forgets
With infrastructure as code, the team writes each server down in a file. A tool reads the file and builds the servers.
The file is kept in Git with the app. Anyone can read it, and every change has a history.
If a server dies, the tool builds it again from the same file.
By hand or from a file
| Question | Set up by hand | Described in a file |
|---|---|---|
| Who knows the setup? | Only the person who did it | Anyone who reads the file |
| A server dies. How long to rebuild? | Days of guessing | Minutes |
| Are test and live the same? | Rarely | Yes, built from one file |
| Can a colleague check a change first? | No | Yes, in a review |
| Who changed what, and when? | Unknown | In the Git history |
The cells students fill in are left blank in this preview.
Read a file that describes servers
mkdir -p infra && cd infra
cat > servers.tf <<'EOF'
resource "aws_instance" "web_1" {
ami = "ami-0a1b2c3d"
instance_type = "t3.small"
tags = { Name = "web-1" }
}
resource "aws_instance" "web_2" {
ami = "ami-0a1b2c3d"
instance_type = "t3.small"
tags = { Name = "web-2" }
}
EOF
# How many servers does the file describe?
grep -c "^resource" servers.tf
# What size is each one?
grep instance_type servers.tf
# Change web_2 from t3.small to t3.large, then press Run again.
A common mistake
Warning
Many people think a quick fix by hand on the server is fine, because the file can catch up later. It rarely does. The next time the tool runs, it puts the server back the way the file says. Your fix disappears, so make every change in the file.
The tool compares the file with reality
The file is the desired state: what should exist. The tool also looks at what really runs.
Any difference is drift. It creates what is missing and removes what should not be there.
Below, two small lists stand in for the file and for reality. Bash finds the drift between them.
Find the drift
mkdir -p infra && cd infra
# What the file says the shop should have
printf 'web-1 small\nweb-2 small\ndb-1 large\n' > desired.txt
# What is really running today
printf 'web-1 small\ndb-1 medium\nold-test large\n' > actual.txt
echo "In the file but not running:"
comm -23 <(sort desired.txt) <(sort actual.txt)
echo "Running but not in the file:"
comm -13 <(sort desired.txt) <(sort actual.txt)
# Add the line "web-3 small" to desired.txt, then run again.
Read the plan, then apply
A good tool never changes servers straight away. First it prints a plan: what it would create, change and destroy.
A person reads the plan. A colleague often reviews it too. Only then does someone apply it.
Reading the plan is how you catch a mistake before it deletes a database.
What a real plan prints
| Line of output | What it means |
|---|---|
| + resource "aws_instance" "web_3" | A new server will be created |
| ~ instance_type: "t3.small" -> "t3.large" | A server will be changed in place |
| - resource "aws_instance" "old_test" | A server will be destroyed |
| Plan: 1 to add, 1 to change, 1 to destroy. | The summary to read first |
The cells students fill in are left blank in this preview.