How it works
The explanation, with examples you can run.
The cycle
terraform init # download providers and modules, configure the backendterraform fmt # canonical formattingterraform validate # syntax and internal consistency, no API callsterraform plan -out=tfplanterraform apply tfplanA small configuration, using only providers that touch the local machine:
terraform { required_version = ">= 1.5" required_providers { random = { source = "hashicorp/random", version = "~> 3.6" } local = { source = "hashicorp/local", version = "~> 2.5" } }} variable "env" { type = string default = "dev"} resource "random_pet" "name" { prefix = var.env} resource "local_file" "config" { filename = "${path.module}/out/${random_pet.name.id}.txt" content = "service=${random_pet.name.id}\n"}The first plan (Terraform 1.5.7; the local_file hash attributes, all (known after apply), are trimmed):
Terraform will perform the following actions: # local_file.config will be created + resource "local_file" "config" { + content = (known after apply) + directory_permission = "0777" + file_permission = "0777" + filename = (known after apply) + id = (known after apply) } # random_pet.name will be created + resource "random_pet" "name" { + id = (known after apply) + length = 2 + prefix = "dev" + separator = "-" } Plan: 2 to add, 0 to change, 0 to destroy. Saved the plan to: tfplan(known after apply) marks values the provider only learns while creating the object: here the random name, and so the file name built from it. Applying the saved plan created both, and a second terraform plan reported No changes. Your infrastructure matches the configuration.
Reading a plan for danger
Changing env to prod gives a very different plan:
# random_pet.name must be replaced-/+ resource "random_pet" "name" { ~ id = "dev-known-woodcock" -> (known after apply) ~ prefix = "dev" -> "prod" # forces replacement # (2 unchanged attributes hidden) } Plan: 2 to add, 0 to change, 2 to destroy.# forces replacement names the argument that cannot be changed in place. With random names that is harmless; with a database, a disk or a load balancer's address, a -/+ line means downtime or data loss. In review, look for three things first: the destroy count, every must be replaced, and anything changing that you did not touch.
What declarative does not mean
Terraform does not watch your infrastructure. It only acts when you run it, it only knows about resources in its state, and the order of blocks in files does not matter (dependencies do, see later). It also cannot make a non-idempotent API safe: if a provider cannot read back a setting, Terraform cannot tell when it drifts.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.