Home/Start here/Terraform
Terraform
Terraform builds things in a cloud account. You describe what you want to exist, and it makes the account match.
How it actually works
You write files ending in .tf. Each one lists resources you want:
a bucket, a network, a permission. Then you run three commands.
terraform init downloads the code that talks to your cloud terraform plan shows exactly what will change, and changes nothing terraform apply makes the change
plan is the one that matters. It prints a list where every line
starts with a symbol: + to create, ~ to modify,
- to destroy. Read that list before you type yes. A surprise
- on a database is the reason this step exists.
What a plan actually looks like
Here is a real one, shortened. This is the quick start template for audit logs running against an empty account.
Terraform will perform the following actions:
# aws_s3_bucket.audit will be created
+ resource "aws_s3_bucket" "audit" {
+ bucket = "audit-log-immutable-123456789012-a1b2c3d4"
+ object_lock_enabled = true
+ force_destroy = false
}
# aws_cloudtrail.audit will be created
+ resource "aws_cloudtrail" "audit" {
+ name = "audit-log-immutable"
+ is_multi_region_trail = true
+ enable_log_file_validation = true
}
Plan: 9 to add, 0 to change, 0 to destroy.
Read the last line first. Nine new things, nothing changed, nothing destroyed. On a fresh account that is exactly right, so you type yes.
The one you stop at
Now the same template after somebody edited the bucket name.
# aws_s3_bucket.audit must be replaced
-/+ resource "aws_s3_bucket" "audit" {
~ bucket = "audit-log-immutable-123456789012-a1b2c3d4" -> "audit-logs-prod"
# forces replacement
}
Plan: 1 to add, 0 to change, 1 to destroy.
That -/+ and the words must be replaced mean
Terraform will delete the bucket and make a new one. On a log bucket with a
retention lock the delete fails and you are left half applied. On a database it
would succeed.
Three things to look for every time:
- Anything to destroy that you did not ask to destroy.
- forces replacement next to a change you thought was small.
- A count far off what you expected. Nine when you changed one setting usually means Terraform lost track of what it made.
The state file, and why it matters
Terraform keeps a file recording what it created. That file is how it knows the bucket in your code and the bucket in your account are the same bucket. Lose it and Terraform will try to create everything again.
Two things about it that catch people out:
- It contains secrets in plain text. Any password or key that passed through Terraform is written into the state file as readable text. A state file anyone can download is a serious problem.
- Two people cannot run at once. Without locking, two simultaneous applies will write over each other and leave the file describing something that does not exist.
On your own machine the state file sits in the folder. For a team it lives in a shared, encrypted, locked location. That is what the "remote state" block at the top of the Standard templates is for.
Two files look alike and are treated in opposite ways. terraform.tfstate
never goes in Git, because of the secrets. .terraform.lock.hcl always
does, because it records the exact provider versions and makes the next run behave
the same as this one.
The words you will see in a Terraform file
| Word | Plain meaning |
|---|---|
resource | One thing you want to exist. A bucket, a key, a rule. |
data | Something that already exists, which you look up and leave alone. |
variable | A setting someone can change without editing the main file. |
output | A value printed after apply, usually so you can use it in the next step. |
local | A shorthand for something repeated in several places in the same file. |
module | A folder of Terraform you reuse, called from somewhere else. |
provider | The plugin that knows how to talk to AWS, Azure, Google Cloud, or Oracle Cloud. |
What Terraform is good at
Anything that is created once and then exists: networks, machines, storage, databases, keys, permissions, DNS records, policies. It tracks what it made, notices when someone changed it by hand, and can put it back.
What to use something else for
Installing software inside a machine. Terraform can start a machine and hand it a startup script, and that is where most people stop. Anything more than that belongs to Ansible.
Deploying an application several times a day. Terraform runs when a person runs it. For something continuous on Kubernetes, use Argo CD.
Every template on this site has a Quick start version: one file, no setup, runs with no input. Audit logs nobody can delete is a good first one, because you can prove it worked by trying to delete something and watching it fail.